The CI token is an orphan periodic token (period 768h) created with
-no-default-policy -policy=uptime-kuma-vps; nothing renews it. The policy
now grants auth/token/renew-self, and the pipeline gains a renew-openbao-token
step plus a cron trigger matching only the cron named uptime-kuma-token-renew.
The deploy step is restricted to push and deployment events so cron runs only
renew. -o /dev/null drops the JSON body that contains the token; -sSf keeps
errors visible and fails the step on a 403.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
additionalProperties: true makes the API server prune nested objects under
spec.config to {}; x-kubernetes-preserve-unknown-fields (as in upstream
master) keeps the free-form contract. Add ingress: [{}] so the policy
default-denies ingress as named.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AutoKuma 2.0.0 (Kubernetes source) syncs KumaEntity objects to Uptime Kuma
at https://kuma.renner.uno. Ships no KumaEntity objects. Image pinned, not
under Flux automation: Kuma's internal API is unofficial, so Kuma and
AutoKuma are bumped together.
ClusterRole is cluster-wide because the controller lists/watches
KumaEntity across all namespaces. The openbao ClusterSecretStore
namespace allowlist gains autokuma. FILES and DOCKER sources are
disabled; /data and /tmp are emptyDirs for readOnlyRootFilesystem.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The marker next to data/ survived a wiped or replaced DB, so the first up -d
exposed a fresh unclaimed Kuma on /setup. Inside data/ it lives and dies with
the DB; it is still written only after a successful setup run and checked
before the first up -d.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The uptime-kuma play reads its credentials from OpenBao via community.hashi_vault, which needs the python hvac library.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Role, play and pipeline deploy Uptime Kuma 2.5.6 behind the VPS Traefik.
The admin user is bootstrapped over socket.io (needSetup/setup) with the
route disabled, so /setup is never exposed; a .setup-done marker keeps the
route enabled on later runs. Credentials come from OpenBao
homelab/infrastructure/uptime-kuma via community.hashi_vault; the
uptime-kuma-vps policy grants read on that one path. Only kuma.renner.uno
is routed; uptime.renner.uno stays unrouted until its DNS moves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
source-controller v1.9.5 uses go-git v5.19.1, whose documented RedirectPolicy
default is "initial", mirroring git's http.followRedirects: follow the
redirect on the discovery request and use the redirected URL as the base for
follow-up requests. The break-glass stays as a fallback only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Snapshot collaborators, konairius teams and branch-protection whitelists
before the transfer and compare after (Gitea drops collaborators who are
members of the new org).
- Break-glass suspends the flux-system Kustomization so it cannot re-apply the
old URL.
- Task 1 notes the off-cycle mint of both review-bot PATs and checks the
k.renner org holds only the two org secrets.
- Prompts move out of the branch PR into a post-rename PR to main, which
rebuilds the review-bot image (build-ci-images would not fire otherwise).
- Expected side effects of the transfer PR listed; greps widened to the whole
repo; wiki-maintenance cron deleted (no pipeline uses it); GitHub mirror gets
its default branch switched before master is deleted.
- Verified facts recorded: transfer collaborator rule, repair copies the
default branch, repo/cron ids, org secret inventory, repoRenameBranch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chart's KubeJobFailed fires while a failed Job object exists, so it
clears only on Job GC (TTL, history limit, Velero's keep-latest), not on
recovery. On 2026-10-18 this held 10 alerts open for runs that had already
been superseded: renovate recovered 2026-10-13 but alerted until its 7d
TTL; registry-bot-secret-rotate-init2 succeeded 9 min after init failed,
the alert started 7 min after that and stayed 11h.
Replace it with a rule that drops a failed Job once a later Job of the
same series completes: series = owning CronJob, or velero.io/repo-name
for kopia maintenance Jobs (exposed via KSM metricLabelsAllowlist).
Failed Jobs without a series alert as before.
KubeContainerWaiting fired for the never-started main container of a pod
whose init container failed. Exclude Failed/Succeeded pods; KubeJobFailed
covers those.
Verified against live Prometheus: the new expression returns nothing now
(chart rule: 2), returns the 30 Velero maintenance failures at 16:40Z
2026-10-18, and returns nothing at the renovate/registry-bot timestamps
after their successful re-runs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two cut-overs with their own windows, prep PRs and rollbacks, built on the
2026-10-18 inventory (repo references, live Flux/Woodpecker/rotator state,
workstation consumers) and the pattern proven on the five repos moved the same
day.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge right after the repo transfer. Gitea API writes do not survive the
old-path redirect, so the config-sync sidecar (live -> main PR) and review-bot
(posting reviews) must address the new path.
- config-sync GITEA_REPO = konairius/homeassistant (pod restarts, the remote is
reset on start).
- ha-config-sync rotator verifies against konairius/homeassistant.
- review-bot REPOS lists konairius/homeassistant.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sidecar took its git remote, Gitea API base and token from a URL with an
embedded PAT stored on the config PVC. That state was invisible to git,
unrotated, and would break on the repo transfer to konairius: the live -> main
PR is opened with an API POST, and Gitea API writes do not survive the old-path
redirect (seen with the wiki on notes).
- ha-config-sync: dedicated Gitea account, write collaborator on homeassistant.
CronJob openbao/ha-config-sync-secret-rotate (quarterly) mints its
write:repository PAT, verifies pull+push on homeassistant and stores it at
infrastructure/ha-config-sync#token. Policy/role applied and the path seeded
on 2026-10-18. Netpol halves gitea-allow-ha-config-sync-rotator and
rotator-ha-config-sync-egress.
- ExternalSecret home-assistant-config-sync-gitea, mounted as a file (not
subPath) so a rotation lands in place without restarting Home Assistant.
- config-sync.sh: GITEA_URL/GITEA_REPO/GITEA_USER/GITEA_TOKEN_FILE from the
manifest; the remote is reset to the credential-free URL on every start; git
gets the token as an http.extraHeader through GIT_CONFIG_* env, re-read every
loop; the PR call uses the same token.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The repo moved to the konairius org. Its webhooks now carry
konairius/authentik-samba-bridge, which REPOS did not list, so the bot
ignored them, and the sweep would post through the old path, where Gitea
API writes do not survive the redirect (seen with the wiki on notes).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
authentik-samba-bridge moved to the konairius org and publishes as
registry-bot (konairius/authentik-samba-bridge#7, pipeline #42):
gitea.renner.uno/konairius/authentik-samba-bridge-{server,ldap-outpost}
:2026.8.3-9dd92dd. Between the deployed 872f754 and 9dd92dd only CI, OCI
labels and pyproject URLs changed; the bridge code is the same.
- HelmRelease: server image repository + tag 2026.8.3-9dd92dd.
- LDAP outpost blueprint: container_image 2026.8.3-9dd92dd.
- Repo URLs in the comments follow.
Restarts the authentik server and worker pods and redeploys the LDAP outpost.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both repos moved from k.renner to the konairius org on 2026-10-18. The old
paths still resolve through Gitea's redirect (the preset API read of
k.renner/renovate-config returns 200), so nothing is broken; this removes the
dependency on the redirect.
- wiki: Wiki__NoteStore__Gitea__Repository = konairius/notes.
- renovate.json extends local>konairius/renovate-config; the runner comments follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The vsftpd repo moved to the konairius org and its pipeline now publishes as
registry-bot to gitea.renner.uno/konairius/vsftpd (konairius/vsftpd#3,
pipeline #12 pushed build.1792310564, same tags as before). The ImageRepository,
the ftp-scanner image and the renovate ignore list follow. The new path is
anonymously pullable like the old one, so no pull secret is needed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first run of registry-bot-secret-rotate minted the token but failed
verification: "failed verification (pull=false push=true)". The rotator
checks a new token by git-pulling the private konairius/vsftpd, and a
write:package-only token cannot read code even though the publishers team
grants code read: token scopes cap the account's rights. read:repository is
read-only and is what the pull needs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
registry-bot is a dedicated Gitea account in the konairius team "publishers"
(packages write, code read). Every konairius release pipeline publishes its
image to gitea.renner.uno/konairius/* with one shared token instead of a
per-repo k.renner PAT.
- CronJob openbao/registry-bot-secret-rotate (quarterly): secret-rotator
gitea-token mints a write:package PAT, verifies it can pull the private
konairius/vsftpd, stores it at infrastructure/registry-bot#token; then
woodpecker-secret upserts the konairius org secret registry_bot_token with
events push,tag,release,manual (no pull_request).
- OpenBao policy rotator-registry-bot. Already applied with its role, and the
token path seeded with a placeholder, on 2026-10-18.
- Netpol halves: gitea-allow-registry-bot-rotator, woodpecker-allow-rotators,
rotator-registry-bot-egress.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bot posted approvals with event "APPROVE". Gitea knows APPROVED,
REQUEST_CHANGES and COMMENT and stores any other value as a pending review
that only its author sees (routers/api/v1/repo/pull_review.go,
preparePullReviewType, default branch). Every approval since cdba8b62 is such
a pending draft: homelab #1270, #1278, #1287, #1318, homeassistant #385.
The bot also counted its own pending review as "reviewed at this head", so
those PRs were never reviewed again. A pending review no longer counts; the
sweep reviews them again, and Gitea submits the existing pending review with
the new event.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>