Can't set user grants from info in user metadata set from external auth provider via Actions
Hey all. I might be missing something obvious here, but hope someone can point me in the right direction.
I'm self-hosting on v3.3.0 and trying to set up a user access flow using ActionsV1 and GitHub as the identity provider (via Dex) and seem to have hit a wall due to the availability of certain methods in Actions and their execution flow. This is a flow I had set up in Keycloak which, whilst pretty clunky, was working as expected.
I'm running Zitadel as an internal service to development teams. The flow I'm trying to set up is the following:
1. Internal user without an existing Zitadel account wants to access one of the clients, or accesses the Zitadel UI directly.
2. Zitadel prompts for login, user selects to sign-in via GitHub
3. User authenticates successfully and gets redirected back to Zitadel
4. User is presented with the few profile fields to fill out and clicks "Register" to create their Zitadel user
5. Based on the GitHub teams list returned by Dex as part of 3, add user metadata to their Zitadel user containing a "primary" team and the full list of GitHub teams they're a member of
6. Automatically assign user grants for that user based on their team membership as defined in user metadata
I currently have two Actions configured:
processGitHubLogin
, which runs on the ExternalAuth flow at PostAuth, and grantInitialRoles
which also runs on the ExternalAuth flow at PostCreation stage.6 Replies
In
processGitHubLogin
, I'm getting the list of GitHub org team memberships back from the Dex login flow and then assigning those as user metadata like so:
And then in grantInitialRoles
I'm trying to set user grants based on that stored user metadata:
I'm facing a few problems here though:
1. On initial user creation and the execution of the processGitHubLogin
action, no metadata is appended until the second time that user authenticates via GitHub. The console log in the action is printed the correct data, but it can't set metadata since the user doesn't exist in Zitadel at this point.
2. Given this, grantInitialRoles
doesn't work. Since it's being executed at PostCreation phase (and only the once, since the trigger runs at the completion of registration), and since the user metadata doesn't exist, I can't set the grants.
As far as I can find, appendUserGrant
is only available at PostCreation for InternalAuth and ExternalAuth flows, so I'm not sure how I can set these user grants up through any auth flow. I've tried creating the internal user beforehand and then linking to the GitHub auth user, which does correctly set the user metadata but obviously the user grant Action won't run since the user was already created.
Any advice would be great, as I'm fresh out of ideas!
The only other approach I've considered here is having a service user set up and making API calls in the Actions to assign grants instead, but I don't want to go down that route unless there aren't any alternatives that I might be missing.
(though I might have to if I want to assign instance roles based on team membership since I don't think that's supported in Actions?)
Passing thought, though I haven’t tried it yet, but would moving the first action from PostAuth to PreCreation make any difference? I’m assuming not since the user still won’t have been created yet.Just came across https://github.com/zitadel/zitadel/issues/8497 which would’ve solved this without necessitating migration to Actions V2, which I’m not against but the lack of support for V2 in the TF provider at the moment is a massive adoption barrier.
GitHub
Actions: appendUserGrant on post authentication triggers · Issue #...
Action currently allow to appendUserGrant on the post creation trigger. This works fine for the registration / first time provisioned users, but lacks the ability to update user grants on already c...
hey @profgriswald good day, indeed but actions v2 are still very much wip, I will let you know when we plan t release the TF provider for it
Hey @Rajat, indeed! Very much understood. I'd rather avoid any sizeable migrations if at all possible anyhow 🙂
hey @profgriswald can you try
processGitHubLogin
and set it as ExternalAuth → Pre Creation instead of Post Auth and try the flow again. It also allows metadata setting before the user is created. Can you try it?. Also I am hoping that the method name and the action name is same. MOre about it on actions doc@Rajat Sure let me try that now. And yes the function and action are the same name.
@Rajat I'm not entirely sure how this approach will work, since the
externalUser
object returned by the external auth is only available in the Post Auth trigger.
Actually that's not strictly true, I can see it's there under ctx.v1.authRequest.linkingUsers
. Now seeing if I can get this hooked up.
Yeah, the ID token from the external auth is only in the Post Auth trigger, and not in the Pre or Post Creation triggers, so there's no way for me to get the claims returned by the external auth
Just to circle back round to this, two points to mention:
1. With assigning metadata, I managed to get this working with appendMetadata
calls in the Post Auth action, but those calls only seemed to work AFTER calls to supporting methods like setFirstName
, possibly because there was no metadata to append to otherwise?
2. I ended up working around granting roles in a Post Creation action albeit in a slightly awkward way (which will likely be moot with Actions V2) by creating a service user and fetching an oauth token in the action and then using that to grab the user metadata and call appendUserGrant
depending on that metadata