Goal
[!TIP]
In hurry? Jump directly to Result section to see the outcome of this dive.[!NOTE]
Although I am organizing and writing this on 2/21 after my LF AI & Data Japan RUG presentation has successfully concluded, I believe it is crucial to leave a record of failures and roadblocks. Therefore, I am documenting this past dive retrospectively.
The goal of this dive is to integrate Okta Sign-In with the Athenz ecosystem, by achieving the following:
- Login into Athenz UI with Okta SSO
- Successfully run
zms-cliwith Okta SSO
ToC
- Goal
- ToC
- Result
-
Setup
- Setup: Sign up Okta
- Setup: Okta with Work Email
- Setup: Okta Verify for Mac OS locally
- Test: Login Okta
- Setup: Okta App Integration
- Setup: Okta Authorization Server API
- Setup: Okta Policy & Rules
- Test: Token Preview
- Setup:
subas athenz user service name - Test:
subfrom Token Preview - Setup: Access Token
- Test: Access Token
- Setup: Adding ZMS properties so that ZMS can trust the okta verify
- Setup: Make sure to restart the ZMS server to get the changes!
- Setup: Set k8s secret for proxy credentials
- Setup: Create proxy container
- Setup: Remove
STATIC_USER_NAME - Setup: Modify the UI config
- Verify: Does it work?
- What I learned
- What's next?
- Closing
Result
I was able to login into Athenz UI successfully using Okta SSO.
However, due to the complexity of Identity mapping, I couldn't achieve the following goals:
- Acting normally as the mapped user
user.ajkimpost-login. (The system authenticates me as the full emailajkim@ajktown.com, failing authorization checks). - Logging into
zms-clidirectly using the Okta integration.
Setup
Setup: Sign up Okta
https://developer.okta.com/signup/
Setup: Okta with Work Email
Setup: Okta Verify for Mac OS locally
Install Okta Verify from App Store.
Test: Login Okta
Login completed!
Setup: Okta App Integration
[!TIP]
Official Athenz Doc: https://github.com/AthenZ/athenz/blob/master/docker/docs/IdP/Auth0.md

https://integrator-8302118-admin.okta.com/admin/apps/active
Click next with OIDC & Web Application:
-
Proof of possession: Makes required signed token, for now we skip
Setup: Okta Authorization Server API
https://integrator-8302118-admin.okta.com/admin/oauth2/as
Setup: Okta Policy & Rules
Create a scope athenz:
Test: Token Preview
Setup: sub as athenz user service name
[!NOTE]
- Source code for authorized client ids not mandatory
- Source code for using
subas service principal
Athenz only sees the sub field to define who you are. You can set up conversion field too but for now we can simply do this:
Test: sub from Token Preview
Setup: Access Token
CLIENT_ID="0oaz36xyehsYf8Cwz697"
CLIENT_SECRET="PUT_YOUR_SECRET_HERE"
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "${CLIENT_ID}:${CLIENT_SECRET}" \
"https://integrator-8302118.okta.com/oauth2/default/v1/token" \
-d "grant_type=client_credentials" \
-d "scope=athenz" | jq
# {
# "token_type": "Bearer",
# "expires_in": 3600,
# "access_token": "CENSORED",
# "scope": "athenz"
# }
Test: Access Token
TOKEN="PUT_YOUR_ACCESS_TOKEN"
curl -k -H "Authorization: Bearer $TOKEN" \
"https://localhost:4443/zms/v1/domain"
Setup: Adding ZMS properties so that ZMS can trust the okta verify
We can omit athenz.auth.oauth.jwt.authorized_client_ids_path because we setup the email address as the SSOT.
### Okta Configuration for ZMS ###
athenz.zms.authority_classes=com.yahoo.athenz.auth.impl.CertificateAuthority,com.yahoo.athenz.auth.impl.AuthorizedServiceAuthHeaderAuthority,com.yahoo.athenz.auth.oauth.OAuthCertBoundJwtAccessTokenAuthority
# Issuer:
athenz.auth.oauth.jwt.claim.aud=api://default
athenz.auth.oauth.jwt.claim.iss=https://integrator-8302118.okta.com/oauth2/default
athenz.auth.oauth.jwt.claim.scope=athenz
athenz.auth.oauth.jwt.parser.jwks_url=https://integrator-8302118.okta.com/oauth2/default/v1/keys
athenz.auth.oauth.jwt.auth0.claim_client_id=cid
athenz.auth.oauth.jwt.verify_cert_thumbprint=false
athenz.auth.oauth.jwt.cert.exclude_role_certificates=false
Setup: Make sure to restart the ZMS server to get the changes!
kubectl rollout restart deployment/athenz-zms-server -n athenz
Setup: Set k8s secret for proxy credentials
Athenz UI does not have any mechanism to handle the Oauth (completely separated) so we want to build our own proxy so that all Athenz cares is about the token stored as Cookie,
But before we do anything, we need the id and secret to represent the proxy so that proxy is trusted by Okta server. To do this correctly, we want to create a k8s secret:
printf "Enter Okta Client ID: "
read _CLIENT_ID
printf "Enter Okta Client Secret: "
read _CLIENT_SECRET
echo ""
_COOKIE_SECRET=$(openssl rand -base64 32 | tr -- '+/' '-_')
_ns="athenz"
echo "🔐 Creating Kubernetes Secret [oauth2-proxy-creds] in ns [$_ns]..."
kubectl delete secret oauth2-proxy-creds -n $_ns --ignore-not-found > /dev/null
kubectl create secret generic oauth2-proxy-creds \
-n $_ns \
--from-literal=client-id=${_CLIENT_ID} \
--from-literal=client-secret=${_CLIENT_SECRET} \
--from-literal=cookie-secret=${_COOKIE_SECRET}
Setup: Create proxy container
Copy the following container spec right under the spec.template.spec.containers section:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:latest
ports:
- containerPort: 3100
name: auth-proxy
env:
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: oauth2-proxy-creds
key: client-id
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-creds
key: client-secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-creds
key: cookie-secret
args:
# destination of this container:
- --upstream=http://127.0.0.1:3000/
# this container's port, the same as the .ports[0].containerPort:
- --http-address=0.0.0.0:3100
# Okta setting:
- --provider=oidc
- --oidc-issuer-url=https://integrator-8302118.okta.com/oauth2/default
- --email-domain=*
# "Athenz-Principal-Auth" is the default (modifiable) cookie name
- --cookie-name=Athenz-Principal-Auth
- --cookie-secure=false
- --pass-access-token=true
# Let the UI read?
- --set-xauthrequest=true
- --pass-user-headers=true
Setup: Remove STATIC_USER_NAME
Remove the following line from the spec.template.spec.containers section, this is only for test and if you want to use the admin back, please do add them later once again:
- name: STATIC_USER_NAME
value: athenz_admin
Setup: Modify the UI config
[!NOTE]
docker/ui/conf/extended-config.js
Modify
-
authUserEmailHeadertoX-Forwarded-Email -
authUserNameHeadertoX-Forwarded-Preferred-Username:
Verify: Does it work?
Please refer to the Result section above to see the verification steps and outcome.
What I learned
Not every tech dive ends with a perfectly working architecture, and that is completely fine.
One of my core principles for maintaining a Weekly Dive habit is knowing how to manage failure gracefully. If I stubbornly pushed to resolve this Okta identity mapping issue, I would have compromised the preparation time for my upcoming LF AI & Data Japan RUG presentation.
By defining this as a [Post-Mortem], I accomplished two things:
- I left a clear, reproducible architecture footprint (oauth2-proxy + Okta OIDC) that I can easily pick back up later.
- I maintained my documentation consistency without feeling guilty about an "incomplete" project.
What's next?
For the next 4 weeks, my Weekly Dives will be entirely dedicated to an Epic: AI Data Japan RUG Prep. Sometimes the best engineering decision you can make is knowing when to pause a task, log the exact error state, and pivot to the higher-priority deadline.
Closing
If you enjoyed this deep dive, please leave a like & subscribe for more!
















Top comments (0)