Skip to content

Reader role migration: rename the role in workload-identity rules too, so they keep their grants - #784

Merged
schmitch merged 2 commits into
mainfrom
claude/749-reader-role-wif-rules
Nov 2, 2026
Merged

schmitch merged 2 commits into
mainfrom
claude/749-reader-role-wif-rules

Conversation

@schmitch

@schmitch schmitch commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Fixes #749

What

Migration 0013 (#733, #734) renames a role an administrator had named reader to reader-<id>, then seeds the built-in reader, which reads every repository. The rules of a workload-identity realm name their role (rules[].role), resolved by name on every CI token (crates/server/src/auth/wif.rs). The migration left them alone, so after the upgrade a rule that pointed at the administrator's role would grant the built-in one: every CI job it matches would read every repository.

How

Before the rename, 0013 rewrites each workload_identity realm whose config.rules names reader (trimmed, as the realm's validation trims it):

  • each such rule now names reader-<id>;
  • the other rules and the order stay as they were, and updated_at is bumped;
  • realms of other kinds, and workload-identity realms whose rules name no reader, are untouched.

The realm's policy digest changes with its rules, so keys its jobs exchanged before the upgrade stop working (realm_current_now, wif.rs:846) and the jobs exchange their ID tokens again. Those keys held the renamed role's id, so this only costs an exchange.

0013 is not released yet, so it is changed in place. A database migrated from main since #734 will report 0013 as modified, as for any unreleased migration.

Documented: a rule whose reader role does not exist

A rule can name reader while no role of that name exists, for example after the role was deleted, which no check stops. In 2.1 such a rule refused the jobs it matched, fail-closed. From the upgrade on, it grants the built-in reader. There is no role the migration could point it at, so it stays as it is. Instead:

  • docs/changes/2.2.0/749.upgrade.md says so and asks administrators to check each workload-identity realm's rules under Admin → Authentication before upgrading, and to point such a rule at a role that exists or remove it;
  • the migration's comment says the same.

Tests

  • crates/db/tests/migrations.rs readers_before_the_upgrade_get_the_reader_role now adds two realms:
    • one whose rules name reader twice (once with spaces) around a ci-pub rule: afterwards it names reader-<id> for both, keeps the ci-pub rule and the conditions as they were, and records the change;
    • one whose rules name no reader: it is unchanged.
  • The test passes (5 passed in --test migrations). With the original 0013 it fails:
    left: ["reader", "ci-pub", " reader "]
    right: ["reader-4", "ci-pub", "reader-4"]
    
  • cargo clippy -p forge-db --all-targets -- -D warnings, cargo fmt --check and cargo xtask changelog --check are clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_012e6DJb6V3DHD5wQrsYhKda

Migration 0013 renames an administrator's role named `reader` to
`reader-<id>` before it seeds the built-in `reader`. The rules of a
workload-identity realm name their role, resolved by name on every CI
token, so a rule that named the custom role would grant the built-in
one, read on every repository, after the upgrade. The migration now
rewrites those rules to the renamed role first; the realm's policy
digest changes with it, so its exchanged keys end and its jobs exchange
again.

Fixes #749

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012e6DJb6V3DHD5wQrsYhKda
@schmitch
schmitch enabled auto-merge November 2, 2026 19:31
A workload-identity rule that names `reader` while no role of that name
exists (a deleted one) refused the jobs it matched; after the upgrade it
resolves to the built-in `reader`. There is no role the migration could
point it at, so the upgrade note and the migration's comment say so and
ask administrators to check their rules before upgrading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012e6DJb6V3DHD5wQrsYhKda
@schmitch
schmitch added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 8ced3fe Nov 2, 2026
19 checks passed
@schmitch
schmitch deleted the claude/749-reader-role-wif-rules branch November 2, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade: migration 0013 points workload-identity rules for an administrator's reader role at the built-in reader, which reads every repository

2 participants