Skip to content

Commit fbf96a5

Browse files
committed
fix it up
1 parent df57270 commit fbf96a5

File tree

6 files changed

+236
-2
lines changed

6 files changed

+236
-2
lines changed

docs/admin/auth/adfs.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Active Directory Federation Services OIDC with Coder (ADFS)
2+
3+
> **Note:** Tested on ADFS 4.0, Windows Server 2019
4+
5+
1. In your Federation Server, create a new application group for Coder. Follow the
6+
steps as described [here.](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/development/msal/adfs-msal-web-app-web-api#app-registration-in-ad-fs)
7+
- **Server Application**: Note the Client ID.
8+
- **Configure Application Credentials**: Note the Client Secret.
9+
- **Configure Web API**: Set the Client ID as the relying party identifier.
10+
- **Application Permissions**: Allow access to the claims `openid`, `email`, `profile`, and `allatclaims`.
11+
1. Visit your ADFS server's `/.well-known/openid-configuration` URL and note
12+
the value for `issuer`.
13+
> **Note:** This is usually of the form `https://adfs.corp/adfs/.well-known/openid-configuration`
14+
1. In Coder's configuration file (or Helm values as appropriate), set the following
15+
environment variables or their corresponding CLI arguments:
16+
17+
- `CODER_OIDC_ISSUER_URL`: the `issuer` value from the previous step.
18+
- `CODER_OIDC_CLIENT_ID`: the Client ID from step 1.
19+
- `CODER_OIDC_CLIENT_SECRET`: the Client Secret from step 1.
20+
- `CODER_OIDC_AUTH_URL_PARAMS`: set to
21+
22+
```console
23+
{"resource":"$CLIENT_ID"}
24+
```
25+
26+
where `$CLIENT_ID` is the Client ID from step 1 ([see here](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-openid-connect-oauth-flows-scenarios#:~:text=scope%E2%80%AFopenid.-,resource,-optional)).
27+
This is required for the upstream OIDC provider to return the requested claims.
28+
29+
- `CODER_OIDC_IGNORE_USERINFO`: Set to `true`.
30+
31+
1. Configure [Issuance Transform Rules](https://learn.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-rule-to-send-ldap-attributes-as-claims)
32+
on your federation server to send the following claims:
33+
34+
- `preferred_username`: You can use e.g. "Display Name" as required.
35+
- `email`: You can use e.g. the LDAP attribute "E-Mail-Addresses" as required.
36+
- `email_verified`: Create a custom claim rule:
37+
38+
```console
39+
=> issue(Type = "email_verified", Value = "true")
40+
```
41+
42+
- (Optional) If using Group Sync, send the required groups in the configured groups claim field. See [here](https://stackoverflow.com/a/55570286) for an example.

docs/admin/auth/group-role-sync.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Group & Role Sync (Enterprise)
2+
3+
You can use groups and roles from your identity provider as the definitive source for Coder's user roles and groups.
4+
5+
## How it Works
6+
7+
1. **Configure OIDC**: Adjust your OIDC identity provider settings to transmit claims via the OIDC token or userinfo endpoint. These claims, usually labeled `groups` and `roles`, aren't sent by default in most OIDC clients.
8+
9+
1. **Configure Coder Server**: Coder can either:
10+
- A) Create new groups in Coder, or
11+
- B) Map claims to existing Coder groups/roles.
12+
13+
1. **Roles Sync on Login**: Upon user authentication, their associated groups and roles synchronize with Coder, using the identity provider as the reference.
14+
15+
## Group Sync (enterprise)
16+
17+
If your OpenID Connect provider supports group claims, you can configure Coder
18+
to synchronize groups in your auth provider to groups within Coder.
19+
20+
To enable group sync, ensure that a groups claim is being sent. This is often `groups` or `memberOf`. Technically, a `roles` claim could be mapped to syncronize groups as Coder just expects an array of strings (e.g. `["Admin", "DevOps-Admin"`)
21+
22+
To check, [configure](../configure.md) the Coder server with the following environment variable to send verbose logs:
23+
24+
```sh
25+
CODER_VERBOSE=true
26+
```
27+
28+
Be sure to restart the server. When a user logs in with OIDC, you should see the following logs from the server.
29+
30+
31+
```sh
32+
[debu] coderd.userauth: got oidc claims trace=0x1b09780 span=0x1b09820 request_id=833f136a-2e6b-4df5-8ecb-1316c71a425a source=id_token claim_fields="[aio aud email exp groups iat idp iss name nbf oid preferred_username rh sub tid uti ver]" blank=[]
33+
34+
[debu] coderd.userauth: got oidc claims trace=0x1b09780 span=0x1b09820 request_id=833f136a-2e6b-4df5-8ecb-1316c71a425a source=userinfo claim_fields="[email family_name given_name name picture sub]" blank=[]
35+
36+
[debu] coderd.userauth: got oidc claims trace=0x1b09780 span=0x1b09820 request_id=833f136a-2e6b-4df5-8ecb-1316c71a425a 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=[]
37+
```
38+
39+
> ℹ️ In this example, Coder is successfully getting the `groups` OIDC claim from the token and merging the claims from userinfo endpoint. See below for troubleshooting instructions.
40+
41+
### Enabling Group Sync
42+
43+
To enable group sync, you must tell Coder which claim to be used:
44+
45+
```sh
46+
CODER_OIDC_GROUP_FIELD=groups
47+
```
48+
49+
By default, Coder will only sync groups that match an existing group in Coder. However, there are two other options.
50+
51+
#### Automatically Create New Groups
52+
53+
To automatically create groups in Coder if they don't exist, set the following server value:
54+
55+
```console
56+
CODER_OIDC_GROUP_AUTO_CREATE=true
57+
```
58+
59+
#### Configuring Group Mapping
60+
61+
For cases when an OIDC provider only returns group IDs ([Azure AD][azure-gids])
62+
or you want to have different group names in Coder than in your OIDC provider,
63+
you can configure mapping between the two.
64+
65+
```console
66+
CODER_OIDC_GROUP_MAPPING='{"myOIDCGroupID": "myCoderGroupName"}'
67+
```
68+
69+
Below is an example mapping in the Coder Helm chart:
70+
71+
```yaml
72+
coder:
73+
env:
74+
- name: CODER_OIDC_GROUP_MAPPING
75+
value: >
76+
{"myOIDCGroupID": "myCoderGroupName"}
77+
```
78+
79+
### Filtering Group Sync
80+
81+
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.
82+
83+
```console
84+
CODER_OIDC_GROUP_REGEX_FILTER="^my-group-.*$"
85+
```
86+
87+
## Role Sync (enterprise)
88+
89+
If your OpenID Connect provider supports roles claims, you can configure Coder
90+
to synchronize roles in your auth provider to deployment-wide roles within Coder.
91+
92+
Set the following in your Coder server [configuration](./configure.md).
93+
94+
```console
95+
# Depending on your identity provider configuration, you may need to explicitly request a "roles" scope
96+
CODER_OIDC_SCOPES=openid,profile,email,roles
97+
98+
# The following fields are required for role sync:
99+
CODER_OIDC_USER_ROLE_FIELD=roles
100+
CODER_OIDC_USER_ROLE_MAPPING='{"TemplateAuthor":["template-admin","user-admin"]}'
101+
```
102+
103+
> One role from your identity provider can be mapped to many roles in Coder (e.g. the example above maps to 2 roles in Coder.)
104+
105+
[azure-gids]: https://github.com/MicrosoftDocs/azure-docs/issues/59766#issuecomment-664387195
106+
107+
### Troubleshooting
108+
109+
Some common issues when enabling group and role sync.
110+
111+
#### No `groups` claim in the `got oidc claims` log
112+
113+
If you are not recieving the `groups` claim, refer to your identify provider documentation. In some cases, you will need to add the claim to your identity provider and request it via a scope in the OIDC config:
114+
115+
```sh
116+
CODER_OIDC_SCOPES=openid,profile,email,groups
117+
```
118+
119+
Here are some general steps:
120+
121+
1. Ensure the user is a part of a group in the IDP. If the user has 0 groups, no `groups` claim will be sent.
122+
2. Check if another claim appears to be the correct claim with a different name. A common name is `memberOf` instead of `groups`. If this is present, update `CODER_OIDC_GROUP_FIELD=memberOf`.
123+
3. 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 `groups` claim. A common solution is to create a filter on the identity provider that returns less than the limit for your IDP.
124+
- [Azure AD limit is 200, and omits groups if exceeded.](https://learn.microsoft.com/en-us/azure/active-directory/hybrid/connect/how-to-connect-fed-group-claims#options-for-applications-to-consume-group-information)
125+
- [Okta limit is 100, and returns an error if exceeded.](https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned)
126+
127+
#### Invalid Scope
128+
129+
If you see an error like the following, you may have an invalid scope.
130+
131+
```console
132+
The application '<oidc_application>' asked for scope 'groups' that doesn't exist on the resource...
133+
```
134+
135+
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.
136+
137+
The solution is to update the value of `CODER_OIDC_SCOPES` to the correct value for the identity provider.

docs/admin/auth/keycloak.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Keycloak Authentication with Coder
2+
3+
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.
4+
5+
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.
6+
7+
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.

docs/admin/auth/oidc.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ Restart your Coder server to apply this configuration. An OIDC authentication bu
2929

3030
![Log in with OIDC button](https://user-images.githubusercontent.com/22407953/261882891-7aa2e922-5572-490f-992a-07126bad0161.png)
3131

32+
## Provider Specific Notes
33+
34+
Any OIDC provider should work with Coder. With that being said, we have some special notes for specific providers.
35+
36+
- [Keycloak](./keycloak.md)
37+
- [Active Directory Federation Services (ADFS)](./adfs.md)
38+
39+
## Group and Role Sync (enterprise)
40+
41+
Learn how to do [group and role sync](group-role-sync.md) with COder.
42+
3243
## How Coder Reads OIDC claims
3344

3445
When a user logs in for the first time via OIDC, Coder will merge both
@@ -146,7 +157,7 @@ Restart your Coder server to apply this configuration.
146157
If you wish to manually onboard users, or use a [script](../automation.md) to add users to Coder, set:
147158

148159
```console
149-
UTH2=false
160+
CODER_OIDC_ALLOW_SIGNUPS=false
150161
```
151162

152163
This will prevent new users from logging in via GitHub. An admin can manually add GitHub users from the "Users" page.

docs/admin/auth/passwordless.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Passwordless Authentication
2+
3+
You can create passwordless users in users for machine accounts. This can come in handy if you plan on [automating Coder](../automation.md) in CI/CD pipelines, for example.
4+
5+
In the Users page `https://coder.example.com/users`, create a new user with `Login Type: none`:
6+
7+
![Create new user](https://user-images.githubusercontent.com/22407953/262183871-9a9070fa-ca35-4816-9990-465b16b94fe4.png)
8+
9+
From there, you can create a long-lived token on behalf of the passwordless user using the [Create token API key](../../api/users.md#create-token-api-key):
10+
11+
```sh
12+
# Replace API_KEY with a token from https://coder.example.com/cli-auth
13+
curl -X POST http://coder-server:8080/api/v2/users/coder-bot/keys/tokens \
14+
-H 'Content-Type: application/json' \
15+
-H 'Accept: application/json' \
16+
-H 'Coder-Session-Token: API_KEY'
17+
```
18+
19+
Then, follow our documentation in [automating Coder](../automation.md) to perform actions on behalf of this user using their API token.

docs/manifest.json

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,25 @@
278278
{
279279
"title": "OIDC",
280280
"description": "Configure OIDC authentication with Coder",
281-
"path": "./admin/auth/oidc.md"
281+
"path": "./admin/auth/oidc.md",
282+
"children": [
283+
{
284+
"title": "Keycloak",
285+
"description": "Authenticate to Coder with Keyclock",
286+
"path": "./admin/auth/keycloak.md"
287+
},
288+
{
289+
"title": "Active Directory Federation Services (ADFS)",
290+
"description": "Authenticate to Coder with ADFS",
291+
"path": "./admin/auth/adfs.md"
292+
},
293+
{
294+
"title": "Group and Role Sync",
295+
"description": "Sync groups and roles from your identity provider into Coder",
296+
"path": "./admin/auth/group-role-sync.md",
297+
"state": "enterprise"
298+
}
299+
]
282300
},
283301
{
284302
"title": "Passwordless",

0 commit comments

Comments
 (0)