Compare commits

...
Author SHA1 Message Date
hermes-bot a4c1f31557 fix(review-bot): mint the review-bot PAT with read:issue
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
Since 9ec31f07 (PR #1503) review-bot's sweep lists the PRs that request its
review via GET /repos/issues/search?review_requested=true. Gitea requires
read:issue for that endpoint, and the rotator mints the review-bot PAT with
write:repository only, so every 5-minute sweep fails with HTTP 403 and
requested reviews are picked up only by the webhook.

- review-bot-secret-rotate: GITEA_SCOPES = write:repository,read:issue.
- One-shot Job review-bot-rotate-read-issue runs the CronJob's rotate-mint and
  sync-woodpecker steps once, so the new token is minted on merge instead of
  at the next quarterly run (2027-01-01). ESO (refresh 1h) picks it up and
  Reloader restarts review-bot. Remove the Job in a follow-up once it ran.

Closes #1505
2026-10-27 23:25:12 +00:00
3 changed files with 103 additions and 1 deletions
@@ -51,6 +51,8 @@ resources:
- ha-config-sync.yaml
- registry-bot.yaml
- review-bot.yaml
# ONE-SHOT (#1505): mint review-bot's PAT with read:issue. Remove after it ran.
- review-bot-rotate-once-job.yaml
- claude-oauth.yaml
# NOT ROTATED, deliberately — recorded here because the whole point of this
# directory is that unrotated credentials should be a visible choice:
@@ -0,0 +1,99 @@
---
# ONE-SHOT, REMOVE AFTER IT RAN (#1505): the rotate-mint + sync-woodpecker steps
# of review-bot-secret-rotate, so the read:issue PAT is minted now, not next quarter.
# No ttlSecondsAfterFinished: a TTL delete would let Flux re-create it and mint again.
apiVersion: batch/v1
kind: Job
metadata:
name: review-bot-rotate-read-issue
namespace: openbao
labels:
app.kubernetes.io/name: review-bot
app.kubernetes.io/component: secret-rotator
spec:
backoffLimit: 1
activeDeadlineSeconds: 300
template:
metadata:
labels:
app.kubernetes.io/name: review-bot
app.kubernetes.io/component: secret-rotator
spec:
serviceAccountName: review-bot-secret-rotator
restartPolicy: Never
securityContext:
runAsNonRoot: true
runAsUser: 65534
runAsGroup: 65534
seccompProfile:
type: RuntimeDefault
initContainers:
- name: rotate-mint
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-07-30
args: ["gitea-token"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
env:
- name: BAO_ADDR
value: http://openbao.openbao.svc.cluster.local:8200
- name: BAO_ROLE
value: rotator-review-bot
- name: BOOTSTRAP_PATH
value: homelab/infrastructure/secret-rotators-bootstrap/review-bot
- name: BAO_PATH
value: homelab/infrastructure/review-bot
- name: GITEA_URL
value: http://gitea.gitea.svc.cluster.local:3000
# Private repo: the pull check is the real access verification.
- name: GITEA_VERIFY_REPO
value: konairius/shelly-manager
# read:issue: the sweep lists requested reviews via /repos/issues/search.
- name: GITEA_SCOPES
value: write:repository,read:issue
- name: GITEA_REQUIRE_PUSH
value: "false"
- name: GITEA_TOKEN_NAME_PREFIX
value: review-bot-rotated
resources:
requests:
cpu: 25m
memory: 16Mi
limits:
memory: 48Mi
containers:
- name: sync-woodpecker
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-07-30
args: ["woodpecker-secret"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
env:
- name: BAO_ADDR
value: http://openbao.openbao.svc.cluster.local:8200
- name: BAO_ROLE
value: rotator-review-bot
- name: BOOTSTRAP_PATH
value: homelab/infrastructure/secret-rotators-bootstrap/woodpecker-bot
- name: BAO_PATH
value: homelab/infrastructure/review-bot
- name: BAO_FIELD
value: token
- name: WOODPECKER_URL
value: http://woodpecker.woodpecker.svc.cluster.local:8000
- name: WOODPECKER_ORG
value: konairius
- name: WOODPECKER_SECRET_NAME
value: review_bot_token
- name: WOODPECKER_EVENTS
value: cron,manual,pull_request
resources:
requests:
cpu: 25m
memory: 16Mi
limits:
memory: 48Mi
@@ -111,8 +111,9 @@ spec:
# push, or repoint this at another private repo it collaborates on.
- name: GITEA_VERIFY_REPO
value: konairius/shelly-manager
# read:issue: the sweep lists requested reviews via /repos/issues/search.
- name: GITEA_SCOPES
value: write:repository
value: write:repository,read:issue
# review-bot posts reviews via the API (write:repository scope)
# but never git-pushes, and is only a read collaborator, so push
# verification would fail. The private-repo pull check above is