From c20e7e466477dd1e9cd3073c7f09ef41806730c6 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 8 Aug 2026 23:41:53 +1000 Subject: [PATCH] Let the agents AppRole mint unkin-agent Gitea tokens (#114) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Why: AI coding agents authenticate to Gitea as Ben using Ben's token. With the unkin-agent identity now in place (terraform-git PR #59), the agents AppRole should issue that account's tokens directly so agent commits and PRs are attributable and carry only least-privilege scopes. How: - add a gitea secrets-engine role minting ephemeral tokens for unkin-agent scoped to write:repository, write:issue, read:user — push branches and open PRs, never merge or administer - add a policy granting read on gitea/creds/unkin-agent, bound to the agents AppRole, mirroring the agent-* Kubernetes creds bindings Depends on terraform-git PR #59: the unkin-agent Gitea account must exist before minted tokens work. The vault-plugin-secrets-gitea engine is already live (plugin v0.1.0 registered, gitea mount configured), so no engine/plugin change is needed here. Reviewed-on: https://git.unkin.net/unkin/terraform-vault/pulls/114 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- .../gitea/unkin-agent.yaml | 20 +++++++++++++++++++ policies/gitea/creds/unkin-agent.yaml | 14 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 config/gitea_secret_backend_role/gitea/unkin-agent.yaml create mode 100644 policies/gitea/creds/unkin-agent.yaml diff --git a/config/gitea_secret_backend_role/gitea/unkin-agent.yaml b/config/gitea_secret_backend_role/gitea/unkin-agent.yaml new file mode 100644 index 0000000..c5a9298 --- /dev/null +++ b/config/gitea_secret_backend_role/gitea/unkin-agent.yaml @@ -0,0 +1,20 @@ +# Role minting ephemeral tokens for the unkin-agent bot user -- the shared +# identity Ben's AI coding agents use to submit work. The agent clones/pushes +# code and opens pull requests, so it gets write on repositories (clone + push + +# PR create) and write on issues (PR/issue comments). Read is implied by write. +# No admin/org/user-write scopes, so it can never merge via API privilege; merge +# is blocked separately by branch protection (merge whitelist = Owners). +# read:user is required because tea (and most API clients) validate the login +# via GET /api/v1/user, which 403s without it. +# Reading gitea/creds/unkin-agent mints a lease-bound token deleted from Gitea +# on revoke/expiry. Consumed by the "agents" AppRole (see +# policies/gitea/creds/unkin-agent.yaml). +--- +username: unkin-agent +scopes: + - write:repository + - write:issue + - read:user +token_name_prefix: vault-unkin-agent +ttl: 3600 # 1h +max_ttl: 14400 # 4h diff --git a/policies/gitea/creds/unkin-agent.yaml b/policies/gitea/creds/unkin-agent.yaml new file mode 100644 index 0000000..9b05039 --- /dev/null +++ b/policies/gitea/creds/unkin-agent.yaml @@ -0,0 +1,14 @@ +# Lets the agents AppRole mint ephemeral Gitea tokens for the unkin-agent bot, +# so AI coding agents authenticate to git.unkin.net as their own least-privilege +# identity instead of Ben's account. Reading gitea/creds/unkin-agent returns a +# lease-bound token scoped by the role (write:repository, write:issue, read:user +# -- never merge/admin). Mirrors the agent-* Kubernetes creds binding pattern. +--- +rules: + - path: "gitea/creds/unkin-agent" + capabilities: + - read + +auth: + approle: + - agents