OIDC Setup
ForgePortal uses OpenID Connect (OIDC) for single sign-on. You configure one IdP and map its groups/roles to ForgePortal roles via auth.oidc and auth.roleMapping in forgeportal.yaml. This page gives step-by-step guides for five common providers.
Common steps (all IdPs)
- Create an OAuth2 / OIDC application in your IdP (confidential client).
- Set redirect URI to:
https://<your-forgeportal-host>/api/v1/auth/callback
(orhttp://localhost:4000/api/v1/auth/callbackfor local dev). - Note client ID and client secret; put the secret in env as
OIDC_CLIENT_SECRET, never in YAML. - Configure scopes so the IdP returns identity and (if needed) groups/roles.
- Configure ForgePortal with issuer, clientId, scopes, and optionally
groupsClaimandroleMapping.
1. Keycloak
IdP setup
- Realm: create or use an existing realm (e.g.
forgeportal). - Clients → Create client:
- Client type: OpenID Connect
- Client ID: e.g.
forgeportal - Access type: confidential
- Valid redirect URIs:
https://<forge-host>/api/v1/auth/callback - Web origins: same origin or
*for dev
- Credentials tab: copy the Secret → set as
OIDC_CLIENT_SECRET. - Client scopes: ensure the client has scopes that include
openid,email,profile, and a scope that exposes groups (e.g. add the built-ingroupsscope to the client, or create a mapper that adds groups to the token).
ForgePortal config
auth:
oidc:
issuer: https://<keycloak-host>/realms/<realm-name>
clientId: forgeportal
# clientSecret: OIDC_CLIENT_SECRET
scopes: openid email profile groups
groupsClaim: groups
roleMapping:
platform-admin: ["forge-admins", "admin"]
developer: ["developers"]
viewer: ["viewers"]
- Issuer:
https://<keycloak-host>/realms/<realm>(no trailing slash). - groupsClaim: Keycloak often uses
groups; if you use a custom claim (e.g.realm_access.roles), set it here.
2. Okta
IdP setup
- Applications → Create App Integration → OIDC, Web Application.
- Sign-in redirect URIs:
https://<forge-host>/api/v1/auth/callback. - Sign-out redirect URI (optional): your app URL.
- Assignments: All users or specific groups.
- After creation: copy Client ID and Client secret; set secret as
OIDC_CLIENT_SECRET. - Assignments → add groups if you use group-based access. Okta can expose groups in the token via Authorization Server → Claims (add a groups claim to the access or ID token).
ForgePortal config
auth:
oidc:
issuer: https://<your-domain>.okta.com/oauth2/default
clientId: <client-id>
scopes: openid email profile groups
groupsClaim: groups
roleMapping:
platform-admin: ["Admins", "SRE"]
developer: ["Developers"]
- Issuer: use your authorization server URL, e.g.
https://<your-domain>.okta.com/oauth2/defaultor a custom server. - If your Okta server uses a different claim for groups (e.g.
organization.groups), setgroupsClaimaccordingly.
3. Auth0
IdP setup
- Applications → Create Application → Regular Web Application.
- Settings:
- Allowed Callback URLs:
https://<forge-host>/api/v1/auth/callback - Allowed Logout URLs: optional
- Allowed Callback URLs:
- Copy Client ID and Client Secret; set secret as
OIDC_CLIENT_SECRET. - Rules or Actions (optional): add a rule/action to include
groupsorrolesin the token (Auth0 does not add groups by default; you can add a custom claim from app_metadata or authorization extension).
ForgePortal config
auth:
oidc:
issuer: https://<tenant>.auth0.com/
clientId: <client-id>
scopes: openid email profile
groupsClaim: groups # or https://your-namespace/roles if using Auth0 roles
roleMapping:
platform-admin: ["admin"]
developer: ["developer"]
- Issuer:
https://<tenant>.auth0.com/(trailing slash is common). - If you use Auth0’s RBAC, the roles claim is often namespaced; set
groupsClaimto that claim (e.g.https://your-app/roles).
4. Azure AD (Entra ID)
IdP setup
- App registrations → New registration:
- Name: e.g.
ForgePortal - Supported account types: as needed (single tenant / multitenant)
- Redirect URI: Web →
https://<forge-host>/api/v1/auth/callback
- Name: e.g.
- Certificates & secrets → New client secret → copy value →
OIDC_CLIENT_SECRET. - API permissions: Add Microsoft Graph (or OpenID) → OpenId permissions:
openid,email,profile. For groups: Delegated → GroupMember.Read.All or use Groups claim in token. - Token configuration: Add optional claim groups (or roles for app roles) so the ID token includes them.
ForgePortal config
auth:
oidc:
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
clientId: <application-client-id>
scopes: openid email profile
groupsClaim: groups
roleMapping:
platform-admin: ["<object-id-of-admin-group>"]
developer: ["<object-id-of-dev-group>"]
- Issuer:
https://login.microsoftonline.com/<tenant-id>/v2.0(replace<tenant-id>). - Azure often returns groups as object IDs (GUIDs); map those in
roleMapping, or use app roles and setgroupsClaim: roles.
5. AWS Cognito
IdP setup
- User pool → App integration → App client (or create one):
- Type: Confidential client
- Auth flows: ALLOW_USER_PASSWORD_AUTH, ALLOW_REFRESH_TOKEN_AUTH, and ALLOW_USER_SRP_AUTH are optional; for OIDC code flow you need Authorization code grant and openid.
- Callback URL(s):
https://<forge-host>/api/v1/auth/callback - Sign out URL: optional
- Note Client ID and Client secret; set secret as
OIDC_CLIENT_SECRET. - App client → Hosted UI: ensure OIDC scope includes
openid,email,profile. For groups: add custom scope or use Pre token generation trigger to addcognito:groupsto the token.
ForgePortal config
auth:
oidc:
issuer: https://cognito-idp.<region>.amazonaws.com/<user-pool-id>
clientId: <app-client-id>
scopes: openid email profile
groupsClaim: cognito:groups
roleMapping:
platform-admin: ["admins", "PlatformAdmins"]
developer: ["developers"]
- Issuer:
https://cognito-idp.<region>.amazonaws.com/<user-pool-id>(no trailing slash). - Cognito puts groups in
cognito:groups; setgroupsClaim: cognito:groupsand map group names inroleMapping.
ForgePortal roles (reminder)
| Role | Purpose |
|---|---|
platform-admin | Full platform and template management. |
template-admin | Manage templates and related config. |
team-admin | Manage teams and members. |
developer | Create/edit entities, run actions. |
viewer | Read-only access. |
Users get the highest role they match in roleMapping. If no group matches, they are treated as viewer (or denied if your IdP does not issue a token). Set roleMapping so each IdP group name (or role) maps to exactly one ForgePortal role.
For full config options, see forgeportal.yaml — auth and Environment Variables.