mirror of https://github.com/grafana/grafana.git
363 lines
14 KiB
Markdown
363 lines
14 KiB
Markdown
|
---
|
|||
|
aliases:
|
|||
|
- /docs/grafana/latest/auth/generic-oauth/
|
|||
|
- /docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/
|
|||
|
description: Grafana OAuthentication Guide
|
|||
|
keywords:
|
|||
|
- grafana
|
|||
|
- configuration
|
|||
|
- documentation
|
|||
|
- oauth
|
|||
|
title: Configure generic OAuth authentication
|
|||
|
weight: 200
|
|||
|
---
|
|||
|
|
|||
|
# Configure generic OAuth authentication
|
|||
|
|
|||
|
You can configure many different OAuth2 authentication services with Grafana using the generic OAuth2 feature. Examples:
|
|||
|
|
|||
|
- [Generic OAuth authentication](#generic-oauth-authentication)
|
|||
|
- [Set up OAuth2 with Auth0](#set-up-oauth2-with-auth0)
|
|||
|
- [Set up OAuth2 with Bitbucket](#set-up-oauth2-with-bitbucket)
|
|||
|
- [Set up OAuth2 with Centrify](#set-up-oauth2-with-centrify)
|
|||
|
- [Set up OAuth2 with OneLogin](#set-up-oauth2-with-onelogin)
|
|||
|
- [Role mapping](#role-mapping)
|
|||
|
- [Team synchronization](#team-synchronization)
|
|||
|
|
|||
|
This callback URL must match the full HTTP address that you use in your browser to access Grafana, but with the suffixed path of `/login/generic_oauth`.
|
|||
|
|
|||
|
You may have to set the `root_url` option of `[server]` for the callback URL to be
|
|||
|
correct. For example in case you are serving Grafana behind a proxy.
|
|||
|
|
|||
|
Example config:
|
|||
|
|
|||
|
```bash
|
|||
|
[auth.generic_oauth]
|
|||
|
name = OAuth
|
|||
|
icon = signin
|
|||
|
enabled = true
|
|||
|
client_id = YOUR_APP_CLIENT_ID
|
|||
|
client_secret = YOUR_APP_CLIENT_SECRET
|
|||
|
scopes =
|
|||
|
empty_scopes = false
|
|||
|
auth_url =
|
|||
|
token_url =
|
|||
|
api_url =
|
|||
|
allowed_domains = mycompany.com mycompany.org
|
|||
|
allow_sign_up = true
|
|||
|
tls_skip_verify_insecure = false
|
|||
|
tls_client_cert =
|
|||
|
tls_client_key =
|
|||
|
tls_client_ca =
|
|||
|
use_pkce = true
|
|||
|
auth_style =
|
|||
|
```
|
|||
|
|
|||
|
Set `api_url` to the resource that returns [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo) compatible information.
|
|||
|
|
|||
|
You can also specify the SSL/TLS configuration used by the client.
|
|||
|
|
|||
|
- Set `tls_client_cert` to the path of the certificate.
|
|||
|
- Set `tls_client_key` to the path containing the key.
|
|||
|
- Set `tls_client_ca` to the path containing a trusted certificate authority list.
|
|||
|
|
|||
|
`tls_skip_verify_insecure` controls whether a client verifies the server's certificate chain and host name. If it is true, then SSL/TLS accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks.
|
|||
|
|
|||
|
`auth_style` controls which [OAuth2 AuthStyle](https://pkg.go.dev/golang.org/x/oauth2#AuthStyle) is used when token is requested from OAuth provider. It determines how `client_id` and `client_secret` are sent to Oauth provider.
|
|||
|
Available values are `AutoDetect`, `InParams` and `InHeader`. By default, `AutoDetect` is used.
|
|||
|
|
|||
|
Set `empty_scopes` to true to use an empty scope during authentication. By default, Grafana uses `user:email` as scope.
|
|||
|
|
|||
|
### Email address
|
|||
|
|
|||
|
Grafana determines a user's email address by querying the OAuth provider until it finds an e-mail address:
|
|||
|
|
|||
|
1. Check for the presence of an e-mail address via the `email` field encoded in the OAuth `id_token` parameter.
|
|||
|
1. Check for the presence of an e-mail address using the [JMESPath](http://jmespath.org/examples.html) specified via the `email_attribute_path` configuration option. The JSON used for the path lookup is the HTTP response obtained from querying the UserInfo endpoint specified via the `api_url` configuration option.
|
|||
|
**Note**: Only available in Grafana v6.4+.
|
|||
|
1. Check for the presence of an e-mail address in the `attributes` map encoded in the OAuth `id_token` parameter. By default Grafana will perform a lookup into the attributes map using the `email:primary` key, however, this is configurable and can be adjusted by using the `email_attribute_name` configuration option.
|
|||
|
1. Query the `/emails` endpoint of the OAuth provider's API (configured with `api_url`), then check for the presence of an email address marked as a primary address.
|
|||
|
1. If no email address is found in steps (1-4), then the email address of the user is set to an empty string.
|
|||
|
|
|||
|
### Groups / Teams
|
|||
|
|
|||
|
Similarly, group mappings are made using [JMESPath](http://jmespath.org/examples.html) with the `groups_attribute_path` configuration option. The `id_token` is attempted first, followed by the UserInfo from the `api_url`. The result of the JMESPath expression should be a string array of groups.
|
|||
|
|
|||
|
Furthermore, Grafana will check for the presence of at least one of the teams specified via the `team_ids` configuration option using the [JMESPath](http://jmespath.org/examples.html) specified via the `team_ids_attribute_path` configuration option. The JSON used for the path lookup is the HTTP response obtained from querying the Teams endpoint specified via the `teams_url` configuration option (using `/teams` as a fallback endpoint). The result should be a string array of Grafana Team IDs. Using this setting ensures that only certain teams is allowed to authenticate to Grafana using your OAuth provider.
|
|||
|
|
|||
|
### Login
|
|||
|
|
|||
|
Customize user login using `login_attribute_path` configuration option. Order of operations is as follows:
|
|||
|
|
|||
|
1. Grafana evaluates the `login_attribute_path` JMESPath expression against the ID token.
|
|||
|
1. If Grafana finds no value, then Grafana evaluates expression against the JSON data obtained from UserInfo endpoint. The UserInfo endpoint URL is specified in the `api_url` configuration option.
|
|||
|
|
|||
|
You can customize the attribute name used to extract the ID token from the returned OAuth token with the `id_token_attribute_name` option.
|
|||
|
|
|||
|
You can set the user's display name with JMESPath using the `name_attribute_path` configuration option. It operates the same way as the `login_attribute_path` option.
|
|||
|
|
|||
|
> **Note:** `name_attribute_path` is available in Grafana 7.4+.
|
|||
|
|
|||
|
### PKCE
|
|||
|
|
|||
|
> Available in Grafana v8.3 and later versions.
|
|||
|
|
|||
|
IETF's [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636)
|
|||
|
introduces "proof key for code exchange" (PKCE) which introduces
|
|||
|
additional protection against some forms of authorization code
|
|||
|
interception attacks. PKCE will be required in [OAuth 2.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-03).
|
|||
|
|
|||
|
You can enable PKCE in Grafana by setting `use_pkce` to `true` in the
|
|||
|
`[auth.generic_oauth]` section.
|
|||
|
|
|||
|
```
|
|||
|
use_pkce = true
|
|||
|
```
|
|||
|
|
|||
|
Grafana always uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier.
|
|||
|
|
|||
|
## Set up OAuth2 with Auth0
|
|||
|
|
|||
|
1. Create a new Client in Auth0
|
|||
|
|
|||
|
- Name: Grafana
|
|||
|
- Type: Regular Web Application
|
|||
|
|
|||
|
1. Go to the Settings tab and set:
|
|||
|
|
|||
|
- Allowed Callback URLs: `https://<grafana domain>/login/generic_oauth`
|
|||
|
|
|||
|
1. Click Save Changes, then use the values at the top of the page to configure Grafana:
|
|||
|
|
|||
|
```bash
|
|||
|
[auth.generic_oauth]
|
|||
|
enabled = true
|
|||
|
allow_sign_up = true
|
|||
|
team_ids =
|
|||
|
allowed_organizations =
|
|||
|
name = Auth0
|
|||
|
client_id = <client id>
|
|||
|
client_secret = <client secret>
|
|||
|
scopes = openid profile email
|
|||
|
auth_url = https://<domain>/authorize
|
|||
|
token_url = https://<domain>/oauth/token
|
|||
|
api_url = https://<domain>/userinfo
|
|||
|
use_pkce = true
|
|||
|
```
|
|||
|
|
|||
|
## Set up OAuth2 with Bitbucket
|
|||
|
|
|||
|
```bash
|
|||
|
[auth.generic_oauth]
|
|||
|
name = BitBucket
|
|||
|
enabled = true
|
|||
|
allow_sign_up = true
|
|||
|
client_id = <client id>
|
|||
|
client_secret = <client secret>
|
|||
|
scopes = account email
|
|||
|
auth_url = https://bitbucket.org/site/oauth2/authorize
|
|||
|
token_url = https://bitbucket.org/site/oauth2/access_token
|
|||
|
api_url = https://api.bitbucket.org/2.0/user
|
|||
|
teams_url = https://api.bitbucket.org/2.0/user/permissions/workspaces
|
|||
|
team_ids_attribute_path = values[*].workspace.slug
|
|||
|
team_ids =
|
|||
|
allowed_organizations =
|
|||
|
```
|
|||
|
|
|||
|
## Set up OAuth2 with Centrify
|
|||
|
|
|||
|
1. Create a new Custom OpenID Connect application configuration in the Centrify dashboard.
|
|||
|
|
|||
|
1. Create a memorable unique Application ID, e.g. "grafana", "grafana_aws", etc.
|
|||
|
|
|||
|
1. Put in other basic configuration (name, description, logo, category)
|
|||
|
|
|||
|
1. On the Trust tab, generate a long password and put it into the OpenID Connect Client Secret field.
|
|||
|
|
|||
|
1. Put the URL to the front page of your Grafana instance into the "Resource Application URL" field.
|
|||
|
|
|||
|
1. Add an authorized Redirect URI like https://your-grafana-server/login/generic_oauth
|
|||
|
|
|||
|
1. Set up permissions, policies, etc. just like any other Centrify app
|
|||
|
|
|||
|
1. Configure Grafana as follows:
|
|||
|
|
|||
|
```bash
|
|||
|
[auth.generic_oauth]
|
|||
|
name = Centrify
|
|||
|
enabled = true
|
|||
|
allow_sign_up = true
|
|||
|
client_id = <OpenID Connect Client ID from Centrify>
|
|||
|
client_secret = <your generated OpenID Connect Client Secret"
|
|||
|
scopes = openid profile email
|
|||
|
auth_url = https://<your domain>.my.centrify.com/OAuth2/Authorize/<Application ID>
|
|||
|
token_url = https://<your domain>.my.centrify.com/OAuth2/Token/<Application ID>
|
|||
|
api_url = https://<your domain>.my.centrify.com/OAuth2/UserInfo/<Application ID>
|
|||
|
```
|
|||
|
|
|||
|
## Set up OAuth2 with OneLogin
|
|||
|
|
|||
|
1. Create a new Custom Connector with the following settings:
|
|||
|
|
|||
|
- Name: Grafana
|
|||
|
- Sign On Method: OpenID Connect
|
|||
|
- Redirect URI: `https://<grafana domain>/login/generic_oauth`
|
|||
|
- Signing Algorithm: RS256
|
|||
|
- Login URL: `https://<grafana domain>/login/generic_oauth`
|
|||
|
|
|||
|
then:
|
|||
|
|
|||
|
1. Add an App to the Grafana Connector:
|
|||
|
|
|||
|
- Display Name: Grafana
|
|||
|
|
|||
|
then:
|
|||
|
|
|||
|
1. Under the SSO tab on the Grafana App details page you'll find the Client ID and Client Secret.
|
|||
|
|
|||
|
Your OneLogin Domain will match the URL you use to access OneLogin.
|
|||
|
|
|||
|
Configure Grafana as follows:
|
|||
|
|
|||
|
```bash
|
|||
|
[auth.generic_oauth]
|
|||
|
name = OneLogin
|
|||
|
enabled = true
|
|||
|
allow_sign_up = true
|
|||
|
client_id = <client id>
|
|||
|
client_secret = <client secret>
|
|||
|
scopes = openid email name
|
|||
|
auth_url = https://<onelogin domain>.onelogin.com/oidc/2/auth
|
|||
|
token_url = https://<onelogin domain>.onelogin.com/oidc/2/token
|
|||
|
api_url = https://<onelogin domain>.onelogin.com/oidc/2/me
|
|||
|
team_ids =
|
|||
|
allowed_organizations =
|
|||
|
```
|
|||
|
|
|||
|
## Role Mapping
|
|||
|
|
|||
|
Grafana checks for the presence of a role using the [JMESPath](http://jmespath.org/examples.html) specified via the `role_attribute_path` configuration option. The JMESPath is applied to the `id_token` first. If there is no match, then the UserInfo endpoint specified via the `api_url` configuration option is tried next. The result after evaluation of the `role_attribute_path` JMESPath expression should be a valid Grafana role, for example, `Viewer`, `Editor` or `Admin`.
|
|||
|
|
|||
|
For more information, refer to the [JMESPath examples](#jmespath-examples).
|
|||
|
|
|||
|
> **Warning**: Currently if no organization role mapping is found for a user, Grafana doesn't
|
|||
|
> update the user's organization role. This is going to change in Grafana 10. To avoid overriding manually set roles,
|
|||
|
> enable the `oauth_skip_org_role_update_sync` option.
|
|||
|
> See [configure-grafana]({{< relref "../../../configure-grafana#oauth_skip_org_role_update_sync" >}}) for more information.
|
|||
|
|
|||
|
On first login, if the`role_attribute_path` property does not return a role, then the user is assigned the role
|
|||
|
specified by [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}).
|
|||
|
You can disable this default role assignment by setting `role_attribute_strict = true`.
|
|||
|
It denies user access if no role or an invalid role is returned.
|
|||
|
|
|||
|
> **Warning**: With Grafana 10, **on every login**, if the`role_attribute_path` property does not return a role,
|
|||
|
> then the user is assigned the role specified by
|
|||
|
> [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}).
|
|||
|
|
|||
|
### JMESPath examples
|
|||
|
|
|||
|
#### Map user organization role
|
|||
|
|
|||
|
To ease configuration of a proper JMESPath expression, you can test/evaluate expressions with custom payloads at http://jmespath.org/.
|
|||
|
|
|||
|
**Basic example:**
|
|||
|
|
|||
|
In the following example user will get `Editor` as role when authenticating. The value of the property `role` will be the resulting role if the role is a proper Grafana role, i.e. `Viewer`, `Editor` or `Admin`.
|
|||
|
|
|||
|
Payload:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
...
|
|||
|
"role": "Editor",
|
|||
|
...
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Config:
|
|||
|
|
|||
|
```bash
|
|||
|
role_attribute_path = role
|
|||
|
```
|
|||
|
|
|||
|
**Advanced example:**
|
|||
|
|
|||
|
In the following example user will get `Admin` as role when authenticating since it has a role `admin`. If a user has a role `editor` it will get `Editor` as role, otherwise `Viewer`.
|
|||
|
|
|||
|
Payload:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
...
|
|||
|
"info": {
|
|||
|
...
|
|||
|
"roles": [
|
|||
|
"engineer",
|
|||
|
"admin",
|
|||
|
],
|
|||
|
...
|
|||
|
},
|
|||
|
...
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Config:
|
|||
|
|
|||
|
```bash
|
|||
|
role_attribute_path = contains(info.roles[*], 'admin') && 'Admin' || contains(info.roles[*], 'editor') && 'Editor' || 'Viewer'
|
|||
|
```
|
|||
|
|
|||
|
#### Map server administrator privileges
|
|||
|
|
|||
|
> Available in Grafana v9.2 and later versions.
|
|||
|
|
|||
|
If the application role received by Grafana is `GrafanaAdmin`, Grafana grants the user server administrator privileges.
|
|||
|
This is useful if you want to grant server administrator privileges to a subset of users.
|
|||
|
Grafana also assigns the user the `Admin` role of the default organization.
|
|||
|
|
|||
|
The setting `allow_assign_grafana_admin` under `[auth.generic_oauth]` must be set to `true` for this to work.
|
|||
|
If the setting is set to `false`, the user is assigned the role of `Admin` of the default organization, but not server administrator privileges.
|
|||
|
|
|||
|
```ini
|
|||
|
allow_assign_grafana_admin = true
|
|||
|
```
|
|||
|
|
|||
|
Example:
|
|||
|
|
|||
|
```ini
|
|||
|
role_attribute_path = contains(info.roles[*], 'admin') && 'GrafanaAdmin' || contains(info.roles[*], 'editor') && 'Editor' || 'Viewer'
|
|||
|
```
|
|||
|
|
|||
|
## Team synchronization
|
|||
|
|
|||
|
> Available in Grafana Enterprise v8.1 and later versions.
|
|||
|
|
|||
|
With Team Sync you can map your Generic OAuth groups to teams in Grafana so that the users are automatically added to the correct teams.
|
|||
|
|
|||
|
Generic OAuth groups can be referenced by group ID, like `8bab1c86-8fba-33e5-2089-1d1c80ec267d` or `myteam`.
|
|||
|
|
|||
|
[Learn more about Team Sync]({{< relref "../../configure-team-sync/" >}})
|
|||
|
|
|||
|
Config:
|
|||
|
|
|||
|
```bash
|
|||
|
groups_attribute_path = info.groups
|
|||
|
```
|
|||
|
|
|||
|
Payload:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
...
|
|||
|
"info": {
|
|||
|
...
|
|||
|
"groups": [
|
|||
|
"engineers",
|
|||
|
"analysts",
|
|||
|
],
|
|||
|
...
|
|||
|
},
|
|||
|
...
|
|||
|
}
|
|||
|
```
|