-
Notifications
You must be signed in to change notification settings - Fork 63
OIDC Documentation #100
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
+358
−17
Merged
OIDC Documentation #100
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import {createMarkdownRenderer} from 'vitepress'; | ||
|
|
||
| const SOURCE = 'https://raw.githubusercontent.com/gotify/server/master/gotify-server.env.example'; | ||
|
|
||
| const uncomment = (line: string): string => line.replace(/^#( ?)/, ''); | ||
| const codeBlock = (text: string) => '```\n' + text.trimEnd() + '\n```'; | ||
|
|
||
| const renderSetting = (block: string[]): string => { | ||
| const assignment = block.find((l) => /^[A-Z][A-Z0-9_]*=/.test(uncomment(l))); | ||
| if (!assignment) throw Error('could not find assignment ' + block); | ||
|
|
||
| const name = uncomment(assignment).split('=')[0]; | ||
| return ['### ' + name, codeBlock(block.join('\n'))].join('\n\n'); | ||
| }; | ||
|
|
||
| export default { | ||
| async load() { | ||
| const res = await fetch(SOURCE); | ||
| if (!res.ok) throw Error('could not fetch gotify-server.env.example'); | ||
|
|
||
| const [header, ...blocks] = (await res.text()) | ||
| .trimEnd() | ||
| .split(/\n *\n/) | ||
| .map((b) => b.split('\n')) | ||
| .filter((b) => b.some((l) => l.trim())); | ||
|
|
||
| const markdown = [ | ||
| codeBlock(header.map(uncomment).join('\n')), | ||
| ...blocks.map(renderSetting), | ||
| ].join('\n\n'); | ||
|
|
||
| return (await createMarkdownRenderer('.')).render(markdown); | ||
| }, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| # Migrate to 3.x | ||
|
|
||
| - The `config.yml` file is no longer supported, convert it to the new env format | ||
| with [`migrate-config`](#migrating-your-config). | ||
| - If you set list or map environment variables, their syntax changed, see | ||
| [List and map syntax](#list-and-map-syntax). | ||
| - If you have scripts hitting client-token endpoints, they may now need | ||
| [elevation](#adapting-your-scripts). | ||
|
|
||
| ## Config Changes | ||
|
|
||
| ### YAML config file removed | ||
|
|
||
| The YAML config file (`config.yml`) is no longer supported. Gotify can now be | ||
| only configured by environment variables, which can be loaded from an env file. | ||
| The first existing file from this search order is loaded: | ||
|
|
||
| 1. `gotify-server.env` (in the working directory) | ||
| 2. `$XDG_CONFIG_HOME/gotify/gotify-server.env` (`$XDG_CONFIG_HOME` falls back to `$HOME/.config` when unset) | ||
| 3. `/etc/gotify/server.env` | ||
|
|
||
| See the [Configuration](/docs/config) page for the full list of variables. | ||
|
|
||
| ### Migrating your config | ||
|
|
||
| The `migrate-config` command converts an existing `config.yml` to the new env | ||
| format. It prints the result to stdout. | ||
|
|
||
| ```bash | ||
| $ gotify-server migrate-config config.yml > gotify-server.env | ||
| ``` | ||
|
|
||
| With Docker: | ||
|
|
||
| ```bash | ||
| $ docker run --rm -v "$(pwd)/config.yml:/app/config.yml" gotify/server \ | ||
| migrate-config config.yml > gotify-server.env | ||
| ``` | ||
|
|
||
| ### Environment List and map syntax | ||
|
|
||
| Defining settings via environment variables was already possible, but the syntax | ||
| for list and map values has changed. If you set any of the variables below, update | ||
| their format. | ||
|
|
||
| **Lists** are now comma-separated instead of a YAML array: | ||
|
|
||
| - `GOTIFY_SERVER_TRUSTEDPROXIES` | ||
| - `GOTIFY_SERVER_CORS_ALLOWORIGINS` | ||
| - `GOTIFY_SERVER_CORS_ALLOWMETHODS` | ||
| - `GOTIFY_SERVER_CORS_ALLOWHEADERS` | ||
| - `GOTIFY_SERVER_STREAM_ALLOWEDORIGINS` | ||
| - `GOTIFY_SERVER_SSL_LETSENCRYPT_HOSTS` | ||
| - `GOTIFY_OIDC_SCOPES` | ||
|
|
||
| ```bash | ||
| # before | ||
| GOTIFY_SERVER_TRUSTEDPROXIES=[127.0.0.1/32, ::1] | ||
| # after | ||
| GOTIFY_SERVER_TRUSTEDPROXIES=127.0.0.1/32,::1 | ||
| ``` | ||
|
|
||
| **Maps** are now a JSON object instead of a YAML map: | ||
|
|
||
| - `GOTIFY_SERVER_RESPONSEHEADERS` | ||
|
|
||
| ```bash | ||
| # before | ||
| GOTIFY_SERVER_RESPONSEHEADERS={X-Custom-Header: "custom value"} | ||
| # after | ||
| GOTIFY_SERVER_RESPONSEHEADERS={"X-Custom-Header":"custom value"} | ||
| ``` | ||
|
|
||
| ## API Changes | ||
|
|
||
| Introduces step-up authentication via time-limited [session | ||
| elevation](./session-elevation.md). A session/client token must re-authenticate | ||
| before sensitive, hard-to-undo actions. | ||
|
|
||
| HTTP Basic auth and application tokens are unaffected. | ||
|
|
||
| ### Endpoints that now require elevation | ||
|
|
||
| With a non-elevated client token these return `403`: | ||
|
|
||
| | Endpoint | Action | | ||
| | :-------------------------------------------- | :----------------------------- | | ||
| | `POST /current/user/password` | Change current user's password | | ||
| | `DELETE /client/{id}` | Delete a client | | ||
| | `DELETE /application/{id}` | Delete an application | | ||
| | `POST /client/{id}/elevate` | Elevate a client token | | ||
| | `GET /user`, `GET`/`POST`/`DELETE /user/{id}` | Manage users (admin) | | ||
|
|
||
| The `Client` and `CurrentUser` models have gotten elevation-related fields. See the | ||
| [API documentation](/api-docs) for details. | ||
|
|
||
| ### Adapting your scripts | ||
|
|
||
| Scripts that hit the endpoints above with a client token now need that token to | ||
| be elevated. Either: | ||
|
|
||
| - Use HTTP Basic auth as they are elevated by default. | ||
| - Elevate the client in the WebUI or the api with basic auth. | ||
|
|
||
| ## CLI Changes | ||
|
|
||
| The binary now uses subcommands. You should migrate to using the `serve` | ||
| subcommand. For backwards compatibility running gotify without a command will | ||
| continue to serve the server. | ||
|
|
||
| ```bash | ||
| $ ./gotify-linux-amd64 serve | ||
| ``` | ||
|
|
||
| The Docker image already defaults to `serve`, so `docker run` and Docker Compose | ||
| setups keep working unchanged. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| # OpenID Connect (OIDC) | ||
|
|
||
| [[toc]] | ||
|
|
||
| Gotify supports OpenID Connect for Single Sign-On (SSO), allowing users to authenticate via an external identity provider such as Authelia or Dex. | ||
|
|
||
| ::: warning | ||
| The identity provider **must** support [PKCE](https://oauth.net/2/pkce/) (Proof Key for Code Exchange). IdPs without PKCE support are currently unsupported. | ||
| ::: | ||
|
|
||
| ## Configuration | ||
|
|
||
| | Variable | Description | | ||
| | :----------------------------- | :--------------------------------------------------------------------------------------------------------- | | ||
| | `GOTIFY_OIDC_ENABLED` | Enable OIDC login. | | ||
| | `GOTIFY_OIDC_ISSUER` | The OIDC issuer URL. Used to discover endpoints via `/.well-known/openid-configuration`. | | ||
| | `GOTIFY_OIDC_CLIENTID` | The client ID registered with your identity provider. | | ||
| | `GOTIFY_OIDC_CLIENTSECRET` | The client secret. | | ||
| | `GOTIFY_OIDC_REDIRECTURL` | The callback URL the identity provider redirects to after authentication. Must match your provider config. | | ||
| | `GOTIFY_OIDC_AUTOREGISTER` | Automatically create a new Gotify user on first OIDC login. | | ||
| | `GOTIFY_OIDC_USERNAMECLAIM` | The OIDC claim used to determine the username. Common values: `preferred_username` or `email`. | | ||
| | `GOTIFY_OIDC_LINK_BY_USERNAME` | Link an OIDC identity to an existing local user with the same username. Disabled by default. | | ||
| | `GOTIFY_OIDC_SCOPES` | Comma-separated scopes to request. Defaults to `openid,profile,email`. | | ||
|
|
||
| ```bash | ||
| GOTIFY_OIDC_ENABLED=true | ||
| GOTIFY_OIDC_ISSUER=https://auth.example.org | ||
| GOTIFY_OIDC_CLIENTID=gotify | ||
| GOTIFY_OIDC_CLIENTSECRET=YOUR_CLIENT_SECRET | ||
| GOTIFY_OIDC_REDIRECTURL=https://gotify.example.org/auth/oidc/callback | ||
| GOTIFY_OIDC_AUTOREGISTER=true | ||
| GOTIFY_OIDC_USERNAMECLAIM=preferred_username | ||
| GOTIFY_OIDC_LINK_BY_USERNAME=false | ||
| GOTIFY_OIDC_SCOPES=openid,profile,email | ||
| ``` | ||
|
|
||
| See the [Configuration](/docs/config) page for the full config reference. | ||
|
|
||
| ### Redirect URL | ||
|
|
||
| - The redirect URL must always end with `/auth/oidc/callback`. | ||
| - If Gotify is served at the root, the redirect URL is `https://gotify.example.org/auth/oidc/callback`. | ||
| - If Gotify is served on a sub-path (e.g. behind a reverse proxy at `/gotify/`), the sub-path must be included: `https://example.org/gotify/auth/oidc/callback`. | ||
| - For the **Android app** to support OIDC login, you must add `gotify://oidc/callback` as an additional redirect URL in your identity provider's client configuration. | ||
|
|
||
| This URL must match **exactly** between the Gotify config and your identity provider's client configuration. | ||
|
|
||
| ## Linking by username | ||
|
|
||
| Gotify identifies users by username. When the OIDC username claim clashes with an existing local user that is not yet bound to an OIDC identity, this login is rejected by default. Set `GOTIFY_OIDC_LINK_BY_USERNAME=true` to bind OIDC identities to existing local users. | ||
|
|
||
| Only enable it if you trust that usernames in your identity provider map to the same people as your Gotify usernames. | ||
|
|
||
| ## Sample IdP Config | ||
|
|
||
| ### Authelia | ||
|
|
||
| [Authelia](https://www.authelia.com/) is a self-hosted authentication and authorization server. | ||
|
|
||
| ::: details Authelia configuration (configuration.yml) | ||
|
|
||
| ```yml | ||
| identity_providers: | ||
| oidc: | ||
| clients: | ||
| - client_id: 'gotify' | ||
| client_name: 'gotify' | ||
| client_secret: '$pbkdf2-sha512$310000$...' # generate with: authelia crypto hash generate pbkdf2 | ||
| public: false | ||
| authorization_policy: 'two_factor' | ||
| require_pkce: true | ||
| pkce_challenge_method: 'S256' | ||
| consent_mode: implicit | ||
| redirect_uris: | ||
| - 'https://gotify.example.org/auth/oidc/callback' # See redirect url docs | ||
| - 'gotify://oidc/callback' # Required for Android app OIDC login | ||
| scopes: | ||
| - 'openid' | ||
| - 'profile' | ||
| - 'email' | ||
| response_types: | ||
| - 'code' | ||
| grant_types: | ||
| - 'authorization_code' | ||
| access_token_signed_response_alg: 'none' | ||
| userinfo_signed_response_alg: 'none' | ||
| token_endpoint_auth_method: 'client_secret_basic' | ||
| ``` | ||
|
|
||
| ::: | ||
|
|
||
| ### Dex | ||
|
|
||
| [Dex](https://dexidp.io/) is a federated OpenID Connect provider. | ||
|
|
||
| ::: details Dex configuration | ||
|
|
||
| ```yml | ||
| staticClients: | ||
| - id: gotify | ||
| redirectURIs: | ||
| - 'https://gotify.example.org/auth/oidc/callback' # See redirect url docs | ||
| - 'gotify://oidc/callback' # Required for Android app OIDC login | ||
| name: 'Gotify' | ||
| secret: secret | ||
| ``` | ||
|
|
||
| ::: |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.