-
Notifications
You must be signed in to change notification settings - Fork 902
docs: rework "admin/authentication" page + PKI authentication docs #9236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Active Directory Federation Services OIDC with Coder (ADFS) | ||
|
||
> **Note:** Tested on ADFS 4.0, Windows Server 2019 | ||
|
||
1. In your Federation Server, create a new application group for Coder. Follow the | ||
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) | ||
- **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`, and `allatclaims`. | ||
1. Visit your ADFS server's `/.well-known/openid-configuration` URL and note | ||
the value for `issuer`. | ||
> **Note:** This is usually of the form `https://adfs.corp/adfs/.well-known/openid-configuration` | ||
1. In Coder's configuration file (or Helm values as appropriate), set the following | ||
environment variables or their corresponding CLI arguments: | ||
|
||
- `CODER_OIDC_ISSUER_URL`: the `issuer` value 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 | ||
|
||
```console | ||
{"resource":"$CLIENT_ID"} | ||
``` | ||
|
||
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)). | ||
This is required for the upstream OIDC provider to return the requested claims. | ||
|
||
- `CODER_OIDC_IGNORE_USERINFO`: Set to `true`. | ||
|
||
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) | ||
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: | ||
|
||
```console | ||
=> issue(Type = "email_verified", Value = "true") | ||
``` | ||
|
||
- (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. |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO, this section should not be under auth directory as it is not an auth method but a feature on top of OIDC/SAML. May be we should have a subdirectory OIDC under auth directory and move this along with setting up OIDC. These are my thoughts, and they are not very important. If you feel the current flow and organization are right. Please ignore this comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, that makes sense to me too. Like "Identity Providers" can be a subsection under |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,137 @@ | ||||||||
# Group & Role Sync (Enterprise) | ||||||||
|
||||||||
You can use groups and roles from your identity provider as the definitive source for Coder's user roles and groups. | ||||||||
|
||||||||
## How it Works | ||||||||
|
||||||||
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. | ||||||||
|
||||||||
1. **Configure Coder Server**: Coder can either: | ||||||||
- A) Create new groups in Coder, or | ||||||||
- B) Map claims to existing Coder groups/roles. | ||||||||
|
||||||||
1. **Roles Sync on Login**: Upon user authentication, their associated groups and roles synchronize with Coder, using the identity provider as the reference. | ||||||||
|
||||||||
## Group Sync (enterprise) | ||||||||
|
||||||||
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 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"`) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
To check, [configure](../configure.md) the Coder server with the following environment variable to send verbose logs: | ||||||||
|
||||||||
```sh | ||||||||
CODER_VERBOSE=true | ||||||||
``` | ||||||||
|
||||||||
Be sure to restart the server. When a user logs in with OIDC, you should see the following logs from the server. | ||||||||
|
||||||||
|
||||||||
```sh | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
shell is more general |
||||||||
[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=[] | ||||||||
|
||||||||
[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=[] | ||||||||
|
||||||||
[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=[] | ||||||||
``` | ||||||||
|
||||||||
> ℹ️ 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. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not related to this PR. But I wonder if we should have different types of Notes e.g., Note A note Important An important information Warning Be careful here https://github.com/orgs/community/discussions/16925 for details There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @BrunoQuaresma, can these be rendered on coder.com/v2/docs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
### Enabling Group Sync | ||||||||
|
||||||||
To enable group sync, you must tell Coder which claim to be used: | ||||||||
|
||||||||
```sh | ||||||||
CODER_OIDC_GROUP_FIELD=groups | ||||||||
``` | ||||||||
|
||||||||
By default, Coder will only sync groups that match an existing group in Coder. However, there are two other options. | ||||||||
|
||||||||
#### Automatically Create New Groups | ||||||||
|
||||||||
To automatically create groups in Coder if they don't exist, set the following server value: | ||||||||
|
||||||||
```console | ||||||||
CODER_OIDC_GROUP_AUTO_CREATE=true | ||||||||
``` | ||||||||
|
||||||||
#### Configuring Group Mapping | ||||||||
|
||||||||
For cases when an OIDC provider only returns group IDs ([Azure AD][azure-gids]) | ||||||||
or you want to have different group names in Coder than in your OIDC provider, | ||||||||
you can configure mapping between the two. | ||||||||
|
||||||||
```console | ||||||||
CODER_OIDC_GROUP_MAPPING='{"myOIDCGroupID": "myCoderGroupName"}' | ||||||||
``` | ||||||||
|
||||||||
Below is an example mapping in the Coder Helm chart: | ||||||||
|
||||||||
```yaml | ||||||||
coder: | ||||||||
env: | ||||||||
- name: CODER_OIDC_GROUP_MAPPING | ||||||||
value: > | ||||||||
{"myOIDCGroupID": "myCoderGroupName"} | ||||||||
``` | ||||||||
|
||||||||
### Filtering Group Sync | ||||||||
|
||||||||
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. | ||||||||
|
||||||||
```console | ||||||||
CODER_OIDC_GROUP_REGEX_FILTER="^my-group-.*$" | ||||||||
``` | ||||||||
|
||||||||
## Role Sync (enterprise) | ||||||||
|
||||||||
If your OpenID Connect provider supports roles claims, you can configure Coder | ||||||||
to synchronize roles in your auth provider to deployment-wide roles within Coder. | ||||||||
|
||||||||
Set the following in your Coder server [configuration](./configure.md). | ||||||||
|
||||||||
```console | ||||||||
# 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 (e.g. the example above maps to 2 roles in Coder.) | ||||||||
|
||||||||
[azure-gids]: https://github.com/MicrosoftDocs/azure-docs/issues/59766#issuecomment-664387195 | ||||||||
|
||||||||
### Troubleshooting | ||||||||
|
||||||||
Some common issues when enabling group and role sync. | ||||||||
|
||||||||
#### No `groups` claim in the `got oidc claims` log | ||||||||
|
||||||||
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: | ||||||||
|
||||||||
```sh | ||||||||
CODER_OIDC_SCOPES=openid,profile,email,groups | ||||||||
``` | ||||||||
|
||||||||
Here are some general steps: | ||||||||
|
||||||||
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. | ||||||||
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`. | ||||||||
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. | ||||||||
- [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) | ||||||||
- [Okta limit is 100, and returns an error if exceeded.](https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned) | ||||||||
|
||||||||
#### Invalid Scope | ||||||||
|
||||||||
If you see an error like the following, you may have an invalid scope. | ||||||||
|
||||||||
```console | ||||||||
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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Keycloak Authentication with Coder | ||
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we provide the example? CODER_OIDC_SCOPES=openid,profile,email,offline_access There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better if we also include an example |
||
|
||
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. |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,19 @@ | ||||||||||
# Passwordless Authentication | ||||||||||
|
||||||||||
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. | ||||||||||
|
||||||||||
In the Users page `https://coder.example.com/users`, create a new user with `Login Type: none`: | ||||||||||
|
||||||||||
 | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace image path with realative |
||||||||||
|
||||||||||
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): | ||||||||||
|
||||||||||
```sh | ||||||||||
# Replace API_KEY with a token from https://coder.example.com/cli-auth | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
curl -X POST http://coder-server:8080/api/v2/users/coder-bot/keys/tokens \ | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
-H 'Content-Type: application/json' \ | ||||||||||
-H 'Accept: application/json' \ | ||||||||||
-H 'Coder-Session-Token: API_KEY' | ||||||||||
``` | ||||||||||
|
||||||||||
Then, follow our documentation in [automating Coder](../automation.md) to perform actions on behalf of this user using their API token. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.