From bbba3d73b9932d26f87c751704c974de494e8e1b Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:37:09 +0200 Subject: [PATCH 1/7] docs(self-hosting): document generic OpenID Connect login Covers the OIDC_* variables added alongside the generic OIDC provider: discovery, callback, display name, RP-initiated logout, group-based access control and invite-free onboarding for self-hosted installs. Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 59 +++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index 48c9865..4912fdf 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -460,7 +460,7 @@ Raise the interval if you are close to Meta's app-wide quota. Horizon and the sc ## Social login -TryPost supports sign in with **Google** and **GitHub**. Both providers are off by default — set the corresponding `*_AUTH_ENABLED` flag and provide credentials to surface the buttons on the login/register pages. +TryPost supports sign in with **Google**, **GitHub** and any **OpenID Connect** provider. All of them are off by default — set the corresponding `*_AUTH_ENABLED` flag and provide credentials to surface the buttons on the login/register pages. ### Google @@ -488,6 +488,63 @@ GITHUB_AUTH_CALLBACK="${APP_URL}/auth/github/callback" Register a new OAuth App at [github.com/settings/developers](https://github.com/settings/developers) and set the **Authorization callback URL** to `${APP_URL}/auth/github/callback`. +### OpenID Connect + +Any spec-compliant OIDC provider — Authentik, Keycloak, Zitadel, Pocket ID, +Entra ID, Okta — can sign users in. Endpoints come from the provider's +discovery document, so only the issuer and the client credentials are needed. + +```env +OIDC_AUTH_ENABLED=true +OIDC_CLIENT_ID=your-client-id +OIDC_CLIENT_SECRET=your-client-secret +OIDC_DISCOVERY_URL=https://id.example.com +OIDC_AUTH_CALLBACK="${APP_URL}/auth/oidc/callback" +OIDC_SCOPES="openid profile email" +OIDC_DISPLAY_NAME="SSO" +``` + +`OIDC_DISCOVERY_URL` takes either the issuer URL or the full +`.well-known/openid-configuration` URL. `OIDC_DISPLAY_NAME` is what the button +reads: *Log in with SSO*. + +Register `${APP_URL}/auth/oidc/callback` as the redirect URI with your +provider. PKCE is always sent, so switch it on there if your provider treats it +as optional. Sign-in is refused if the provider reports the email address as +unverified, since accounts are matched by email. + + + The provider must publish a JWKS — ID token signatures are verified against + it, along with issuer, audience, expiry and a per-request nonce. + + +#### Signing out of the provider as well + +| Variable | Default | Description | +|----------|---------|-------------| +| `OIDC_LOGOUT_ENABLED` | `true` | When the provider publishes an `end_session_endpoint`, logging out of TryPost ends the session at the provider too. Turn it off to only clear the local session. | + +#### Restricting who may sign in + +| Variable | Default | Description | +|----------|---------|-------------| +| `OIDC_GROUPS_CLAIM` | `groups` | Claim carrying the group names, read from userinfo or the ID token | +| `OIDC_ALLOWED_GROUPS` | empty | Comma-separated groups allowed to sign in. Empty means the provider alone decides. | + +#### Onboarding without invites (self-hosted) + +By default a new user needs an invite, the same as with any other sign-up. On a +single-team install you can let provider group membership be the only +onboarding step instead: + +| Variable | Default | Description | +|----------|---------|-------------| +| `OIDC_AUTO_JOIN_ENABLED` | `false` | Place new OIDC users on the shared account instead of requiring an invite. Ignored unless `SELF_HOSTED=true`. | +| `OIDC_AUTO_JOIN_ROLE` | `member` | Role they join with: `admin`, `member` or `viewer` | +| `OIDC_AUTO_JOIN_ACCOUNT_ID` | oldest account | Account to join, for instances hosting more than one team | + +Existing members keep the role they already have; auto-join never changes it. + ## AI features (optional) The Generate / Review / Create AI flows in the post editor need a configured text-generation provider. Without one, the AI buttons stay disabled. See [AI Providers](/self-hosting/ai) for the full list of supported providers, per-provider model overrides, and OpenRouter-specific gotchas. From 2b3b394ae6495015cef450600f31b145548cc7dd Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:37:09 +0200 Subject: [PATCH 2/7] docs(self-hosting): clarify how unverified emails are handled Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index 4912fdf..94814fc 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -510,8 +510,13 @@ reads: *Log in with SSO*. Register `${APP_URL}/auth/oidc/callback` as the redirect URI with your provider. PKCE is always sent, so switch it on there if your provider treats it -as optional. Sign-in is refused if the provider reports the email address as -unverified, since accounts are matched by email. +as optional. + +An existing local account is adopted when the email addresses match, which is +how someone moves from a password to SSO. If the provider reports the address +as unverified, that adoption is refused - signing in still works, it just +creates a separate account. Providers that do no email verification at all are +therefore not locked out. The provider must publish a JWKS — ID token signatures are verified against From 704e371f0414d8f56412f34e1c3f7bba3c9c7570 Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:37:09 +0200 Subject: [PATCH 3/7] docs(self-hosting): document PASSWORD_LOGIN_ENABLED Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index 94814fc..a1be025 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -488,6 +488,26 @@ GITHUB_AUTH_CALLBACK="${APP_URL}/auth/github/callback" Register a new OAuth App at [github.com/settings/developers](https://github.com/settings/developers) and set the **Authorization callback URL** to `${APP_URL}/auth/github/callback`. +### Turning off email and password sign-in + +Once an identity provider is in place, the local password form is usually +unwanted: it is a second way in that your provider's policies — MFA, lockout, +offboarding — do not cover. + +```env +PASSWORD_LOGIN_ENABLED=false +``` + +This closes the login, password-reset and password-registration endpoints, not +just the form in the UI. The login page itself stays reachable, since that is +where the provider buttons live. + + + The setting is ignored while no other provider is enabled, so it can never + lock everybody out of an instance. Re-enable it in the environment if you + ever need the password form back. + + ### OpenID Connect Any spec-compliant OIDC provider — Authentik, Keycloak, Zitadel, Pocket ID, From 0b5a338bb948aad4644d72cc96e29394a3d78a11 Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:37:09 +0200 Subject: [PATCH 4/7] docs(self-hosting): document OIDC_POST_LOGOUT_REDIRECT_URI Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index a1be025..e966e3f 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -548,6 +548,14 @@ therefore not locked out. | Variable | Default | Description | |----------|---------|-------------| | `OIDC_LOGOUT_ENABLED` | `true` | When the provider publishes an `end_session_endpoint`, logging out of TryPost ends the session at the provider too. Turn it off to only clear the local session. | +| `OIDC_POST_LOGOUT_REDIRECT_URI` | empty | Where the provider returns the browser afterwards. Leave empty to stay on the provider's page. | + + + A post-logout redirect has to match a URI registered with your provider + character for character, trailing slash included. Providers reject the whole + logout request on a mismatch, which leaves the user signed in at the provider + while believing they are signed out. That is why nothing is sent by default. + #### Restricting who may sign in From f054d98f22f8756f8fda54de326740008c5a835f Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:37:09 +0200 Subject: [PATCH 5/7] docs(self-hosting): document OIDC_ADMIN_GROUPS Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index e966e3f..50de0f9 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -575,6 +575,13 @@ onboarding step instead: | `OIDC_AUTO_JOIN_ENABLED` | `false` | Place new OIDC users on the shared account instead of requiring an invite. Ignored unless `SELF_HOSTED=true`. | | `OIDC_AUTO_JOIN_ROLE` | `member` | Role they join with: `admin`, `member` or `viewer` | | `OIDC_AUTO_JOIN_ACCOUNT_ID` | oldest account | Account to join, for instances hosting more than one team | +| `OIDC_ADMIN_GROUPS` | empty | Groups whose members administer the workspace | + +With `OIDC_ADMIN_GROUPS` set, the workspace role of every OIDC user follows the +provider on each sign-in: in the group means admin, out of it means +`OIDC_AUTO_JOIN_ROLE`. An instance can then run without a standing local admin +account, and taking someone out of the group at the provider is all that +offboarding needs. Leave it empty to keep managing roles in the application. Existing members keep the role they already have; auto-join never changes it. From 01ba6da2a8b09834a3cde9c1d4a90d160aed0c0c Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:40:45 +0200 Subject: [PATCH 6/7] docs(self-hosting): note that ownership outranks the group role Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index 50de0f9..7419928 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -583,6 +583,13 @@ provider on each sign-in: in the group means admin, out of it means account, and taking someone out of the group at the provider is all that offboarding needs. Leave it empty to keep managing roles in the application. + + The account owner is left out of this. Ownership is resolved separately and + outranks the workspace role, so syncing it would show the owner as a member + while every permission stays in place. On a fresh install the first person to + sign in becomes the owner, so sign in yourself before inviting anyone. + + Existing members keep the role they already have; auto-join never changes it. ## AI features (optional) From b65ffe37e4aea2c47152fc82ee805caeabb8955f Mon Sep 17 00:00:00 2001 From: obelix58143 <88147701+obelix58143@users.noreply.github.com> Date: Mon, 14 Sep 2026 15:45:45 +0200 Subject: [PATCH 7/7] docs(self-hosting): document OIDC_RELEASE_OWNERSHIP Co-Authored-By: Claude Opus 5 --- self-hosting/configuration.mdx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index 7419928..bff55b0 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -576,6 +576,7 @@ onboarding step instead: | `OIDC_AUTO_JOIN_ROLE` | `member` | Role they join with: `admin`, `member` or `viewer` | | `OIDC_AUTO_JOIN_ACCOUNT_ID` | oldest account | Account to join, for instances hosting more than one team | | `OIDC_ADMIN_GROUPS` | empty | Groups whose members administer the workspace | +| `OIDC_RELEASE_OWNERSHIP` | `false` | Clear the account owner so every right comes from the groups | With `OIDC_ADMIN_GROUPS` set, the workspace role of every OIDC user follows the provider on each sign-in: in the group means admin, out of it means @@ -583,11 +584,21 @@ provider on each sign-in: in the group means admin, out of it means account, and taking someone out of the group at the provider is all that offboarding needs. Leave it empty to keep managing roles in the application. +The account owner is left out of the sync: ownership is resolved separately and +outranks the workspace role, so syncing it would show the owner as a member +while every permission stays in place. On a fresh install the first person to +sign in becomes the owner, so sign in yourself before inviting anyone. + +`OIDC_RELEASE_OWNERSHIP=true` removes that exception by clearing the owner +altogether, which is usually what an instance wants when the provider is meant +to decide who may do what. The owner-only actions - deleting a workspace and +billing - then become unavailable to everyone; connecting accounts, managing +the team and inviting run on the admin role and keep following the groups. + - The account owner is left out of this. Ownership is resolved separately and - outranks the workspace role, so syncing it would show the owner as a member - while every permission stays in place. On a fresh install the first person to - sign in becomes the owner, so sign in yourself before inviting anyone. + There is no way to transfer ownership, and deleting an owner deletes the + account and its workspaces with it. Releasing ownership is therefore also how + you retire a local admin account that an SSO-only instance no longer needs. Existing members keep the role they already have; auto-join never changes it.