netbirdio / netbird

Connect your devices into a secure WireGuard®-based overlay network with SSO, MFA and granular access controls.
https://netbird.io
BSD 3-Clause "New" or "Revised" License
11.02k stars 505 forks source link

Group sync with Zitadel #1713

Open sisumara opened 7 months ago

sisumara commented 7 months ago

Describe the problem

I've been trying to configure self-hosted Netbird with Zitadel as IDP to use user roles which I've created under the Netbird project in Zitadel, but without any success. I've tried to use the claims as it is described in Zitadel's manual, but without any success. I've tried to use these claims:

To Reproduce

Steps to reproduce the behavior:

  1. Create user roles in Zitadel under Netbird's project.
  2. Add described claims to Settiings -> Groups -> Enable JWT group sync -> JWT Claim
  3. Get error in management logs: JWT claim "urn:zitadel:iam:org:projects:roles" not found

Expected behavior

I expect to get user Roles from Zitadel to assign different groups in Netbird.

Are you using NetBird Cloud?

Self-host NetBird's control plane.

NetBird version

0.26.3

Screenshots

Screenshot 2024-03-15 at 8 54 39 AM Screenshot 2024-03-15 at 8 56 08 AM Screenshot 2024-03-15 at 8 55 54 AM
mlsmaycon commented 7 months ago

hello @sisumara, it seems like the claim is not the correct one. To discover the correct claim, please open your browser's development tools, and get one request to the management API, e.g., /api/users, there you will find an authentication header with a Bearer token, which you can copy and paste into the https://jwt.io/ website, then you will see the claims parsed in the payload view. Choose the one that maps to the roles.

sisumara commented 7 months ago

hello @sisumara, it seems like the claim is not the correct one. To discover the correct claim, please open your browser's development tools, and get one request to the management API, e.g., /api/users, there you will find an authentication header with a Bearer token, which you can copy and paste into the https://jwt.io/ website, then you will see the claims parsed in the payload view. Choose the one that maps to the roles.

I've tried that approach, but this the only one Bearer token which I've found in there and there is no any mentions about groups. Here is how it looks like:

Screenshot 2024-03-17 at 11 12 18 AM

What am I doing wrong?

sisumara commented 7 months ago

I've found that Zitadel includes information about the roles if you enable "Assert Roles on Authentication" option in Project settings.

Screenshot 2024-03-17 at 9 10 41 PM

Then the token includes information about user roles like this:

"urn:zitadel:iam:org:project:256448444641310477:roles": {
    "netbird-admin": {
      "356409606912278797": "my-idp-domain"
    },
    "netbird-user": {
      "356409606912278797": "my-idp-domain"
    }
  },
  "urn:zitadel:iam:org:project:roles": {
    "netbird-admin": {
      "356409606912278797": "my-idp-domain"
    },
    "netbird-user": {
      "356409606912278797": "my-idp-domain"
    }
  }
}

But when I try to add the claim urn:zitadel:iam:org:project:256448444641310477:roles or urn:zitadel:iam:org:project:roles to the dashboard I see this error in log - DEBG management/server/account.go:1677: JWT claim "urn:zitadel:iam:org:project:roles" is not a string array

chris-si commented 7 months ago

Hi,

I'm also having trouble syncing the groups via JWT. The claims exist in the access token like @sisumara already described but NetBird somehow cannot read them correctly.

With the claim urn:zitadel:iam:org:project:<netBirdProjectId>:roles which exists inside the access token, I also get the following error with NetBird v0.26.6: DEBG management/server/account.go:1721: JWT claim "urn:zitadel:iam:org:project:<netBirdProjectId>:roles" is not a string array

1ndef1n1te commented 3 months ago

Hello @sisumara @chris-si , u can do the following steps for configure IdP(Zitadel) auto-groups with Netbird:

Zitadel configuration:

1) Netbird need list of groups for auto-group working when zitadel default claims return objects, because of that u need to create custom action in Zitadel with following content:

function flatRoles(ctx, api) {
  if (ctx.v1.user.grants == undefined || ctx.v1.user.grants.count == 0) {
    return;
  }

  let grants = [];
  ctx.v1.user.grants.grants.forEach(claim => {
    claim.roles.forEach(role => {
        grants.push(role)  
    })
  })

  api.v1.claims.setClaim('groups', grants)
}

Select Flow: Complement token, Triggers: Pre Userinfo creation, Pre access token creation Note that name of action need to be the same like function in this action 2) Create Role in Zitadel: Project -> Netbird project -> Roles -> + New 3) Go to the Authorizations -> Select user -> Select Netbird project and choose the correct roles for the user

Netbird configuration

1) Go to the Settings -> Groups -> Enable JWT group sync and JWT claim should be the same like in action (In this example groups)

After that configuration users should sync roles with Zitadel. but we still fight with SYNCING because in our setup Netbird only add groups from IdP but not delete groups when when delete it in IdP, could u @mlsmaycon help me with this problem?

UPDATE: our problem seems to be solved