I have a back-end. A type of self-hosted CMS. This CMS maintains tokens; obtained upon initial login or user creation, maintained and refreshed, and encrypted at rest.
To perform its operations, this CMS uses a M2M “main” token.
I have a Jamstack-type front-end on a different server, different domain. That front-end commonly uses an API, registered with Auth0, and uses passwordless, with RS256. For management-type operations, that front-end uses its own “main” client id and client secret.
But there are times when that front-end needs to tap data stored in the CMS.
I am wondering what the best strategy is here. Should I register the FE client id and client secret as additional keys with the CMS, so the CMS can “impersonate” the front-end?
Should I treat the front-end and CMS as a single app with shared keys? But they live on different domains.
The CMS needs to be able to validate the signature of requesting tokens coming from the front-end basically. It might even need to retrieve “userinfo”, and use custom claims to perform some authorization.
If I understand correctly, you should be using a Single-Page Applications (SPA) with API strategy. With your FE app requesting access tokens and sending them with requests to your CMS/API. The CMS/API would validate the token and serve the data.
Is the front end requesting data from the CMS? Can you elaborate on why the CMS would be impersonating the FE? I am a little bit confused by this part.
The front-end is requesting both data from the CMS, and from a separate API.
The CMS also accesses data from that API, independently. In addition to its own data.
It’s worth noting that that API is not fully fleshed-out on Auth0. We just use minimal custom claims for access control.
When a request comes from the FE, it is unauthenticated. After we verify and validate the token, we add a custom claim to match that Auth0 user to an internal ID from the CMS.
To generate the internal ID, we use a piece of unique data - ie. an email or similarly unique piece of info, which we pull from /userprofile.
At this point, the only token from which it seems safe to do this is the FE token. Hence, the CMS has to be able to perform operations on behalf of the front-end.
Thanks for expanding on that. In my mind, you would have the front end registered as a SPA app, the CMS registered as an M2M app and API, and the other backend registered as an API.
The user would authenticate in the FE
When the FE app needs data from the CMS or other API it would request an access token for either API (audience)
Respective access token would be sent with requests to the CMS or other API
If the CMS needs to make requests to the other API it would request a M2M token
M2M token would be sent with requests to the other API
I’m a little confused about this part:
How is the request from the FE unauthenticated while still having a token? Also, how are you adding custom claims to the token after the token has been issued from Auth0?
I think this set up makes sense how you have described. The access token can be exchanged for userinfo (alternatively, you should be able to inspect the token and grab the user ID/sub. You could also add more data as custom claims if there is a specific claim you need).
@dan.woda apologies for the very belated answer. No, I think this clarifies my use case.
My concern was: I could have used the m2m access from the CMS to get information about users, but this seemed to cross boundaries in a way I wasn’t comfortable with; besides, the PHP SDK somewhat prevents this.
JWKS verification requires the issuing app id and secret for a token, which means that I can only ever verify my front-end tokens from an app that knows the issuing client id and secret.
So: problem solved. The functionality works as intended. Thanks again.