All-in-one Dockerfile.openldap bundling the app + OpenLDAP + Redis in one container, plus an idempotent bare-metal install.sh, and a Jekyll docs site for GitHub Pages: - Dockerfile.openldap (node:20-alpine; openldap + pw-sha2/ppolicy/memberof/ refint; dumb-init PID 1; npm ci --omit=dev; tos.md copied to /). - docker-entrypoint.sh: generate slapd.conf (mdb + overlays + TLS + indexes + access), self-signed LDAPS cert, seed directory tree + required groups, bundled redis, export app_* config, exec node. - docker-compose.yml, .dockerignore, DEPLOYMENT.md, secrets.js.example. - install.sh: idempotent Debian/Ubuntu bare-metal installer (Node 20.x, OpenLDAP, Redis, systemd unit) with flags + --dry-run/--skip-ldap/--skip-app. - ops/ldif/: memberof/refint/tls/index/nodes/logging LDIFs. - nodejs/conf/base.js: generic defaults (dc=example,dc=com / localhost / SSO Manager) so per-deployment values move to secrets.js or app_* env. - nodejs/package.json: bump @simpleworkjs/conf to ^1.1.0 (app_* env overrides). - nodejs/routes/index.js: /health endpoint for healthchecks. - docs/: _config.yml + index/deployment/configuration/oauth/ldap pages (jekyll-theme-cayman) for GitHub Pages from /docs. Co-Authored-By: Claude <noreply@anthropic.com>
3.9 KiB
layout, title
| layout | title |
|---|---|
| default | OAuth / OIDC |
OAuth 2.0 / OpenID Connect
SSO Manager is an OpenID Connect / OAuth 2.0 provider: it issues its own access, refresh, and ID tokens that your apps can consume to authenticate users and authorize API calls. It also runs a full OpenLDAP directory, so it can be both your SSO and your user directory at once.
Discovery
The provider publishes a standards-compliant discovery document:
GET https://<sso-host>/.well-known/openid-configuration
It advertises the issuer, authorization_endpoint, token_endpoint,
userinfo_endpoint, end_session_endpoint, supported scopes, and token
lifetimes. OIDC clients (e.g. the theta42/proxy) can read their endpoint URLs
from here rather than configuring each one.
The issuer advertised is conf.oauth.issuer — set it to the browser-facing
HTTPS URL the SSO is served at (e.g. https://sso.example.com), either in
conf/secrets.js or via app_oauth__issuer / OAUTH_ISSUER.
OAuth clients
An OAuth client represents an app that authenticates against the SSO. Each has:
client_id(UUID) +client_secret(bcrypt-hashed; the raw secret is shown once when the client is created or rotated — save it immediately).name,description,created_by(the admin uid that created it).redirect_uris— allowed callback URLs (must match exactly).scopes— requested scopes (defaultopenid profile email groups).allowed_groups— restrict the client to members of specific SSO groups (empty = any valid user).token_lifetime—access_token/refresh_tokenlifetimes (seconds).
Managing clients
Clients are managed from the web UI (as a member of the app_sso_oauth_admin
group) or the HTTP API at /api/oauth/client (auth via the auth-token header
from a login):
| Method | Path | Action |
|---|---|---|
GET |
/api/oauth/client |
list clients |
POST |
/api/oauth/client |
create a client (returns the raw client_secret once) |
GET |
/api/oauth/client/:id |
get one |
PUT |
/api/oauth/client/:id |
update redirect URIs / scopes / groups |
DELETE |
/api/oauth/client/:id |
delete |
POST |
/api/oauth/client/:id/rotate |
rotate the secret (returns the new raw secret once) |
All client-management endpoints are gated by the
app_sso_oauth_admingroup.
Scopes
| Scope | Claims / access |
|---|---|
openid |
OIDC ID token + discovery |
profile |
preferred_username, display name, etc. |
email |
the user's mail |
groups |
the user's group memberships (the groups claim) |
The groups claim is what relying parties (e.g. the proxy's
app_auth__adminGroups) use to map group membership to roles.
Token lifetimes
Defaults (overridable per-client via token_lifetime, or globally via
app_oauth__token_lifetime__access_token /
app_oauth__token_lifetime__refresh_token):
- access token: 3600s (1 hour)
- refresh token: 2592000s (30 days)
Admin gating
SSO admin actions are gated by LDAP group membership (checked via the group's
member list, not memberOf on the user):
app_sso_admin— full admin (users, groups, settings).app_sso_oauth_admin— OAuth client management.app_sso_invite— invitation management.
The bootstrap in theta-env creates your
first admin and adds them to app_sso_admin + app_sso_oauth_admin
automatically; for a standalone install, add the admin's DN to those groups
manually (or via ops/ldap-setup.sh).
JWT signing
Tokens are signed with conf.oauth.jwtSecret (app_oauth__jwtSecret /
JWT_SECRET). Persist this secret — if it changes, every issued token
stops validating. The all-in-one Docker image auto-generates one if none is set,
but that generated value does not survive container recreation unless you
persist it (set JWT_SECRET in your .env).