Docs: Grafana JWT & jwt_claims_headers updates (#3226)

* feat(docs) Update Grafana docs to have auto_sign_up

* fix(docs) Add signout url

* update jwt_claims_headers reference

* update Grafana guide

Co-authored-by: Sara Jarjoura <sara@sensibleweather.com>
This commit is contained in:
Alex Fornuto 2022-04-01 09:59:03 -05:00 committed by GitHub
parent da159fe65b
commit 030d50c148
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 22 deletions

View file

@ -26,30 +26,24 @@ This guide begins with the following steps assumed complete:
This guide uses the following temporary values in commands and configuration examples, which will need to be adjusted for your setup:
- `http://grafana:3000` - The path Pomerium will use to access Grafana. This example emulates a common Docker-based setup.
- `http://grafana.local:3000` - The path to access the Grafana interface from your local computer. We will need direct access to add at least one user before Pomerium is configured.
- `http://grafana.local:3000` - The path to access the Grafana interface from your local computer. Depending on your desired configuration, you may need direct access to add at least one user before Pomerium is configured.
- `https://grafana.localhost.pomerium.io` - The path to access Grafana through Pomerium. Change this to match the domain space Pomerium is configured in.
## Enable JWT Authentication in Grafana
Edit `grafana.ini` to configure [JWT authentication]. Replace `auth.localhost.pomerium.io` with the value of [`authenticate_service_url`] in your Pomerium configuration:
```ini
```abnf
[auth]
signout_redirect_url = https://grafana.localhost.pomerium.io/.pomerium/sign_out ; signs users out of Pomerium when they sign out from Grafana
[auth.jwt]
enabled = true
header_name = X-Pomerium-Jwt-Assertion
email_claim = email
jwk_set_url = https://auth.localhost.pomerium.io/.well-known/pomerium/jwks.json
cache_ttl = 60m
enabled = true ;enables authentication by JWT
header_name = X-Pomerium-Jwt-Assertion ;defines the header to look at to provide the JWT
email_claim = email ;associates the email_claim in the JWT with the email of the Grafana user
jwk_set_url = https://auth.localhost.pomerium.io/.well-known/pomerium/jwks.json ;URL to the signing key to validate the JWT
cache_ttl = 60m ;sets a 60 minute cache time for the token
```
This configuration:
- enables authentication by JSON web token (**JWT**),
- defines the header to look at to provide the JWT,
- associates the email_claim in the JWT with the email of the Grafana user,
- specifies the location of the signing key for the JWT to validate it,
- sets a 60 minute cache time for the token.
Once you've saved and exited the file, restart Grafana.
## Add Users to Grafana
@ -57,9 +51,11 @@ Once you've saved and exited the file, restart Grafana.
At this stage Grafana is configured to use the `email` claim in the JWT to associate an incoming connection with a user. Pomerium will be configured to include identity information via the JWT in the next section. But the user must still exist in Grafana to be associated. Otherwise, you will see this error in the browser after authenticating:
```json
{"message":"Invalid JWT"}
{"message":"User not found"}
```
Further down in this guide we'll go over Grafana's `auto_sign_up` option to create users as needed. But first we should create at least one user with administrator privileges. If you plan on administering Grafana through a direct connection to the service, you can skip this section.
1. To add users without requiring them to accept an invitation, log in to Grafana directly as an admin user at `http://grafana.local:3000`.
1. Under the shield icon in the main menu (**Server Admin**), select **Users**.
@ -147,7 +143,60 @@ Once the new route is applied, users can access Grafana from `https://grafana.lo
### Manage Access at Scale
The steps outlined above work to confirm the configuration for small teams, but adding users individually and manually does not scale for larger organizations. To add users to Grafana at scale, consider using Grafana's Admin API and the [Global Users] endpoint to automate the creation of Grafana users with data from your IdP.
::: tip Note
Ensure that Grafana is up to date to take advantage of `auto_sign_up`, as it is only available for JWT as of version 8.4.0.
:::
The steps outlined above work to confirm the configuration for small teams, but adding users individually and manually does not scale for larger organizations. To add users to Grafana at scale, you can use the Grafana's `auto_sign_up`configuration to auto-signup users as they log in:
```abnf
[auth]
signout_redirect_url = https://grafana.localhost.pomerium.io/.pomerium/sign_out
[auth.jwt]
enabled = true
header_name = X-Pomerium-Jwt-Assertion
email_claim = email
jwk_set_url = https://auth.localhost.pomerium.io/.well-known/pomerium/jwks.json
cache_ttl = 60m
username_claim = sub ;sets the username to the value of the "sub" claim
auto_sign_up = true ;sets the login to automatically create a new user if one doesn't exist
[users]
auto_assign_org = true ;auto assigns the user to the existing default organization
auto_assign_org_role = Editor ;auto assigns the user the "Editor" role
```
Note that the value of `auto_assign_org_role` could also be "Admin" or "Viewer".
This will automatically create a user with their email and username populated. To have the "Name" field populated for users, you can set the `jwt_claims_headers` option in Pomerium to include `name` in the JWT payload:
::::: tabs
:::: tab config.yaml
```yaml
jwt_claims_headers: name
```
::::
:::: tab Environment Variable
```bash
JWT_CLAIMS_HEADERS=name
```
::::
:::: tab Pomerium Ingress Controller
```yaml
extraEnv:
JWT_CLAIMS_HEADERS: name
```
::::
:::::
This configuration will allow seamless authentication and authorization without any additional toil for your team.
::: tip Tip for Google Users
When using Google as an IdP, the user field is populated by a numeric value that you can not configure. Note that Grafana can accept the `name` field as a username, including spaces:
```abnf
username_claim = name
```
:::
## Troubleshooting

View file

@ -28,7 +28,7 @@ Pomerium can hot-reload route configuration details, authorization policy, certi
When running Pomerium as a single system service or container, all the options on this page can be set in a single `config.yaml` file, or passed to the single instance as environment variables.
When running Pomerium in a distributed environment where there are multiple processes, each handling separate [components](https://www.pomerium.com/docs/architecture.md#component-level), all components can still share a single config file or set of environment variables.
When running Pomerium in a distributed environment where there are multiple processes, each handling separate [components](/docs/architecture.md#component-level), all services can still share a single config file or set of environment variables.
Alternately, you can create individual config files or sets of environment variables for each service. When doing so, each file or set must have matching [shared settings](#shared-settings), as well as settings relevant to that [service mode](#service-mode). The list below is sorted to better differentiate which config options correlate to which service mode.
@ -994,7 +994,9 @@ users are encouraged to add these to `set_response_headers` or their downstream
The JWT Claim Headers setting allows you to pass specific user session data to upstream applications as HTTP request headers. Note, unlike the header `x-pomerium-jwt-assertion` these values are not signed by the authorization service.
Any claim in the pomerium session JWT can be placed into a corresponding header for upstream consumption. This claim information is sourced from your Identity Provider (IdP) and Pomerium's own session metadata. The header will have the following format:
Additionally, this will add the claim to the `X-Pomerium-Jwt-Assertion` header provided by [`pass_identity_headers`](#pass-identity-headers), if not already present.
Any claim in the pomerium session JWT can be placed into a corresponding header and the JWT payload for upstream consumption. This claim information is sourced from your Identity Provider (IdP) and Pomerium's own session metadata. The header will have the following format:
`X-Pomerium-Claim-{Name}` where `{Name}` is the name of the claim requested. Underscores will be replaced with dashes; e.g. `X-Pomerium-Claim-Given-Name`.

View file

@ -29,7 +29,7 @@ preamble: |
When running Pomerium as a single system service or container, all the options on this page can be set in a single `config.yaml` file, or passed to the single instance as environment variables.
When running Pomerium in a distributed environment where there are multiple processes, each handling separate [components](https://www.pomerium.com/docs/architecture.md#component-level), all services can still share a single config file or set of environment variables.
When running Pomerium in a distributed environment where there are multiple processes, each handling separate [components](/docs/architecture.md#component-level), all services can still share a single config file or set of environment variables.
Alternately, you can create individual config files or sets of environment variables for each service. When doing so, each file or set must have matching [shared settings](#shared-settings), as well as settings relevant to that [service mode](#service-mode). The list below is sorted to better differentiate which config options correlate to which service mode.
@ -1121,7 +1121,9 @@ settings:
doc: |
The JWT Claim Headers setting allows you to pass specific user session data to upstream applications as HTTP request headers. Note, unlike the header `x-pomerium-jwt-assertion` these values are not signed by the authorization service.
Any claim in the pomerium session JWT can be placed into a corresponding header for upstream consumption. This claim information is sourced from your Identity Provider (IdP) and Pomerium's own session metadata. The header will have the following format:
Additionally, this will add the claim to the `X-Pomerium-Jwt-Assertion` header provided by [`pass_identity_headers`](#pass-identity-headers), if not already present.
Any claim in the pomerium session JWT can be placed into a corresponding header and the JWT payload for upstream consumption. This claim information is sourced from your Identity Provider (IdP) and Pomerium's own session metadata. The header will have the following format:
`X-Pomerium-Claim-{Name}` where `{Name}` is the name of the claim requested. Underscores will be replaced with dashes; e.g. `X-Pomerium-Claim-Given-Name`.
@ -1136,7 +1138,7 @@ settings:
Use this option if you previously relied on `x-pomerium-authenticated-user-{email|user-id|groups}`.
shortdoc: |
The JWT Claim Headers setting allows you to pass specific user session data down to downstream applications as HTTP request headers.
The JWT Claim Headers setting allows you to pass specific user session data to upstream applications as HTTP request headers and additional JWT claims.
- name: "Override Certificate Name"
keys: ["override_certificate_name"]
attributes: |