# Forgejo Admin API Token (PAT) Date: 2026-07-12 (verified 2026-07-13; file-drop retired 2026-07-18, WARDEN-WP-0029 T04) Catalog: `forgejo-admin-api-token` (status `active`, `resolvable: true`) Owner: `railiance-platform` (CCR-2026-0006) Forgejo site-admin personal access token for operator and automation tooling. Sibling to `forgejo-mailer` (SMTP via ESO); phase 1 is workstation + activity-core worker fetch only — no cluster ExternalSecret delivery. **Ask first:** `warden plan "forgejo admin api token" --json` — agents must not draft founder credential steps without a plan verdict. --- ## OpenBao pointers | Field | Value | | --- | --- | | Mount | `platform` | | Path | `platform/workloads/forgejo/forgejo-admin` | | Secret field | `API_TOKEN` (PAT value) | | Metadata fields | `API_USER`, `API_BASE_URL`, `TOKEN_SCOPES`, `GENERATED_AT` (optional, non-secret) | | Policy | `workload-kv-read-forgejo-admin` | | OIDC role | `forgejo-admin-workload-kv-read` (`groups=net-kingdom-admins`) | **PAT scopes (minimum for current consumers):** `read:package`, `write:package`, `read:repository`, `write:repository`, plus admin scopes as needed for `forgejo-operator-bootstrap` (mirror the current admin PAT). **Forgejo account:** `tegwick` (site admin, `coulomb` Owners). --- ## Worker checklist 1. **Plan** (agents — always): ```bash warden plan "forgejo admin api token" --json # expect verdict=autonomous, lane=forgejo-admin-api-token ``` 2. **Login** if needed (caller identity — ops-warden adds no credential): ```bash warden plan "oidc login forgejo admin" --json # or: bao login -method=oidc -path=netkingdom role=forgejo-admin-workload-kv-read ``` 3. **Use the token via sanctioned transports** (never file-drop steady state): ```bash # Preferred: inject into child only warden access forgejo-admin-api-token --exec --field API_TOKEN -- \ env | grep -c FORGEJO # example; real consumers use the env name they need # Or write mode-0600 for a single tool invocation (you own deletion) warden access forgejo-admin-api-token --out "$XDG_RUNTIME_DIR/forgejo-admin.token" --field API_TOKEN # Or wrapping token (unwrap in your own context) warden access forgejo-admin-api-token --wrap ``` High-risk lane: with `WARDEN_AGENT_ID` set, raw stdout fetch is refused — use `--out` / `--exec` / `--wrap` only. 4. **Run consumers** (railiance-platform / railiance-apps — keep env out of chat): ```bash # Package prune (railiance-platform) — prefer credential exec / warden access --exec make forgejo-package-prune-dry-run make forgejo-package-prune # Operator bootstrap / npm smoke / reuse webhook (railiance-apps) make forgejo-operator-bootstrap make forgejo-npm-smoke make reuse-forgejo-webhook ``` **Retired steady-state paths (do not use):** - `/tmp/forgejo-tegwick-api-token` — legacy file drop - Pasting the PAT into chat, workplans, or shell history `FORGEJO_ADMIN_TOKEN` in the process environment is acceptable only as a short-lived injection via `--exec` (or equivalent owner-native exec), not as a durable workstation file. --- ## Operator provisioning (attended founder act) After CCR approval and policy apply — **one founder act**, not agent file drops: 1. Forgejo UI: `tegwick` → Settings → Applications → Generate New Token 2. Store via desk paste-once (preferred) or platform helper: ```bash # Preferred: plan + desk (value never in shell history) warden plan "provision forgejo admin api token" --json > /tmp/plan-forgejo.json warden desk --plan-json /tmp/plan-forgejo.json \ --path platform/workloads/forgejo/forgejo-admin --field API_TOKEN # shred plan file (metadata only, but still): shred -u /tmp/plan-forgejo.json # Alternative: platform provision script (stdin/file owned by operator) ~/railiance-platform/scripts/forgejo-admin-pat-provision.sh ``` 3. Verify field presence without printing values: ```bash bao kv metadata get platform/workloads/forgejo/forgejo-admin ``` --- ## Verify the lane (capabilities-safe — never read the value) Prove allow/deny with `bao token capabilities`, **not** `bao kv get -field=…`. `bao kv metadata get` (above) is fine — it shows versions, not values. Reading the data field to "confirm" it is the anti-pattern (`wiki/playbooks/catalog-lane-promotion.md#capabilities-safe-lane-verification`). ```bash # Positive: lane OIDC identity can read the data path bao login -method=oidc -path=netkingdom role=forgejo-admin-workload-kv-read bao token capabilities "$(bao print token)" platform/data/workloads/forgejo/forgejo-admin # → expect: read # Negative: default-only identity is denied DEFAULT_TOKEN=$(bao token create -policy=default -field=token) # if denied, that IS the pass — do NOT fall back bao token capabilities "$DEFAULT_TOKEN" platform/data/workloads/forgejo/forgejo-admin # → expect: deny ``` Confirming the PAT works against Forgejo is a separate, value-using action — use `warden access … --exec` and call `/api/v1/user`; never paste the token. --- ## Consumers (downstream wiring — after lane verified) | Consumer | Repo | Notes | | --- | --- | --- | | `tools/cmd/forgejo-package-prune` | `railiance-platform` | Prefer OpenBao / `warden access --exec`; no `/tmp` token file | | `weekly-forgejo-package-prune` activity | `activity-core` | | | `forgejo-operator-bootstrap`, `forgejo-npm-smoke`, `reuse-forgejo-webhook` | `railiance-apps` | | | binky-control cutover | `binky-control` | Use `warden plan` for deploy-key / admin needs; no founder file drops | Docs: `railiance-platform/docs/forgejo-package-prune.md`, `railiance-apps/docs/forgejo-on-railiance01.md`. **Cross-repo follow-up (WP-0029 T04):** update consumer docs that still mention `/tmp/forgejo-tegwick-api-token` to `warden access` / credential exec. --- ## See also - `railiance-platform/credential-change-requests/CCR-2026-0006-forgejo-admin-api-token-lane.yaml` - `railiance-platform/openbao/policies/workload-kv-read-forgejo-admin.hcl` - `wiki/playbooks/railiance-backup-offsite-lane.md` (OIDC workstation read pattern) - `forgejo-mailer` lane — SMTP only; unchanged - WARDEN-WP-0029 — `warden plan` / `warden desk`