diff --git a/assets/gitea-deploy-keys.png b/assets/gitea-deploy-keys.png deleted file mode 100644 index 36ca141..0000000 Binary files a/assets/gitea-deploy-keys.png and /dev/null differ diff --git a/docs/sso-and-identity.md b/docs/sso-and-identity.md index 736317a..b704cda 100644 --- a/docs/sso-and-identity.md +++ b/docs/sso-and-identity.md @@ -1,6 +1,7 @@ - @@ -60,7 +61,7 @@ This is the actual live query against Authentik's API, not a paraphrase of what' ``` $ curl -s -H "Authorization: Bearer [REDACTED]" \ "https://authentik.[service-to-service zone]/api/v3/providers/proxy/?page_size=1" | jq '.pagination.count' -96 +94 $ curl -s -H "Authorization: Bearer [REDACTED]" \ "https://authentik.[service-to-service zone]/api/v3/providers/proxy/?page_size=200" | jq -r '.results[].name' | grep -E '^proxmox' [no output — Proxmox has no Proxy Provider at all] @@ -91,11 +92,23 @@ So an app's OIDC discovery/authority setting always points at the service-to-ser ## Git Access: least privilege, not the admin account -Automation should never run with more privilege than it needs. CI and orchestration pushes (the flows described in [`docs/orchestration.md`](orchestration.md)) run through a dedicated, non-admin bot account with scoped write access — never through an administrator identity. This wasn't the original setup: automated pushes used to run through the personal admin account used for interactive access, the same one with full admin rights over the Git server. That got fixed by standing up a separate account with its own SSH keypair and adding it as a write collaborator on every repo it touches — routine automated commits no longer run under an admin credential at all. Hosts that only need to *read* get separate read-only deploy keys instead of any shared credential. The practical payoff: if an automation credential ever leaks, the blast radius is "can push to specific repos," not "has full admin control of the Git server." +Automation should never run with more privilege than it needs. CI and orchestration pushes (the flows described in [`docs/orchestration.md`](orchestration.md)) run through a dedicated, non-admin bot account with scoped write access — never through an administrator identity. This wasn't the original setup: automated pushes used to run through the personal admin account used for interactive access, the same one with full admin rights over the Git server. That got fixed by standing up a separate account with its own SSH keypair and adding it as a write collaborator on every repo it touches — routine automated commits no longer run under an admin credential at all. The 5 docker hosts that only ever pull (never push) use that same bot account's key too — copied identically to each host at first provisioning, not a separate credential per host. The practical payoff: if an automation credential ever leaks, the blast radius is "can push to the repos this bot account touches," not "has full admin control of the Git server." ![Gitea repo collaborators: automation-bot with Write access, not an admin account](../assets/gitea-collaborators-automation-bot.png) -![Gitea repo deploy keys: a host-specific key scoped to Read only](../assets/gitea-deploy-keys.png) +This is the real provisioning task, not a description of it — the automation-bot key gets copied to every docker host identically: + +``` +# The automation-bot private key - authenticates the push to Gitea AND signs +# commits (ssh_key_path == ssh_signing_key_path). Copied from the control node. +- name: Install the automation-bot git key + copy: + src: "{{ ssh_key_path }}" + dest: "{{ ssh_key_path }}" + owner: "{{ git_repo_owner }}" + group: "{{ git_repo_group }}" + mode: "0600" +``` --- Related: [`docs/dns-naming.md`](dns-naming.md), [`docs/orchestration.md`](orchestration.md), [`docs/secrets-and-pki.md`](secrets-and-pki.md) · Stacks: [`stacks/identity-and-security/authentik/`](../stacks/identity-and-security/authentik/), [`stacks/platform/gitea/`](../stacks/platform/gitea/)