Okta
Read the Identity overview first to understand the
IdentityProvider resource, userInfoPrefix, and claim mappings.
Configure an Okta organization as a Hub identity provider, either for OIDC login alone or with directory sync through the Okta Management API. Okta is standards-compliant once you attach a groups claim to the authorization server.
Prerequisites
- An Okta org and admin access to it.
- The base URL for your Okta org (
https://<org>.okta.comor a custom domain). - For directory access,
hub-coreneeds network access to that org URL.
Set up the login app
- App integration. In the Okta admin console, go to Applications > Create App Integration and choose OIDC — OpenID Connect with application type Web Application.
- Redirect URI. Set the sign-in redirect URI to
https://<hub-url>/oidc/callback. - Grant types. Enable Authorization Code.
- Credentials. Record the client ID and client secret from the application's General tab.
- Groups claim. Under Security > API > Authorization Servers, select
your authorization server (usually
default) and open the Claims tab. Add a claim:- Name:
groups - Include in token type: ID Token, Always
- Value type: Groups
- Filter: Regex
.*(or a narrower pattern scoping which Okta groups Hub sees).
- Name:
- Assign users. Assign the application to the users and groups you want to allow into Hub.
Configure OIDC login
apiVersion: authentication.hub.upbound.io/v1beta1
kind: IdentityProvider
metadata:
name: okta
spec:
redirect:
browserLogin: true
clientSecret: "<client-secret>"
scopes:
- openid
- email
- profile
validation:
userInfoPrefix: "okta:"
issuer:
# The default authorization server URL.
url: https://<org>.okta.com/oauth2/default
audiences:
- <client-id>
claimMappings:
username:
claim: email
groups:
claim: groups
claimValidationRules:
- expression: "claims.email_verified == true"
message: "email must be verified"
Role bindings reference users as okta:<email> and groups as
okta:<group-name>.
If you use a custom authorization server other than default, replace
/oauth2/default in the issuer URL with /oauth2/<auth-server-id> and make
sure the groups claim exists there too. Take the value from the authorization
server's discovery document at <issuer>/.well-known/openid-configuration — it
must match exactly.
Set up directory access
Skip this if you only need login. Directory queries use a separate app from the one above: Okta only mints Management API tokens for a service app that authenticates with a signed JWT assertion, so a client secret won't do.
- Service app. Go to Applications > Create App Integration and choose API Services.
- Key pair. On the app's General tab, set client authentication to Public key / Private key and add a key. Let Okta generate one and copy the PEM private key — it's shown once. Note the key ID if you register more than one key.
- Scopes. On the Okta API Scopes tab, grant
okta.groups.readandokta.users.read. - Admin role. If your org requires an admin role for API service apps, assign a read-only one.
Hub accepts RSA and ECDSA P-256 keys in PEM (PKCS#8, PKCS#1, or SEC1). If you enable Require Demonstrating Proof of Possession (DPoP) on the app, Hub handles the proofs and nonce challenges itself — nothing extra to configure.
Configure the directory
Add a directory block alongside the login configuration:
spec:
# ...redirect and validation as above
directory:
# Okta tokens carry group names, not IDs — see below.
groupClaimType: DisplayName
userClaimType: Email
config:
apiVersion: directory.hub.upbound.io/v1alpha1
kind: OktaConfiguration
orgURL: https://<org>.okta.com
clientID: "<service-app-client-id>"
privateKey: |
-----BEGIN PRIVATE KEY-----
<PEM contents>
-----END PRIVATE KEY-----
privateKeyID: "<key-id>"
| Field | Required | Description |
|---|---|---|
orgURL | yes | Okta org base URL. Must be an absolute https:// URL. |
clientID | yes | Client ID of the API Services app — not the login app. |
privateKey | yes | PEM private key that signs the client assertion. Read back as ***. |
privateKeyID | no | The key's kid. Required when the app has more than one key registered. |
The groups claim you configured on the authorization server emits group
names, so groupClaimType: DisplayName is what makes directory groups and
signed-in users resolve to the same string. Keep the resource named okta and
userInfoPrefix set to okta: so both sides agree — see matching directory
groups to role bindings.
Group search is a prefix match on the group's Okta name. Member lists carry each user's email and display name, falling back to first and last name when the profile has no display name set.
Verify
# Search groups by name prefix.
curl -H "Authorization: Bearer $HUB_TOKEN" \
"$HUB_URL/apis/authentication.hub.upbound.io/v1beta1/groups?identityProvider=okta&displayNameQuery=platform"
# List members, using a group name from the response above.
curl -H "Authorization: Bearer $HUB_TOKEN" \
"$HUB_URL/apis/authentication.hub.upbound.io/v1beta1/users?identityProvider=okta&group=okta:platform-eng"
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
cannot authenticate to Okta | Okta rejected the client assertion. | Check orgURL and clientID, confirm the public key is registered on the service app, and set privateKeyID if the app has several keys. |
cannot parse okta private key | Unsupported key encoding. | Use a PEM-encoded RSA or ECDSA P-256 key. |
403 from the Management API | Scopes not granted. | Grant okta.groups.read and okta.users.read on the Okta API Scopes tab, and assign an admin role if your org requires one. |
directory not configured | No directory block on the IdentityProvider. | Add one. |
| Search returns nothing | displayNameQuery matches on a prefix. | Query the start of the group name, not a word in the middle. |
| Role bindings never apply | groupClaimType disagrees with the token. | Use DisplayName for Okta, and match userInfoPrefix to the resource name. |
| A group is missing from a broad search | Hub considers at most 200 matches per query. | Narrow the query so the group falls inside the match set. |
Next step
With the provider registered, decide what its identities may do: Access management covers binding the prefixed usernames and groups above to Hub roles.