Identity Provider (IdP) Setup#
The unified osmo chart uses embedded Dex by default and bootstraps a static
admin account whose password is stored in a retained Secret. This configuration
uses volatile Dex storage and is intended only to speed up development and
evaluation. For production, disable embedded Dex and configure an external
identity provider (IdP) so users log in with your organization’s credentials
(for example, Microsoft Entra ID, Google Workspace, or AWS IAM Identity
Center). OSMO connects directly to the IdP; there is no Keycloak or other
broker in the middle.
External OIDC configures two client IDs. browserClientId is used by both
OAuth2 Proxy’s confidential browser flow and the CLI’s default authorization
code flow with PKCE. Its application registration therefore needs the OSMO web
callback and a localhost loopback callback; OAuth2 Proxy uses its client secret,
but the CLI never receives that secret. cliClientId is used by the optional
device authorization flow (osmo login --method code). Some providers allow
one application registration to support all of these flows; others require a
separate public client for device authorization. If the browser registration
cannot also act as a public PKCE client, use the device authorization flow for
CLI login.
Choose a userClaim that is present in ID tokens from the browser, PKCE,
and device flows. The CLI requests openid, profile, and
offline_access, but not email; use sub unless your provider always
includes the selected claim in those tokens. The CLI uses an available
localhost port for PKCE by default. If your provider requires an exact loopback
redirect URI, register a fixed port and pass it to osmo login with
--callback-port.
Note
In the unified osmo chart, select
authentication.provider: externalOidc, disable the default local
bootstrap user, and set embeddedDependencies.dex.enabled: false. Supply
browser and device client IDs, the issuer, authorization, token, device,
and JWKS endpoints, jwksHost, user/role claim names, scopes, and existing
Secret references. logoutEndpoint is optional and may remain empty.
HTTP endpoints are accepted for trusted development only. HTTPS JWKS
connections use the system CA bundle, validate the exact jwksHost DNS
name, and honor an explicit URI port. See
Migrating authentication for the complete migration contract.
Generate a random 32-byte cookie secret:
$ openssl rand -base64 32
Save the browser client secret and command output as
external-oidc-secret.yaml. Restrict access to this file and do not commit
it to source control:
apiVersion: v1
kind: Secret
metadata:
name: osmo-external-oidc
namespace: osmo
type: Opaque
stringData:
client_secret: <oidc-browser-client-secret>
cookie_secret: <random-32-byte-cookie-secret>
$ kubectl create --filename external-oidc-secret.yaml
When to use an IdP#
Use an IdP when:
You want users to sign in via a browser with corporate SSO (e.g., Microsoft, Google, etc.).
You want to map IdP groups or roles to OSMO roles so that access is controlled partly by your directory.
You are deploying in production and already have an IdP.
If you are evaluating OSMO or running in an environment without an IdP, use the default admin and access tokens instead (see Default admin (no IdP)).
How it works#
Register OSMO’s browser client in the IdP with the web and localhost callbacks. OAuth2 Proxy uses its client secret for the web flow, while the CLI uses the same client ID without the secret for PKCE. Register the device client separately when your provider requires it.
When a user visits the OSMO UI or API without a session, OAuth2 Proxy redirects them to the IdP. After login, Envoy validates the returned JWT and forwards the request to OSMO with
x-osmo-userandx-osmo-rolesset.OSMO roles can be assigned from two sources: directly via the OSMO user/role APIs, or from an IdP. When using an IdP, external claims (e.g., LDAP groups, OIDC roles) are mapped to OSMO roles through the IdP Role Mapping and Sync Modes.
Identity Provider Configuration Reference#
Placeholder |
Meaning |
Example |
|---|---|---|
|
OSMO service hostname |
|
|
Microsoft tenant ID |
|
|
OAuth2 Proxy browser and CLI PKCE client/application ID |
From IdP app registration |
|
CLI device-authorization client/application ID |
From the same or a separate IdP app registration |
|
OAuth2 client secret |
From IdP app registration |
|
AWS Identity Center instance ID |
|
|
AWS region |
|
Microsoft Entra ID (Azure AD)#
You can use one app registration for OAuth2 Proxy, CLI PKCE, and device
authorization. In that case, use its application ID for both
browserClientId and cliClientId. Configure the flows explicitly:
Under Authentication, add a Web redirect URI of
https://<your-domain>/oauth2/callbackfor OAuth2 Proxy.Under Authentication, add
http://localhostto Mobile and desktop applications for CLI PKCE, and enable Allow public client flows for PKCE and device authorization.Create a client secret under Certificates & secrets for OAuth2 Proxy. Do not distribute that secret to the CLI; CLI PKCE uses an
S256challenge and device authorization uses no client secret.OSMO requests only the OpenID Connect
openid,email,profile, andoffline_accessscopes. The chart’sscopesvalue configures OAuth2 Proxy; the CLI independently requestsopenid,offline_access, andprofile. The CLI does not need Microsoft GraphUser.Reador a delegated OSMO API permission for the current ID-token gateway contract. Add a delegated permission only when the client requests and uses that protected API’s scope.Implicit grant and hybrid flows settings are independent of authorization code with PKCE. PKCE does not require the implicit ID-token setting and does not replace delegated permissions. Do not disable an existing implicit or hybrid-flow setting as part of enabling PKCE.
Optional: Under Token configuration, add a “Groups” claim so group IDs (or names) are in the token for role mapping.
Endpoints:
Purpose |
URL |
|---|---|
Token |
|
Authorize |
|
Device authorization |
|
JWKS |
|
Issuer |
|
Logout |
|
Example Helm values:
externalUrl: https://<your-domain>
authentication:
provider: externalOidc
bootstrap:
identities:
admin:
enabled: false
externalOidc:
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
browserClientId: <browser-client-id>
# Use the same ID when this registration also supports device authorization.
cliClientId: <cli-client-id>
authorizationEndpoint: https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
tokenEndpoint: https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
deviceEndpoint: https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/devicecode
jwksUri: https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys
jwksHost: login.microsoftonline.com
userClaim: preferred_username
rolesClaim: groups
scopes:
- openid
- email
- profile
- offline_access
logoutEndpoint: https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/logout
browserClientSecret:
existingSecret: osmo-external-oidc
key: client_secret
rolloutNonce: ''
cookieSecret:
existingSecret: osmo-external-oidc
key: cookie_secret
rolloutNonce: ''
embeddedDependencies:
dex:
enabled: false
Google OAuth2#
In Google Cloud Console, create OAuth 2.0 credentials for the browser flow. Set the authorized redirect URI to
https://<your-domain>/oauth2/callback.If the same client supports CLI PKCE, also register the localhost loopback callback. Otherwise, configure a device client as
cliClientIdand useosmo login --method code.Configure the OAuth consent screen and add the
openid,email, andprofilescopes.
Endpoints:
Purpose |
URL |
|---|---|
Token |
|
Authorize |
|
Device authorization |
|
JWKS |
|
Issuer |
|
Use sub as the user claim for Google because it is present in tokens for
both browser and CLI login; the CLI does not request the email scope. The
browser audience is typically the full client ID (for example,
<browser-client-id>.apps.googleusercontent.com). Google does not publish an
OIDC logout endpoint, so leave logoutEndpoint empty. Set jwksHost to
www.googleapis.com and configure rolesClaim only with a claim that your
Google identity configuration actually emits; standard Google ID tokens do not
include Workspace groups.
AWS IAM Identity Center (AWS SSO)#
Enable AWS IAM Identity Center and note the instance ID and region.
Create a “Customer managed” OAuth 2.0 application for the browser flow with redirect URI
https://<your-domain>/oauth2/callbackand scopesopenid,email, andprofile. Use its client ID asbrowserClientIdand record its client secret.Enable device authorization on that application and use the same client ID as
cliClientId, or create a separate public device client and use its ID.osmo login --method codeusescliClientIdand no client secret.If the browser application supports public PKCE, also register the localhost loopback callback for the default
osmo loginflow.Assign users/groups to the application as needed.
Endpoints:
Purpose |
URL |
|---|---|
Token |
|
Authorize |
|
Device authorization |
|
JWKS |
|
Issuer |
|
Replace <region> and <instance-id> with your values. Set jwksHost
to oidc.<region>.amazonaws.com. Use sub as the user claim unless your
PKCE and device ID tokens are configured to include another stable claim.
Leave logoutEndpoint empty unless your configured provider exposes an OIDC
logout endpoint.
Managing users and roles with an IdP#
Users can be created in OSMO automatically when they first log in (just-in-time provisioning), or via the CLI (e.g.
osmo user create).Roles can be assigned in OSMO via the CLI (for example,
osmo user update <user_id> --add-roles <role_name>). They can also be derived from IdP claims: configure IdP Role Mapping and Sync Modes so that IdP group or role names map to OSMO role names. OSMO merges IdP-derived roles with manually assigned roles.
For more details, see IdP Role Mapping and Sync Modes.
Verification#
Browser: Open
https://<your-domain>in a private window. You should be redirected to the IdP, then back to OSMO with a session.CLI PKCE: Run
osmo login https://<your-domain>. For device authorization, add--method code. Then runosmo profile listto confirm the user has the expected identity and roles.
Troubleshooting#
Invalid token / 401: Check issuer and audience in Envoy match the JWT. Ensure the IdP’s JWKS URI is reachable from the cluster and the signing key is present.
Redirect fails: Ensure the redirect URI in the IdP exactly matches (scheme, host, path, no trailing slash).
Missing ``x-osmo-user`` / 400: Ensure
userClaimnames a claim present in the ID token for the login flow in use.User has no roles / 403: Ensure the user exists in OSMO and has roles (via
osmo user get <user_id>or IdP mapping).
See also
Authentication and Authorization for overview of authentication with and without an IdP
Authentication Flow for request flow
Roles and Policies for roles and policies