Identity Management
Centralized authentication, authorization, and secrets management for RavenmaskOS.
Overview
The identity management stack implements a layered, enterprise-grade security model:
┌─────────────────────────────────────────────────────────────────┐
│ EXTERNAL REQUEST │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ LAYER 1: EDGE (Traefik) │
│ - TLS termination (Let's Encrypt) │
│ - Route 53 DNS validation │
│ - ForwardAuth middleware │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ LAYER 2: AUTHENTICATION │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ OAuth2-Proxy │───▶│ Zitadel │ │
│ │ (ForwardAuth) │ │ (OIDC/SSO) │ │
│ └─────────────────┘ └─────────────────┘ │
│ OR │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ NextAuth.js │───▶│ Zitadel │ │
│ │ (Direct OIDC) │ │ (OIDC/SSO) │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ LAYER 3: AUTHORIZATION │
│ ┌─────────────────┐ │
│ │ OpenFGA │ ← Fine-grained permissions │
│ │ (AuthZ) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ LAYER 4: SERVICE IDENTITY (In Progress) │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ SPIRE Server │───▶│ SPIRE Agent │ │
│ │ (Trust Domain) │ │ (Workload ID) │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ LAYER 5: SECRETS │
│ ┌─────────────────┐ │
│ │ OpenBao │ ← Dynamic credentials, rotation │
│ │ (Secrets) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Components
| Service | Purpose | URL | Status |
|---|---|---|---|
| Zitadel | OIDC/SSO Provider | auth.ravenhelm.dev | ✅ Running |
| OAuth2-Proxy | Forward Auth Middleware | oauth.ravenhelm.dev | ✅ Running |
| OpenFGA | Fine-grained Authorization | Internal | ✅ Running |
| SPIRE | Service Identity (SPIFFE) | Internal | ⚠️ Partial |
| OpenBao | Secrets Management | vault.ravenhelm.dev | ✅ Production |
OpenBao Sub-Pages
| Page | Description |
|---|---|
| OpenBao OIDC | Zitadel SSO authentication for UI access |
| OpenBao AppRole | Service-to-service authentication |
| OpenBao Auto-Unseal | GCP KMS auto-unseal configuration |
| OpenBao Norns Integration | How Norns fetches secrets from vault |
Authentication Flows
Flow 1: OAuth2-Proxy (ForwardAuth)
Used for services without native OIDC support.
User → Traefik → OAuth2-Proxy Check
│
┌─────────────┴─────────────┐
↓ ↓
Cookie Valid Cookie Invalid
↓ ↓
Forward to Redirect to Zitadel
Service ↓
User Authenticates
↓
Authorization Code
↓
OAuth2-Proxy exchanges
code for tokens
↓
Set secure cookie
↓
Redirect to service
Protected Services:
- Homepage (dashboard.ravenhelm.dev)
- n8n UI (n8n.ravenhelm.dev)
- Homebridge (homebridge.ravenhelm.dev)
Flow 2: Direct OIDC (NextAuth.js)
Used for Next.js applications with native OIDC.
User → Next.js App → NextAuth.js
↓
Redirect to Zitadel
↓
User Authenticates
↓
Authorization Code
↓
NextAuth exchanges
code for tokens
↓
JWT Session Cookie
↓
App renders with
user context
Services Using Direct OIDC:
- Norns Admin (norns.ravenhelm.dev)
- Bifrost Admin (bifrost.ravenhelm.dev)
- Grafana (grafana.ravenhelm.dev)
Service Integration Matrix
| Service | Auth Method | Integration Type | Notes |
|---|---|---|---|
| Homepage | OAuth2-Proxy | Traefik ForwardAuth | Full protection |
| n8n | OAuth2-Proxy + PAT | Hybrid | UI protected, API uses PAT |
| Homebridge | OAuth2-Proxy | Traefik ForwardAuth | Full protection |
| Norns | NextAuth.js | Direct OIDC | Native integration |
| Bifrost | NextAuth.js | Direct OIDC | Native integration |
| Grafana | Generic OAuth | Direct OIDC | Role mapping enabled |
| Langfuse | NextAuth.js | Direct OIDC | Native integration |
OIDC Applications
Registered in Zitadel:
| Application | Client ID | Type |
|---|---|---|
| OAuth2-Proxy | 351314046345084937 | Web (PKCE) |
| Norns Admin | 350642335773687817 | Web |
| Grafana | 351369960024506377 | Web |
| GitLab | 351312537486163977 | Web |
Cookie & Session Security
OAuth2-Proxy Cookie
| Property | Value |
|---|---|
| Name | _oauth2_proxy |
| Domain | .ravenhelm.dev |
| Secure | true (HTTPS only) |
| HttpOnly | true |
| SameSite | Lax |
| Max-Age | 24 hours |
PKCE (Proof Key for Code Exchange)
OAuth2-Proxy uses S256 code challenge method to prevent authorization code interception attacks.
Trust Domain
All services operate under the ravenhelm.dev trust domain:
- DNS:
*.ravenhelm.dev→ Traefik - OIDC Issuer:
https://auth.ravenhelm.dev - SPIFFE Trust Domain:
spiffe://ravenhelm.dev - Cookie Domain:
.ravenhelm.dev
Quick Commands
# Check all identity services
for svc in zitadel oauth2-proxy spire-server spire-agent openbao; do
echo "=== $svc ==="
docker ps --filter "name=$svc" --format "{{.Names}}: {{.Status}}"
done
# Test OIDC discovery
curl -s https://auth.ravenhelm.dev/.well-known/openid-configuration | jq .issuer
# Check OAuth2-Proxy logs
docker logs oauth2-proxy 2>&1 | tail -20
# View Zitadel logs
docker logs zitadel 2>&1 | tail -20
# Check SPIRE server health
docker exec spire-server /opt/spire/bin/spire-server healthcheck
# Check OpenBao status
docker exec openbao bao status
Secrets Management
OpenBao (Production)
Secrets are centrally managed in OpenBao with the following features:
| Feature | Status |
|---|---|
| KV v2 Secrets Engine | ✅ Active |
| GCP KMS Auto-Unseal | ✅ Active |
| OIDC Authentication | ✅ Active |
| AppRole (Services) | ✅ 4 services configured |
| Norns Integration | ✅ Reading from vault |
Secret Paths:
secret/api-keys/- Anthropic, OpenAI, Deepgram, etc.secret/database/- PostgreSQL, Redissecret/integrations/- Slack, Twilio, GitLabsecret/services/- Langfuse, LiveKitsecret/infrastructure/- AWS
See Secrets Migration for full migration status.
Legacy: Environment Files
Some services still use .env files as backup, but primary source is now OpenBao.
Implementation Status
| Component | Phase | Status |
|---|---|---|
| Zitadel | Phase 1 | ✅ Production |
| OAuth2-Proxy | Phase 1 | ✅ Production |
| Direct OIDC Apps | Phase 1 | ✅ Production |
| SPIRE Server | Phase 2 | ✅ Running |
| SPIRE Agent | Phase 2 | ⚠️ Attestation Issues |
| OpenBao | Phase 2 | ✅ Production (GCP KMS auto-unseal, OIDC, AppRole) |
| OpenFGA | Phase 2 | ✅ Production |
| Norns → OpenBao | Phase 3 | ✅ Integrated |
Runbooks
Zitadel / OAuth2
- Add New OIDC Application
- Rotate OAuth2-Proxy Cookie Secret
- Reset Zitadel Admin Password
- SPIRE Agent Attestation Fix
OpenBao
- OpenBao Operations - Day-to-day operations
- OpenBao Unseal - Manual unseal procedures
- Secrets Migration - Migration status and plan
Troubleshooting
See individual service pages for specific troubleshooting: