Does the Ory Hydra support the OAuth 2.0 Token Exc...
# general
a
Does the Ory Hydra support the OAuth 2.0 Token Exchange (RFC 8693) ? If not, is there any other alternative ?
m
Currently not supported, but being worked on right now. So will be supported very soon. What is your use case? If you add some more context on what you are trying to do then I can suggest an alternative
a
ok we are planning to support workload identity and need to exchange workload access token with hydra access token. so checking if ory hydra can support the token exchange natively
May I know the timelines when the token exchange support will be available?
I see this github.com/ory/hydra/issues/1218#… which is dated back in 2018 but not yet released
Please let me know the timelines on when the token exchange will be supported by ory hydra natively
m
You mean you want to support learn.microsoft.com/en-us/entra/workload-id ?
a
yes similar to that, in our case, we have our own kubernetes clusters are deployed where some of the pods in these clusters with k8 tokens need to call the APIs but these API are gated/ authorized with hyrda oAuth. so we need some way to exchange those K8 tokens with hydra access tokens. so that the services in the pods can use the hydra access tokens to call the APIs.
m
Ok I see. Let me see if there is a way for you to solve it today. But Token Exchange (RFC 8693) will be available later this year for Ory Hydra, can't share a more fine-grained timeline for it yet.
Ok you can probably also solve it with JWT-bearer grant (RFC 7523) The pod sends its Kubernetes service account token as the assertion and gets an Ory access token back, with sub set to
system:serviceaccount:<namespace>:<name>
. I tested it on our side with a Kubernetes-style token. I can send some more details if you want.
a
yes
system:serviceaccount:<namespace>:<name>
thats right
yes please send me more details on the alternatives if you have
šŸ‘ 1
Will Token Exchange (RFC 8693) will be available in hydra natively starting next year ?
m
1. Mount a projected service account token in the pod. Set its audience to your Ory token URL. The default automounted token won't work, because its audience is the API server and its lifetime is too long.
Copy code
volumes:
 - name: ory-token
  projected:
   sources:
   - serviceAccountToken:
     path: ory-token
     audience: https://<your-ory-domain>/oauth2/token
     expirationSeconds: 600
2. Get the cluster's issuer from
kubectl get --raw /.well-known/openid-configuration
(the issuer field) and its signing keys from
kubectl get --raw /openid/v1/jwks.
3. Register the cluster as a trusted issuer with POST /admin/trust/grants/jwt-bearer/issuers, one call per signing key. Replace subject with "allow_any_subject": true if every service account in the cluster should be allowed. expires_at is required, so renew the trust before that date.
Copy code
{"issuer": "<cluster issuer>", "subject": "system:serviceaccount:<ns>:<sa>", "scope": ["<scopes>"], "jwk": { <key from jwks> }, "expires_at": "2027-10-01T00:00:00Z"}
4. Create an OAuth2 client with
grant_types: ["urn:ietf:params:oauth:grant-type:jwt-bearer"], token_endpoint_auth_method: "none"
and the same scopes. The pod needs no secret, but client_id is required. 5. Exchange from the pod:
Copy code
curl -X POST https://<your-ory-domain>/oauth2/token \
  -d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
  -d client_id=<client id> \
  -d scope=<scopes> \
  --data-urlencode assertion="$(cat /var/run/secrets/tokens/ory-token)"
Three things to check while you test: • Each service account token can be exchanged only once. Sending the same token again returns jti_known, so the pod should cache the Ory access token and exchange again only after the kubelet rotates the token file. Please test a container restart for this case. • If your Kubernetes version doesn't put a jti claim in the token, the exchange fails with "MUST contain an 'jti' (JWT ID) claim". Send me the decoded claims and we'll sort out the config. • If your APIs check aud on Ory tokens, add the API's audience to the client's audience list and pass audience=value in the exchange. Otherwise aud comes back empty. Let me know how it goes.
šŸ‘€ 1
Yea next year it will be available for sure. Probably commercial versions first though.
šŸ™ 1