EddytorDocs & API

SSO with OIDC

Connect Okta, Entra ID, Auth0, Keycloak, or any standards-compliant OIDC provider for sign-in.

Eddytor's SSO layer accepts any standards-compliant OIDC provider. There's no admin UI for it yet, so you configure it via the REST API. SSO is a Preview feature, off by default until enabled per-organisation.

This is the end-to-end walkthrough from a clean install.

1. Register an OIDC app at your IdP

The sign-in redirect URI is always ${server.public_url}/v1/oauth/sso/callback.

  • Okta: Applications → Create App Integration → OIDC / Web Application. Capture the Client ID, Client secret, and the issuer URL (e.g. https://your-tenant.okta.com).
  • Keycloak / Auth0 / Authentik / others: same pattern, same redirect URI.

2. Get an admin bearer token

The curl calls need one. Mint a non-expiring API key inside the container:

docker compose exec eddytor-server eddytoradm create-api-key --email you@example.com
export EDDYTOR_TOKEN="edd_live_…"

3. Look up your organisation ID

ORG_ID=$(curl -fsS http://localhost:8080/api/v1/organisations \
  -H "Authorization: Bearer $EDDYTOR_TOKEN" | jq -r '.[0].id')

4. Enable the SSO feature flag for the org

curl -fsS -X PATCH "http://localhost:8080/api/v1/organisations/$ORG_ID/config" \
  -H "Authorization: Bearer $EDDYTOR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"features":{"sso":true}}'

5. Create the OIDC connection

curl -fsS -X POST "http://localhost:8080/api/v1/organisations/$ORG_ID/sso" \
  -H "Authorization: Bearer $EDDYTOR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "displayName": "Okta",
    "issuerUrl": "https://your-tenant.okta.com",
    "clientId": "0oa…",
    "clientSecret": "…",
    "emailDomain": "example.com",
    "enforceSso": false,
    "defaultRole": "editor"
  }'
FieldNotes
issuerUrlMust be https://. Eddytor probes ${issuer}/.well-known/openid-configuration at create time and rejects on failure.
emailDomainLowercase. Sign-ins with an email at this domain route to your IdP instead of magic link.
enforceSsotrue blocks magic-link fallback for the domain. Start false, flip to true once confirmed working.
defaultRoleOne of viewer, editor, builder, admin - granted to first-time sign-ins via this connection.

6. Smoke-test

Sign out, then hit ${server.public_url}/v1/oauth/authorize?login_hint=alice@example.com in a browser - Eddytor should 302 you to your IdP, then back through /v1/oauth/sso/callback into a session.

Update / delete later with PUT / DELETE on /v1/organisations/$ORG_ID/sso/$CONN_ID.

Callback host override (rare)

If your callback host differs from public_url (e.g. the IdP allow-list is locked to a single FQDN behind a CDN):

[server]
oauth_redirect_base = "https://idp-callbacks.example.com"

The IdP redirect URI must then match ${oauth_redirect_base}/v1/oauth/sso/callback.

Heads up

enforce_sso: true blocks magic-link for that domain. Confirm the IdP round-trip works with false first, or you can lock yourself out. The in-container eddytoradm path is still your recovery hatch.

Next

On this page