From 4b30ba0cfd9f16b97a70695fa5b54a8f0d2b5f02 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sun, 30 Aug 2026 00:48:10 +1000 Subject: [PATCH 1/2] Add repospawner machine user scoped to terraform-git repospawner opens repo-creation PRs against terraform-git and needs no other access, so give it its own identity and a per-repo team instead of adding it to the org-wide agents team. - add config/git.unkin.net/user/repospawner.yaml (limited visibility, not admin, no org/repo creation), mirroring the unkin-agent bot posture - add config/git.unkin.net/unkin/team/repospawner.yaml granting write on the terraform-git repository only (include_all_repositories false) --- .../git.unkin.net/unkin/team/repospawner.yaml | 16 ++++++++++++++++ config/git.unkin.net/user/repospawner.yaml | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 config/git.unkin.net/unkin/team/repospawner.yaml create mode 100644 config/git.unkin.net/user/repospawner.yaml diff --git a/config/git.unkin.net/unkin/team/repospawner.yaml b/config/git.unkin.net/unkin/team/repospawner.yaml new file mode 100644 index 0000000..5aec440 --- /dev/null +++ b/config/git.unkin.net/unkin/team/repospawner.yaml @@ -0,0 +1,16 @@ +# Least-privilege access for the repospawner bot: Write on terraform-git only, +# which is the minimum Gitea permission that allows pushing a branch and opening +# a pull request. repospawner does its whole job here (repo-creation PRs), so it +# is kept out of the org-wide "agents" team (include_all_repositories: true). +# +# Merge stays reserved for Ben: branch protection on terraform-git's main sets a +# merge whitelist of the Owners team only. Keep this team out of every merge and +# approval whitelist. +description: "repospawner bot -- push branches + open PRs on terraform-git only" +permission: write +include_all_repositories: false +can_create_repos: false +repositories: + - terraform-git +members: + - repospawner diff --git a/config/git.unkin.net/user/repospawner.yaml b/config/git.unkin.net/user/repospawner.yaml new file mode 100644 index 0000000..8bea574 --- /dev/null +++ b/config/git.unkin.net/user/repospawner.yaml @@ -0,0 +1,19 @@ +# Service identity for repospawner, which opens pull requests against this +# repository (terraform-git) to add new Gitea repositories on request. It is +# deliberately separate from unkin-agent so its access can stay scoped to the +# single repository it needs: the "repospawner" team (unkin/team/repospawner.yaml) +# grants Write on terraform-git and nothing else. +# +# Auth is via ephemeral API tokens minted by the vault-plugin-secrets-gitea +# engine -- no usable credential lives in this repo's state beyond the generated +# placeholder. Merge stays blocked by branch protection (merge whitelist = +# Owners only), so it can push branches and open PRs but never merge. +email: repospawner@unkin.net +full_name: "Repo Spawner" +description: "repospawner service identity -- opens repo-creation PRs against terraform-git" +# Conservative bot posture: not a site admin, cannot create orgs or repos, +# profile visible only to signed-in users. +visibility: limited +admin: false +allow_create_organization: false +max_repo_creation: 0 From dd26c861fc3399cfc94e6b21ce5cfed1be222beb Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sun, 30 Aug 2026 00:55:01 +1000 Subject: [PATCH 2/2] repospawner: mark the account restricted Defense in depth for the repo-creation bot: a restricted Gitea account can only see repositories and organisations it is explicitly added to, so a leaked repospawner token cannot enumerate or read the rest of the estate. The repospawner team grant on terraform-git already covers everything the bot does, so nothing it needs is lost. --- config/git.unkin.net/user/repospawner.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/git.unkin.net/user/repospawner.yaml b/config/git.unkin.net/user/repospawner.yaml index 8bea574..9cc0c39 100644 --- a/config/git.unkin.net/user/repospawner.yaml +++ b/config/git.unkin.net/user/repospawner.yaml @@ -15,5 +15,8 @@ description: "repospawner service identity -- opens repo-creation PRs against te # profile visible only to signed-in users. visibility: limited admin: false +# Restricted: account can only see repos/orgs it is explicitly added to -- the +# repospawner team grant on terraform-git is all it needs. +restricted: true allow_create_organization: false max_repo_creation: 0