Phase 10: Gitea OIDC login prerequisites in compose (external-only registration, auto-register, account linking); README steps

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 17:09:33 -05:00
parent 6db786e00e
commit b661ee795b
4 changed files with 31 additions and 9 deletions

View File

@@ -246,7 +246,7 @@ Checklist:
publishes the plugin zip is the obvious first pipeline publishes the plugin zip is the obvious first pipeline
- risk: the runner's Docker socket is root on the host for anyone who can push a workflow - risk: the runner's Docker socket is root on the host for anyone who can push a workflow
### Phase 10 — Gitea login via Authentik (OIDC) (later) ### Phase 10 — Gitea login via Authentik (OIDC) (compose done; Authentik + Gitea UI steps pending)
Same pattern as Jellyfin: Authentik is the identity, Gitea trusts it. Same pattern as Jellyfin: Authentik is the identity, Gitea trusts it.
- [ ] Authentik → Applications → Create with provider → OAuth2/OpenID: name `gitea`, redirect - [ ] Authentik → Applications → Create with provider → OAuth2/OpenID: name `gitea`, redirect
`https://git.HOST/user/oauth2/authentik/callback`, authorization flow implicit-consent, scopes `https://git.HOST/user/oauth2/authentik/callback`, authorization flow implicit-consent, scopes
@@ -255,11 +255,9 @@ Same pattern as Jellyfin: Authentik is the identity, Gitea trusts it.
provider OpenID Connect, name `authentik` (must match the callback path above), provider OpenID Connect, name `authentik` (must match the callback path above),
client ID/secret, discovery URL `https://auth.HOST/application/o/<slug>/.well-known/openid-configuration`, client ID/secret, discovery URL `https://auth.HOST/application/o/<slug>/.well-known/openid-configuration`,
"Skip local 2FA", claim mapping: group claim `groups` → Gitea admin group `admins` "Skip local 2FA", claim mapping: group claim `groups` → Gitea admin group `admins`
- [ ] Gitea app.ini / env: `GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION=true`, - [x] Gitea env: `DISABLE_REGISTRATION=false` + `ALLOW_ONLY_EXTERNAL_REGISTRATION=true` (local self-signup stays
`GITEA__oauth2_client__ACCOUNT_LINKING=auto`, `GITEA__oauth2_client__USERNAME=nickname` so first off), `ENABLE_AUTO_REGISTRATION`, `ACCOUNT_LINKING=auto`, `USERNAME=nickname`, `UPDATE_AVATAR`
Discord login creates the Gitea user with no form (registration stays closed for local accounts) - [ ] optional: hide the password form on the login page (custom template) so Discord is the only visible way in
- [ ] optional: `GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=true`, hide the password form on the
login page (`GITEA__oauth2_client__OPENID_CONNECT_SCOPES`, custom template) so Discord is the only way in
- [ ] policy on the Authentik application: who may reach Gitea at all (e.g. `admins` + a `devs` group) - [ ] policy on the Authentik application: who may reach Gitea at all (e.g. `admins` + a `devs` group)
- [ ] test with a non-admin Discord user; confirm admin mapping via `admins` group - [ ] test with a non-admin Discord user; confirm admin mapping via `admins` group

View File

@@ -204,6 +204,21 @@ already existed run `./createGiteaDb.sh` once.
Runner caveat: it holds the Docker socket, so anyone who can push a workflow can run as root on the box. Runner caveat: it holds the Docker socket, so anyone who can push a workflow can run as root on the box.
Keep repo write access to trusted people. Keep repo write access to trusted people.
**Login via Authentik (Discord)** — same pattern as Jellyfin, done once:
1. Authentik → Applications → Create with provider → name `Gitea`, slug `gitea`; **OAuth2/OpenID Provider**,
authorization flow implicit-consent, client type Confidential, redirect URI (strict)
`https://git.HOST/user/oauth2/authentik/callback`, signing key = the default certificate, scopes
`openid email profile` (the default profile mapping carries `preferred_username` and `groups`). Copy client ID + secret.
2. Gitea → Site Administration → Identity & Access → Authentication Sources → Add: type **OAuth2**, name
**`authentik`** (must match the callback path), provider **OpenID Connect**, client ID/secret, OpenID Connect
Auto Discovery URL `https://auth.HOST/application/o/gitea/.well-known/openid-configuration`, tick "Skip local
2FA", claim name for groups `groups`, administrator group claim value `admins`. Save.
3. compose (already set): registration only via external sources, auto-registration + account linking on,
username from `preferred_username`. A first Discord login creates the Gitea user with no form.
4. Test in a private window: https://git.HOST/user/login → "Sign in with authentik" → Discord → logged in.
Members of `admins` become Gitea site admins on login. The local admin account stays as a fallback.
Optional later: hide the password form (custom template) so Discord is the only visible way in.
## 5f. Live portal (`live.HOST`) ## 5f. Live portal (`live.HOST`)
React + dockview page (`live/`) behind Authentik forward-auth: every active stream is a dockable window, React + dockview page (`live/`) behind Authentik forward-auth: every active stream is a dockable window,

View File

@@ -57,7 +57,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
| Jellyfin | watch page, SSO via Authentik, direct play only | live | | Jellyfin | watch page, SSO via Authentik, direct play only | live |
| Vanguard Metadata plugin | seasons by tag, Discord names/avatars/events, feed, playback policy | **0.1.3 built** (flat `<Title>__<ts>` names, policy task, feed wording) — install pending; server has 0.1.0 or 0.1.2 | | Vanguard Metadata plugin | seasons by tag, Discord names/avatars/events, feed, playback policy | **0.1.3 built** (flat `<Title>__<ts>` names, policy task, feed wording) — install pending; server has 0.1.0 or 0.1.2 |
| MariaDB | databases for the bot and Gitea; public :3306, root local-only | live | | MariaDB | databases for the bot and Gitea; public :3306, root local-only | live |
| Gitea | git hosting on MariaDB, Actions enabled; holds this repo | live, local admin | | Gitea | git hosting on MariaDB, Actions enabled; holds this repo | live, local admin; Discord login via Authentik OIDC **compose ready, UI steps pending** |
| act_runner | CI jobs in Docker | **not registered** | | act_runner | CI jobs in Docker | **not registered** |
| discord-bot | Python runtime, idles until `bot/app/main.py` exists | live, no code yet | | discord-bot | Python runtime, idles until `bot/app/main.py` exists | live, no code yet |
| `bot.` host | bot web UI behind Authentik forward-auth; Caddy requires group `bot-users` (from a Discord role) | Caddy block live; **`bot` CNAME still points at the wrong IP; roles→groups policy pending** | | `bot.` host | bot web UI behind Authentik forward-auth; Caddy requires group `bot-users` (from a Discord role) | Caddy block live; **`bot` CNAME still points at the wrong IP; roles→groups policy pending** |
@@ -69,7 +69,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea
1. Authentik: `discord-roles-to-groups` policy so `streamers`/`editors`/`media-admins`/`bot-users` follow Discord roles (`bot-users` group needed for the bot host). Set the provider's Invalidation flow to `default-provider-invalidation-flow` so every logout forces a full re-login. 1. Authentik: `discord-roles-to-groups` policy so `streamers`/`editors`/`media-admins`/`bot-users` follow Discord roles (`bot-users` group needed for the bot host). Set the provider's Invalidation flow to `default-provider-invalidation-flow` so every logout forces a full re-login.
2. Confirm plugin 0.1.3 under Jellyfin → Plugins and the Gitea runner registered. 2. Confirm plugin 0.1.3 under Jellyfin → Plugins and the Gitea runner registered.
3. Portal viewer during a real stream: corner chip `webrtc`; Windows Go Live with WarDogs audio (first Windows streamer). 3. Portal viewer during a real stream: corner chip `webrtc`; Windows Go Live with WarDogs audio (first Windows streamer).
4. Gitea login via Authentik (plan phase 10). 4. Gitea login via Authentik: deploy the compose change, then the Authentik provider + Gitea auth source (README 5e).
5. Housekeeping: pin `AUTHENTIK_TAG`, rotate the Discord client secret seen in a screenshot, nightly Postgres dump, Caddyfile formatting warning. 5. Housekeeping: pin `AUTHENTIK_TAG`, rotate the Discord client secret seen in a screenshot, nightly Postgres dump, Caddyfile formatting warning.
6. Medal filename pattern in the plugin (need a sample filename). 6. Medal filename pattern in the plugin (need a sample filename).
7. Home archive puller on the home box. 7. Home archive puller on the home box.

View File

@@ -219,7 +219,16 @@ services:
GITEA__server__SSH_DOMAIN: ${GIT_HOST:-git.example.com} GITEA__server__SSH_DOMAIN: ${GIT_HOST:-git.example.com}
GITEA__server__SSH_PORT: "2222" # what users put in their remotes GITEA__server__SSH_PORT: "2222" # what users put in their remotes
GITEA__server__SSH_LISTEN_PORT: "22" # inside the container GITEA__server__SSH_LISTEN_PORT: "22" # inside the container
GITEA__service__DISABLE_REGISTRATION: "true" # accounts are created by an admin (or via Authentik OIDC later) # accounts come from Authentik (Discord) via OIDC: external auto-registration on, local self-registration off
GITEA__service__DISABLE_REGISTRATION: "false"
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true"
GITEA__service__SHOW_REGISTRATION_BUTTON: "false"
GITEA__service__REQUIRE_SIGNIN_VIEW: "false"
GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION: "true"
GITEA__oauth2_client__ACCOUNT_LINKING: auto
GITEA__oauth2_client__USERNAME: nickname # Authentik preferred_username
GITEA__oauth2_client__UPDATE_AVATAR: "true"
GITEA__oauth2_client__OPENID_CONNECT_SCOPES: openid email profile
GITEA__actions__ENABLED: "true" GITEA__actions__ENABLED: "true"
GITEA__actions__DEFAULT_ACTIONS_URL: github GITEA__actions__DEFAULT_ACTIONS_URL: github
GITEA__webhook__ALLOWED_HOST_LIST: private,loopback,external GITEA__webhook__ALLOWED_HOST_LIST: private,loopback,external