[preview](https://coder.com/docs/@15431-docs-org-sync/admin/users/idp-sync#organization-sync-premium) --------- Co-authored-by: EdwardAngert <2408959-EdwardAngert@users.noreply.gitlab.com> Co-authored-by: EdwardAngert <17991901+EdwardAngert@users.noreply.github.com>
22 KiB
IDP Sync (enterprise) (premium)
If your OpenID Connect provider supports group claims, you can configure Coder
to synchronize groups in your auth provider to groups within Coder. To enable
group sync, ensure that the groups claim is being sent by your OpenID
provider. You might need to request an additional
scope or additional configuration
on the OpenID provider side.
If group sync is enabled, the user's groups will be controlled by the OIDC provider. This means manual group additions/removals will be overwritten on the next user login.
There are two ways you can configure group sync:
Server Flags
-
Confirm that your OIDC provider is sending claims.
Log in with OIDC and visit the following URL with an
Owneraccount:https://[coder.example.com]/api/v2/debug/[your-username]/debug-linkYou should see a field in either
id_token_claims,user_info_claimsor both followed by a list of the user's OIDC groups in the response. This is the claim sent by the OIDC provider.See Troubleshooting to debug this.
Depending on the OIDC provider, this claim may be called something else. Common names include
groups,memberOf, androles. -
Configure the Coder server to read groups from the claim name with the OIDC group field server flag:
-
Environment variable:
CODER_OIDC_GROUP_FIELD=groups -
As a flag:
--oidc-group-field groups
-
On login, users will automatically be assigned to groups that have matching names in Coder and removed from groups that the user no longer belongs to.
For cases when an OIDC provider only returns group IDs (Azure AD) or you want to have different group names in Coder than in your OIDC provider, you can configure mapping between the two with the OIDC group mapping server flag:
-
Environment variable:
CODER_OIDC_GROUP_MAPPING='{"myOIDCGroupID": "myCoderGroupName"}' -
As a flag:
--oidc-group-mapping '{"myOIDCGroupID": "myCoderGroupName"}'
Below is an example mapping in the Coder Helm chart:
coder:
env:
- name: CODER_OIDC_GROUP_MAPPING
value: >
{"myOIDCGroupID": "myCoderGroupName"}
From the example above, users that belong to the myOIDCGroupID group in your
OIDC provider will be added to the myCoderGroupName group in Coder.
Runtime (Organizations)
You must have a Premium license with Organizations enabled to use this. Contact your account team for more details.
For deployments with multiple organizations, you must configure group sync at the organization level. In future Coder versions, you will be able to configure this in the UI. For now, you must use CLI commands.
-
Confirm you have the Coder CLI installed and are logged in with a user who is an Owner or Organization Admin role.
-
Confirm that your OIDC provider is sending a groups claim.
Log in with OIDC and visit the following URL:
https://[coder.example.com]/api/v2/debug/[your-username]/debug-linkYou should see a field in either
id_token_claims,user_info_claimsor both followed by a list of the user's OIDC groups in the response. This is the claim sent by the OIDC provider.See Troubleshooting to debug this.
Depending on the OIDC provider, this claim may be called something else. Common names include
groups,memberOf, androles. -
To fetch the current group sync settings for an organization, run the following:
coder organizations settings show group-sync \ --org <org-name> \ > group-sync.jsonThe default for an organization looks like this:
{ "field": "", "mapping": null, "regex_filter": null, "auto_create_missing_groups": false }
Below is an example that uses the groups claim and maps all groups prefixed by
coder- into Coder:
{
"field": "groups",
"mapping": null,
"regex_filter": "^coder-.*$",
"auto_create_missing_groups": true
}
You much specify Coder group IDs instead of group names. The fastest way to find the ID for a corresponding group is by visiting
https://coder.example.com/api/v2/groups.
Here is another example which maps coder-admins from the identity provider to
two groups in Coder and coder-users from the identity provider to another
group:
{
"field": "groups",
"mapping": {
"coder-admins": [
"2ba2a4ff-ddfb-4493-b7cd-1aec2fa4c830",
"93371154-150f-4b12-b5f0-261bb1326bb4"
],
"coder-users": ["2f4bde93-0179-4815-ba50-b757fb3d43dd"]
},
"regex_filter": null,
"auto_create_missing_groups": false
}
To set these group sync settings, use the following command:
coder organizations settings set group-sync \
--org <org-name> \
< group-sync.json
Visit the Coder UI to confirm these changes:
Group allowlist
You can limit which groups from your identity provider can log in to Coder with CODER_OIDC_ALLOWED_GROUPS. Users who are not in a matching group will see the following error:
Role sync (enterprise) (premium)
If your OpenID Connect provider supports roles claims, you can configure Coder to synchronize roles in your auth provider to roles within Coder.
There are 2 ways to do role sync. Server Flags assign site wide roles, and runtime org role sync assigns organization roles
You must have a Premium license with Organizations enabled to use this. Contact your account team for more details.
Server Flags
-
Confirm that your OIDC provider is sending a roles claim by logging in with OIDC and visiting the following URL with an
Owneraccount:https://[coder.example.com]/api/v2/debug/[your-username]/debug-linkYou should see a field in either
id_token_claims,user_info_claimsor both followed by a list of the user's OIDC roles in the response. This is the claim sent by the OIDC provider.See Troubleshooting to debug this.
Depending on the OIDC provider, this claim may be called something else.
-
Configure the Coder server to read groups from the claim name with the OIDC role field server flag:
-
Set the following in your Coder server configuration.
# Depending on your identity provider configuration, you may need to explicitly request a "roles" scope CODER_OIDC_SCOPES=openid,profile,email,roles # The following fields are required for role sync: CODER_OIDC_USER_ROLE_FIELD=roles CODER_OIDC_USER_ROLE_MAPPING='{"TemplateAuthor":["template-admin","user-admin"]}'
One role from your identity provider can be mapped to many roles in Coder. The example above maps to two roles in Coder.
Runtime (Organizations)
For deployments with multiple organizations, you can configure role sync at the organization level. In future Coder versions, you will be able to configure this in the UI. For now, you must use CLI commands.
-
Confirm that your OIDC provider is sending a roles claim.
Log in with OIDC and visit the following URL with an
Owneraccount:https://[coder.example.com]/api/v2/debug/[your-username]/debug-linkYou should see a field in either
id_token_claims,user_info_claimsor both followed by a list of the user's OIDC roles in the response. This is the claim sent by the OIDC provider.See Troubleshooting to debug this.
Depending on the OIDC provider, this claim may be called something else.
-
To fetch the current group sync settings for an organization, run the following:
coder organizations settings show role-sync \ --org <org-name> \ > role-sync.jsonThe default for an organization looks like this:
{ "field": "", "mapping": null }
Below is an example that uses the roles claim and maps coder-admins from the
IDP as an Organization Admin and also maps to a custom provisioner-admin
role:
{
"field": "roles",
"mapping": {
"coder-admins": ["organization-admin"],
"infra-admins": ["provisioner-admin"]
}
}
Be sure to use the
namefield for each role, not the display name. Usecoder organization roles show --org=<your-org>to see roles for your organization.
To set these role sync settings, use the following command:
coder organizations settings set role-sync \
--org <org-name> \
< role-sync.json
Visit the Coder UI to confirm these changes:
Organization Sync (Premium)
If your OpenID Connect provider supports groups/role claims, you can configure Coder to synchronize claims in your auth provider to organizations within Coder.
Viewing and editing the organization settings requires deployment admin permissions (UserAdmin or Owner).
Organization sync works across all organizations. On user login, the sync will add and remove the user from organizations based on their IdP claims. After the sync, the user's state should match that of the IdP.
You can initiate an organization sync through the CLI or through the Coder dashboard:
Dashboard
-
Confirm that your OIDC provider is sending claims. Log in with OIDC and visit the following URL with an
Owneraccount:https://[coder.example.com]/api/v2/debug/[your-username]/debug-linkYou should see a field in either
id_token_claims,user_info_claimsor both followed by a list of the user's OIDC groups in the response. This is the claim sent by the OIDC provider. See Troubleshooting to debug this.Depending on the OIDC provider, this claim may be called something else. Common names include
groups,memberOf, androles. -
Fetch the corresponding organization IDs using the following endpoint:
https://[coder.example.com]/api/v2/organizations -
As a Coder organization user admin or site-wide user admin, go to Settings > IdP organization sync.
-
In the Organization sync field text box, enter the organization claim, then select Save.
Users are automatically added to the default organization.
Do not disable Assign Default Organization. If you disable the default organization, the system will remove users who are already assigned to it.
-
Enter an IdP organization name and Coder organization(s), then select Add IdP organization:
CLI
Use the Coder CLI to show and adjust the settings.
These deployment-wide settings are stored in the database. After you change the settings, a user's memberships will update when they log out and log back in.
-
Show the current settings:
coder organization settings show org-sync { "field": "organizations", "mapping": { "product": ["868e9b76-dc6e-46ab-be74-a891e9bd784b", "cbdcf774-9412-4118-8cd9-b3f502c84dfb"] }, "organization_assign_default": true } -
Update with the JSON payload. In this example,
settings.jsoncontains the payload:coder organization settings set org-sync < settings.json { "field": "organizations", "mapping": { "product": [ "868e5b23-dc6e-46ab-be74-a891e9bd784b", "cbdcf774-4123-4118-8cd9-b3f502c84dfb" ], "sales": [ "d79144d9-b30a-555a-9af8-7dac83b2q4ec", ] }, "organization_assign_default": true }Analyzing the JSON payload:
Field Explanation field If this field is the empty string "", then org-sync is disabled.
Org memberships must be manually configured through the UI or API.mapping Mapping takes a claim from the IdP, and associates it with 1 or more organizations by UUID.
No validation is done, so you can put UUID's of orgs that do not exist (a noop). The UI picker will allow selecting orgs from a drop down, and convert it to a UUID for you.organization_assign_default This setting exists for maintaining backwards compatibility with single org deployments, either through their upgrade, or in perpetuity.
If this is set to 'true', all users will always be assigned to the default organization regardless of the mappings and their IdP claims.
Troubleshooting group/role/organization sync
Some common issues when enabling group/role sync.
General guidelines
If you are running into issues with group/role sync:
-
View your Coder server logs and enable verbose mode.
-
To reduce noise, you can filter for only logs related to group/role sync:
CODER_VERBOSE=true CODER_LOG_FILTER=".*userauth.*|.*groups returned.*" -
Restart the server after changing these configuration values.
-
Attempt to log in, preferably with a user who has the
Ownerrole.
The logs for a successful group sync look like this (human-readable):
[debu] coderd.userauth: got oidc claims request_id=49e86507-6842-4b0b-94d4-f245e62e49f3 source=id_token claim_fields="[aio aud email exp groups iat idp iss name nbf oid preferred_username rh sub tid uti ver]" blank=[]
[debu] coderd.userauth: got oidc claims request_id=49e86507-6842-4b0b-94d4-f245e62e49f3 source=userinfo claim_fields="[email family_name given_name name picture sub]" blank=[]
[debu] coderd.userauth: got oidc claims request_id=49e86507-6842-4b0b-94d4-f245e62e49f3 source=merged claim_fields="[aio aud email exp family_name given_name groups iat idp iss name nbf oid picture preferred_username rh sub tid uti ver]" blank=[]
[debu] coderd: groups returned in oidc claims request_id=49e86507-6842-4b0b-94d4-f245e62e49f3 email=ben@coder.com username=ben len=3 groups="[c8048e91-f5c3-47e5-9693-834de84034ad 66ad2cc3-a42f-4574-a281-40d1922e5b65 70b48175-107b-4ad8-b405-4d888a1c466f]"
To view the full claim, the Owner role can visit this endpoint on their Coder deployment after logging in:
https://[coder.example.com]/api/v2/debug/[username]/debug-link
User not being assigned / Group does not exist
If you want Coder to create groups that do not exist, you can set the following environment variable.
If you enable this, your OIDC provider might be sending over many unnecessary groups. Use filtering options on the OIDC provider to limit the groups sent over to prevent creating excess groups.
# as an environment variable
CODER_OIDC_GROUP_AUTO_CREATE=true
# as a flag
--oidc-group-auto-create=true
A basic regex filtering option on the Coder side is available. This is applied
after the group mapping (CODER_OIDC_GROUP_MAPPING), meaning if the group
is remapped, the remapped value is tested in the regex. This is useful if you
want to filter out groups that do not match a certain pattern. For example, if
you want to only allow groups that start with my-group- to be created, you can
set the following environment variable.
# as an environment variable
CODER_OIDC_GROUP_REGEX_FILTER="^my-group-.*$"
# as a flag
--oidc-group-regex-filter="^my-group-.*$"
Invalid Scope
If you see an error like the following, you may have an invalid scope.
The application '<oidc_application>' asked for scope 'groups' that doesn't exist on the resource...
This can happen because the identity provider has a different name for the
scope. For example, Azure AD uses GroupMember.Read.All instead of groups.
You can find the correct scope name in the IDP's documentation. Some IDP's allow
configuring the name of this scope.
The solution is to update the value of CODER_OIDC_SCOPES to the correct value
for the identity provider.
No group claim in the got oidc claims log
Steps to troubleshoot.
- Ensure the user is a part of a group in the IDP. If the user has 0 groups, no
groupsclaim will be sent. - Check if another claim appears to be the correct claim with a different name.
A common name is
memberOfinstead ofgroups. If this is present, updateCODER_OIDC_GROUP_FIELD=memberOf. - Make sure the number of groups being sent is under the limit of the IDP. Some
IDPs will return an error, while others will just omit the
groupsclaim. A common solution is to create a filter on the identity provider that returns less than the limit for your IDP.
Provider-Specific Guides
Below are some details specific to individual OIDC providers.
Active Directory Federation Services (ADFS)
Note: Tested on ADFS 4.0, Windows Server 2019
-
In your Federation Server, create a new application group for Coder. Follow the steps as described here.
- Server Application: Note the Client ID.
- Configure Application Credentials: Note the Client Secret.
- Configure Web API: Set the Client ID as the relying party identifier.
- Application Permissions: Allow access to the claims
openid,email,profile, andallatclaims.
-
Visit your ADFS server's
/.well-known/openid-configurationURL and note the value forissuer.Note: This is usually of the form
https://adfs.corp/adfs/.well-known/openid-configuration -
In Coder's configuration file (or Helm values as appropriate), set the following environment variables or their corresponding CLI arguments:
-
CODER_OIDC_ISSUER_URL: theissuervalue from the previous step. -
CODER_OIDC_CLIENT_ID: the Client ID from step 1. -
CODER_OIDC_CLIENT_SECRET: the Client Secret from step 1. -
CODER_OIDC_AUTH_URL_PARAMS: set to{"resource":"$CLIENT_ID"}where
$CLIENT_IDis the Client ID from step 1 (see here). This is required for the upstream OIDC provider to return the requested claims. -
CODER_OIDC_IGNORE_USERINFO: Set totrue.
-
-
Configure Issuance Transform Rules on your federation server to send the following claims:
-
preferred_username: You can use e.g. "Display Name" as required. -
email: You can use e.g. the LDAP attribute "E-Mail-Addresses" as required. -
email_verified: Create a custom claim rule:=> issue(Type = "email_verified", Value = "true") -
(Optional) If using Group Sync, send the required groups in the configured groups claim field. See here for an example.
-
Keycloak
The access_type parameter has two possible values: "online" and "offline." By default, the value is set to "offline". This means that when a user authenticates using OIDC, the application requests offline access to the user's resources, including the ability to refresh access tokens without requiring the user to reauthenticate.
To enable the offline_access scope, which allows for the refresh token
functionality, you need to add it to the list of requested scopes during the
authentication flow. Including the offline_access scope in the requested
scopes ensures that the user is granted the necessary permissions to obtain
refresh tokens.
By combining the {"access_type":"offline"} parameter in the OIDC Auth URL with
the offline_access scope, you can achieve the desired behavior of obtaining
refresh tokens for offline access to the user's resources.


