Goal
Our subsidiary organization is using Auth0 to have a federated login to our parent companies Okta IdP. We are looking to Authenticate AND authorize access to Auth0 protected tools by taking Okta AD groups placed on the Okta issued id_token
claim to Auth0 and mapping those AD groups to Auth0’s Authorization Core RBAC Roles. We’d like that mapping of roles to sync every time we issue a new access_token
from Auth0 (1 hour)
What Works
We have working federated authentication solutions with both:
- Enterprise OIDC Connection
- Okta Workforce Connection.
We also have a working solution for federated authorization mapping within an Auth0 Rule or Auth0 Action (Auth0 Rule saving us an extra request to the Management API since the access_token
is passed into the user’s identities in the Auth0 Rule)
The Problem
After an hour has passed since the initial federated login, the access_token
issued to Auth0 from Okta (exp
of +1 hour when issued) goes stale and expires. The Auth0 docs suggest using a refresh_token
issued from the IdP (Okta in this case) so that we can get a new access_token. However, both the Enterprise OIDC Connection and the Okta Workforce Connection do NOT store a refresh token in the user’s identities even if present on the code exchange between Auth0 and Okta. Therefore, we cannot get a new Okta access_token
for the purpose of getting the latest AD group claims via Okta’s /userinfo
route. Because of that, we can’t map those AD groups to the latest RBAC permissions defined in Auth0. At worst, we would be updating our Auth0 RBAC roles for as long as the Auth0 session is maintained (and not needing to go to Okta) – which in our case is the default 7 days. That’s undesired, as we’d want to adjust RBAC roles on the Auth0 side if a user had a removed AD group on the Okta side (removal of access)
Solutions Explored
-
Use a Social Federated Login (OAuth2.0) and leverage the fact that it stores both the
access_token
andrefresh_token
- Problem: We need the identifier first feature for our connection. And that’s only possible with an Enterprise Connection
-
Use the Enterprise OIDC Connection and expect that “Auth0 automatically syncs user profile data with each user login” according to this doc
-
Problem: Although the docs say “with each user login”, I don’t think that means once an Auth0 session is established or for silent auth’s with a
response_mode=web_message
&prompt=none
- Both of these scenarios cause Auth0 to redirect back to the primary application without going back to Okta first. Which leads me to believe that there is no way that claims are being synced unless Auth0 is somehow storing and auto using the refresh token to fetch updated claims via the Okta
/userinfo
route. But I highly doubt that.
- Both of these scenarios cause Auth0 to redirect back to the primary application without going back to Okta first. Which leads me to believe that there is no way that claims are being synced unless Auth0 is somehow storing and auto using the refresh token to fetch updated claims via the Okta
-
Problem: Although the docs say “with each user login”, I don’t think that means once an Auth0 session is established or for silent auth’s with a
-
Require Application to force re-auth as described in these docs (
max_age
param).- Problem: This works well, however it allows the application to define when the full upstream authentication happens. In our case, our applications are all first party and we desire that the sync between Okta AD group claims and Auth0 RBAC roles happens as part of the identity server logic and not determine by a single application/client.
-
Use Auth0 Rules to define a redirect back to our Auth0
/authorize
route but with the connection name for Okta defined so it forces the login to go to Okta first before issuing a token back to the client. Thereby, allowing us to get a fresh newacces_token
stored for the user on every new application session.- When the
access_token
in the Okta connection expires, we would simply force a redirect by usingcontext.redirect = { url : redirectUrl }
-
Problem: Although this does indeed work to refresh the
access_token
so we can fetch new claims from the Okta/userinfo
route, we cannot add the initial scopes (or any) requested by the client application to the redirect URL. Otherwise, we get “Invalid redirect URL” as a text response from the/authorize
endpoint- we’ve tried URL encoding it as well
- example req/resp traces:
x-auth0-requestid: 9fe90ac5861ee86c635c
traceparent: 00-00000000000000005699ba5454a99e24-7c1a930519c4279c-01
auth0-request-id=7be37d6e2f564523,auth0=true
- example bad redirect
- When the
context.redirect = {
url: "https://{{AUTH_SERVER}}/authorize?response_type=code&scope=openid email profile offline_access&client_id={{CLIENT_ID}}&redirect_uri={{WHITELISTED_CALLBACK_URL}}&connection={{OKTA_WORKFORCE_CONNECTION_NAME}}",
};
-
Use Auth0 Actions to define a redirect back to our Auth0
/authorize
route but with the connection name for Okta defined so it forces the login to go to Okta first before issuing a token back to the client. Thereby, allowing us to get a fresh newacces_token
stored for the user on every new application session.- When the
access_token
in the Okta connection expires, we would simply force a redirect by usingapi.redirect.sendUserTo(redirectUrl.href)
- Currently our best solution
-
Problem: I am needing to make a Management API request to simply get the
access_token
for the user while in the Auth0 Rule, theuser.identities
has theaccess_token
. Unfortunately the Auth0 Action does NOT.
- When the
Questions
- Will Enterprise Connections ever store refresh tokens in the user’s identities storage? Is that on the roadmap?
- it seems OIDC Connections might have that coming down the pipeline according to this link, but what about other Enterprise Connections?
- The Okta Enterprise Connection does not allow us in the UI to adjust the scopes fetched from Okta. I needed to change the scopes requested (adding the
offline_access
scope for the refresh token) via the Management API connection PUT actionhttps://{{auth0_domain}}/api/v2/connections/:conn_id
. Is there plans for the Okta Enterprise connection to allow this change via the UI? - (reference: Solutions Explored #4) is the inclusion of scopes on a Rule redirect truly something we shouldn’t or can’t do? or is it a bug?
- (reference: Solutions Explored #5) will
access_token
ever be present on the function’sevent.user
variable? This would save us a Management API fetch (doing our best to avoid the rate limits). - Are there other methods to sync Okta AD group claims to Auth0 that we didn’t explore?