Skip to content

OIDC Authentication

EdgePlane uses OIDC for human operator authentication. This guide covers server configuration, CLI login flows, and Kubernetes secret management.

Terminal window
OIDC_ISSUER_URL=https://<your-idp>/application/o/<provider-slug>/
OIDC_CLIENT_ID=<oidc-client-id>
OIDC_CLIENT_SECRET=<oidc-client-secret>
OIDC_REDIRECT_URI=https://<edgeplane-host>/api/auth/oidc/callback
OIDC_SCOPES=openid profile email
# optional — auto-discovered if omitted
# OIDC_JWKS_URL=https://<your-idp>/application/o/<provider-slug>/jwks/

When the API container reaches the IdP via a private address (e.g. a Kubernetes ClusterIP) but browsers must redirect to a public hostname:

Terminal window
# Server-side: token discovery, JWKS fetch, iss validation
OIDC_ISSUER_URL=http://<cluster-ip>/application/o/<slug>/
OIDC_INTERNAL_ISSUER_URL=http://<cluster-ip>/application/o/<slug>/
# Browser-side: authorize_url returned to CLI and web — never validated against JWT claims
OIDC_PUBLIC_ISSUER_URL=https://<public-idp-host>/application/o/<slug>/

Rule: OIDC_ISSUER_URL must match the iss claim in issued JWTs. OIDC_PUBLIC_ISSUER_URL only rewrites the authorize_url returned to browsers and CLI clients.

Terminal window
# 1. Initiate — get a browser URL and a cli_nonce
curl -s https://<edgeplane-host>/api/auth/oidc/cli-initiate
# → {"authorize_url": "https://...", "cli_nonce": "...", "expires_at": "..."}
# 2. Open authorize_url in your browser and complete login.
# The success page shows a grant_id (olg_…).
# 3. Exchange the grant_id for a session token
curl -s -X POST https://<edgeplane-host>/api/auth/oidc/exchange \
-H "Content-Type: application/json" \
-d '{"grant_id": "olg_…"}'
# → {"token": "ep_…", "subject": "…", "expires_at": "…"}
# 4. Save the session token (edgeplane reads this automatically)
cat > ~/.edgeplane/session.json <<EOF
{"token":"ep_…","subject":"…","email":"…","expires_at":"…","base_url":"https://<edgeplane-host>","session_id":1}
EOF
chmod 600 ~/.edgeplane/session.json

Polling instead of copy-paste:

Terminal window
curl -s https://<edgeplane-host>/api/auth/oidc/cli-poll/<cli_nonce>
# → {"status":"ready","grant_id":"olg_…"} (404 until login completes)

With edgeplane auth login:

Terminal window
export EP_BASE_URL="https://<edgeplane-host>"
edgeplane auth login --ttl-hours 8
edgeplane auth whoami

EdgePlane uses a backend PKCE flow:

  1. Browser requests GET /api/auth/oidc/start
  2. Server redirects to IdP authorize endpoint with PKCE challenge
  3. IdP returns to GET /api/auth/oidc/callback
  4. Server exchanges auth code, validates token, issues one-time grant
  5. Browser calls POST /api/auth/oidc/exchange to receive ep_* session token

EdgePlane has three authentication paths — no static API token (EP_TOKEN was removed in v0.11.0):

PathWhoHow
OIDC sessionHuman operatorsedgeplane auth login → browser flow → ep_* session token
Service accountCI / scriptedCreate via API → ep_sa_* token → pass via EP_AGENT_TOKEN
Node JWTedgeplaned daemonedgeplane agent node register → RS256 JWT at /etc/edgeplane/node.json

When OIDC_ISSUER_URL and OIDC_CLIENT_ID are set, the server enables OIDC login automatically.

  1. Set OIDC_ISSUER_URL, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in the server environment
  2. Configure OIDC_REDIRECT_URI to https://<edgeplane-host>/api/auth/oidc/callback in your IdP
  3. Validate the CLI login flow: edgeplane auth login → browser → edgeplane auth whoami
  4. Validate the web dashboard login (browser → tower root → IdP → back to dashboard)

Never commit OIDC client secrets, service tokens, or static tokens to Git.

# Create a Secret with all auth env vars
apiVersion: v1
kind: Secret
metadata:
name: edgeplane-auth
type: Opaque
stringData:
OIDC_ISSUER_URL: "https://..."
OIDC_CLIENT_ID: "..."
OIDC_CLIENT_SECRET: "..."

Mount in the deployment:

envFrom:
- secretRef:
name: edgeplane-auth
Token typeDescriptionRecommended for
Session token (ep_*)DB-backed, revocable, expiringInteractive CLI/web use
Service account (ep_sa_*)Long-lived, programmaticMCP clients, CI pipelines
Node JWTPer-node RS256 JWTedgeplaned daemon, machine-to-machine
OIDC JWTShort-lived, identity-boundSSO environments (exchanged for session token)

Session tokens are the recommended auth mechanism for interactive use. They are revocable, expiring, and never written to agent config files on disk.