fix(renovate): document and probe the five token scopes Renovate needs; lint daemon-bound actions #85

Merged
jakman85 merged 1 commits from fix/renovate-auth into main 2026-10-30 07:10:02 +00:00
Owner

Root cause (run 350)

The token fix worked: platform init now passes. Renovate then stopped at the next missing scope. Gitea's router log, filtered to the act-runner pod 10.0.0.38:

06:49:31 GET /api/v1/user                                      200 OK
06:49:31 GET /api/v1/version                                   200 OK
06:49:31 GET /api/v1/repos/Home-Network/home-network-k3s-impl  200 OK
06:49:31 GET /api/v1/orgs/Home-Network                         403 Forbidden

From the job log:

ERROR: Repository has unknown error
  "url": "https://gitea.home.keithjackson.dev/api/v1/orgs/Home-Network",
  "message": "token does not have at least one of required scope(s), required=[read:organization], token scope=read:package,write:repository,read:user"
  • This is Gitea, not Cilium. The body is Gitea's JSON, Gitea logged the request, and x-envoy-upstream-service-time shows Envoy forwarded it.
  • The secret was updated. /user went from 403 to 200, and the scope list now includes read:user.
  • Why read:organization. Renovate's initRepo → isOrg → GET /orgs/{owner} requires it.
  • Why write:issue is the next wall. Gitea 1.24.3 files /issues, /labels and /milestones under the issue scope, which the dependency dashboard and PR labels need.
  • The cause of the loop. The workflow header listed only three scopes, and the operator minted exactly those.

Operator fix (required, the main fix)

Re-mint RENOVATE_TOKEN for renovate-bot with user: Read, organization: Read, repository: Read and Write, issue: Read and Write, package: Read. Overwrite the Actions secret and revoke the old token.

Git changes

  • renovate.yaml:
    • The scope list is corrected in the header and the preflight text, with the call each scope serves.
    • A new preflight step probes the scopes with GETs, the token passed to curl on stdin and never in argv. It names a missing scope instead of Renovate's bare Authentication failure, and tells a 401 (value) from a Gitea 403 (scope) from an Envoy Access denied (Cilium).
  • ci/lint.sh: new guard. It rejects workflow uses: lines that need a Docker daemon (docker://, renovatebot/github-action, docker/*-action), the class fixed in #84. It flags the pre-#84 workflow, passes the current tree and ignores comments.
  • Handoff: decisions/2026-10-30-renovate-auth.md.

Gate

The local toolbox gate returned rc 3 (UNDETERMINED, not green). gitea-settings is the only stage that did not run. .gitea/** and ci/** are sensitive paths, so approval-policy will fail in CI until the operator posts /approve-override <reason> as a PR review. No agent posted it.

The probe was tested only with a bogus token, which gives the 401 path, plus a scope-list parser test against run 350's real message. The re-minted token does not depend on this PR: it can be dispatched against main right away.

🤖 Generated with Claude Code

## Root cause (run 350) The token fix worked: platform init now passes. Renovate then stopped at the **next** missing scope. Gitea's router log, filtered to the act-runner pod `10.0.0.38`: ``` 06:49:31 GET /api/v1/user 200 OK 06:49:31 GET /api/v1/version 200 OK 06:49:31 GET /api/v1/repos/Home-Network/home-network-k3s-impl 200 OK 06:49:31 GET /api/v1/orgs/Home-Network 403 Forbidden ``` From the job log: ``` ERROR: Repository has unknown error "url": "https://gitea.home.keithjackson.dev/api/v1/orgs/Home-Network", "message": "token does not have at least one of required scope(s), required=[read:organization], token scope=read:package,write:repository,read:user" ``` - **This is Gitea, not Cilium.** The body is Gitea's JSON, Gitea logged the request, and `x-envoy-upstream-service-time` shows Envoy forwarded it. - **The secret was updated.** `/user` went from 403 to 200, and the scope list now includes `read:user`. - **Why `read:organization`.** Renovate's `initRepo` → `isOrg` → `GET /orgs/{owner}` requires it. - **Why `write:issue` is the next wall.** Gitea 1.24.3 files `/issues`, `/labels` and `/milestones` under the **issue** scope, which the dependency dashboard and PR labels need. - **The cause of the loop.** The workflow header listed only three scopes, and the operator minted exactly those. ## Operator fix (required, the main fix) Re-mint `RENOVATE_TOKEN` for `renovate-bot` with **user: Read, organization: Read, repository: Read and Write, issue: Read and Write, package: Read**. Overwrite the Actions secret and revoke the old token. ## Git changes - `renovate.yaml`: - The scope list is corrected in the header and the preflight text, with the call each scope serves. - A **new preflight step probes the scopes** with GETs, the token passed to curl on stdin and never in argv. It names a missing scope instead of Renovate's bare `Authentication failure`, and tells a 401 (value) from a Gitea 403 (scope) from an Envoy `Access denied` (Cilium). - `ci/lint.sh`: new guard. It rejects workflow `uses:` lines that need a Docker daemon (`docker://`, `renovatebot/github-action`, `docker/*-action`), the class fixed in #84. It flags the pre-#84 workflow, passes the current tree and ignores comments. - Handoff: `decisions/2026-10-30-renovate-auth.md`. ## Gate The local toolbox gate returned **rc 3** (UNDETERMINED, not green). `gitea-settings` is the only stage that did not run. `.gitea/**` and `ci/**` are sensitive paths, so **`approval-policy` will fail in CI** until the operator posts `/approve-override <reason>` as a PR **review**. No agent posted it. The probe was tested only with a bogus token, which gives the 401 path, plus a scope-list parser test against run 350's real message. The re-minted token does not depend on this PR: it can be dispatched against `main` right away. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
gitea-admin added 1 commit 2026-10-30 06:58:57 +00:00
fix(renovate): document and probe the five token scopes Renovate needs; lint daemon-bound actions
gate / gate (pull_request) Successful in 2m54s
gate / conformance (pull_request) Has been skipped
0c6ee4921d
Run 350 cleared platform init (/user 200, /version 200, /repos 200), then stopped at
GET /api/v1/orgs/Home-Network with Gitea's own 403:
  token does not have at least one of required scope(s), required=[read:organization],
  token scope=read:package,write:repository,read:user
The workflow's header listed only those three scopes, and the operator minted exactly that.
Renovate's initRepo -> isOrg needs read:organization, and Gitea files /issues and /labels under
the issue scope, which the dashboard and PR labels need: write:issue.

- renovate.yaml: corrects the scope list (read:user, read:organization, write:repository,
  write:issue, read:package), with the call each serves. A new preflight step probes them with
  GETs, the token passed to curl on stdin, and names a missing scope instead of Renovate's bare
  "Authentication failure".
- ci/lint.sh: rejects workflow `uses:` lines that need a Docker daemon (docker://,
  renovatebot/github-action, docker/*-action), the class fixed in #84.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
jakman85 approved these changes 2026-10-30 07:04:14 +00:00
jakman85 merged commit 593d0fad15 into main 2026-10-30 07:10:02 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Home-Network/home-network-k3s-impl#85