Hi there
I am wondering, what would be the right pattern to implement impersonation in Camunda 8?
With impersonation I mean that you can call a REST API later in the process with the user that started the process, even the token of the user is not valid anymore.
We use OAuth2 with Keycloak. In Camunda 7 we do this manually with Keycloak REST API and the grant type urn:ietf:params:oauth:grant-type:token-exchange.
For this we get the authenticatedUserId from Camunda.
Hey @pme123 - I’ve been thinking about this today, and I don’t quite have a good pattern for you yet. I have asked around to gather thoughts from others and am waiting on their response.
Are the calls that need to be impersonated to your API, or to a third party? Does your Keycloak setup allow impersonation?
My first thought is to use Keycloak’s built-in impersonation features, using a “zeebe” user to fetch a token that impersonates the user, and use that token in further requests. As for implementing that, I think I would first try an execution listener on any tasks need to use impersonation and generate the token securely in your listener. (I don’t know that this is best, just my first thought!)
Hi @nathan.loding thanks for the response.
We have a gateway that handles the token stuff (so for all APIs the same token). And yes our Keycloak supports impersonation (see the grant type in my question).
With Camunda 7 we did the following:
In a Starter Listener Skript we persisted the UserId in a process variable. execution.getProcessEngineServices().getIdentityService().getCurrentAuthentication().getUserId().
And then when calling the service, we get the token from keycloak for that user.
So like your proposal, only that we fetch the token for each service (as the token may not be active anymore).
@pme123 - for step 1, I would instead start a process with the userId variable and then consume it in the execution listener (which should be passed all the in scope variables).
While I don’t pretend to be an expert in this area, this is the pattern I would try in my process if I were developing it right now. I’d love to hear any other solutions people have!
@pme123 - yes, there are a lot of questions still, and we don’t know all the factors at play in your environments.
The provider could be used to fetch secure values based on other data in the process. For instance, if you had a process variable with the user ID, and a set of secrets for that user ID (perhaps a client ID and client secret), the provider could fetch those secrets to be used in the REST connector.
Both approaches assume that the user ID is available as a global process variable, and there are pros and cons to each.