Skip to content

fix(guard): no strategy is issued a system: username; pin the system identities - #163

Merged
braghettos merged 1 commit into
mainfrom
test/pin-system-identities
Nov 14, 2026
Merged

braghettos merged 1 commit into
mainfrom
test/pin-system-identities

Conversation

@braghettos

Copy link
Copy Markdown
Collaborator

Why

acmp asked, for snowplow: can authn ever issue a JWT or client certificate whose groups hold system:authenticated or system:unauthenticated, or whose username is system:anonymous or starts with system:? snowplow adds system:authenticated to a token's groups unless they hold system:unauthenticated or the username is system:anonymous (snowplow#1342). That is safe only if authn never issues those.

From the code:

  • Groups were already guarded for every strategy and issuance path: checkSystemGroups → 403 SystemGroupNotAllowed.
  • A system: username was refused only for identity sources (usernames.Reserved, prefix system). For basic and ServiceAccount identities it was ruled out only by Kubernetes' object-name rules, since a name can't contain :.

What

  • The name guard (nameGuard.admit) and the exchange (VouchForExchange) refuse a system: username for every strategy (name_reserved). This is the explicit form of what the apiserver already rules out, so no valid name changes behaviour.
  • Tests pin the exact identities snowplow depends on:
    • TestNoStrategyIsIssuedASystemIdentity: every strategy, both naming modes, refusing system:authenticated and system:unauthenticated groups and the system:anonymous, system:serviceaccount:… and system:kube-scheduler usernames.
    • TestNoExchangeVouchesForASystemUsername.
    • TestSystemGroupsAreRefused, now naming the two groups.
  • Docs: behavior.md, new section "Kubernetes system identities".

Mutation-checked: removing the guard from either site fails a test.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NSM9VWrDcDtRDRTQoHjgV3

…identities

snowplow evaluates RBAC with a token's groups plus system:authenticated
unless they hold system:unauthenticated or the username is
system:anonymous (snowplow#1342), which is safe only because authn never
issues those. Groups were already guarded for every strategy
(checkSystemGroups); a system: username was refused only for identity
sources (usernames.Reserved), and for basic and ServiceAccount identities
was ruled out only by Kubernetes' object-name rules. The name guard and the
exchange now refuse a system: username for every strategy (name_reserved),
an explicit form of what the apiserver already rules out, so no valid name
changes behaviour.

TestNoStrategyIsIssuedASystemIdentity pins every strategy in both naming
modes against system:authenticated, system:unauthenticated,
system:anonymous and two other system: users; the exchange has its own
test, and TestSystemGroupsAreRefused names the two groups. Mutation-checked:
removing the guard from the name guard or the exchange fails a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NSM9VWrDcDtRDRTQoHjgV3
@braghettos
braghettos merged commit bc76105 into main Nov 14, 2026
18 checks passed
@braghettos
braghettos deleted the test/pin-system-identities branch November 14, 2026 19:33
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.

1 participant