Step 1: Make tokens addressed to Bifrost
For providers with a client-credentials grant, configure the provider so tokens for your services carry Bifrost as their audience:- Okta: use an authorization server whose audience is Bifrost’s URL, and a scope your service apps may request.
- Auth0: create an API whose identifier is Bifrost’s URL, and authorize your machine-to-machine apps for it.
- Keycloak: add an audience mapper that puts Bifrost’s URL in
audfor the service-account clients.
- Kubernetes: mount a projected service account token with
audienceset to Bifrost’s URL (aserviceAccountTokensource in aprojectedvolume). Itssubissystem:serviceaccount:<namespace>:<service account>, the value you map. - GitHub Actions: give the job
permissions: id-token: writeand request the token with Bifrost’s URL as the audience, for examplecore.getIDToken('https://bifrost.example.com')inactions/github-script. Itssubnames the repository and ref, such asrepo:acme/payments:ref:refs/heads/main.
Step 2: Add the provider as a trusted issuer
- In Bifrost, open User Provisioning, edit your SSO provider, and go to Provider Configuration → Workload identity.
- Under Additional trusted issuers, select Add issuer, give it a name, choose Generic OIDC, paste the issuer URL, set the audience, and fill in the workload ID claim from the table above. Add the rule only if you will map your SSO app’s own client ID.
- Select Test, then save the provider.
Step 3: Map a client to a service account
- Open the service account under Governance → Users and go to Workload identity.
- Select Add workload identity, choose the issuer, and enter the value of the issuer’s workload ID claim as the token carries it: the client ID for Okta, Auth0 and Keycloak, or the
subvalue for an issuer like Kubernetes or GitHub Actions. - Select Add.
UpdateWorkloadIdentities permission.
If the client ID is your SSO app’s and the issuer has no rule, Bifrost refuses the mapping and asks you to add the rule first, and refuses a provider save that removes the rule while such a mapping exists. A mapping that ends up in that state another way, such as when the provider’s config is changed in config.json, shows Needs a people rule and takes no tokens until the rule is back.
Step 4: Call Bifrost
The service sends its token as the bearer token; with a client-credentials provider, it gets the token from the grant first. For example, with Auth0, withCLIENT_ID and CLIENT_SECRET exported in the environment. The request body is built from the environment and sent on standard input, so the secret never appears in a command’s arguments, where other users on the host could read it:

