Skip to content

feat(cp): IdentityMismatch reconcile check (ADR #19 slice 3) - #23

Merged
brettchien merged 1 commit into
mainfrom
feat/identity-mismatch-slice3
Aug 13, 2026
Merged

feat(cp): IdentityMismatch reconcile check (ADR #19 slice 3)#23
brettchien merged 1 commit into
mainfrom
feat/identity-mismatch-slice3

Conversation

@brettchien

Copy link
Copy Markdown
Contributor

Drafted by Orca (ecs-claude) — flagging authorship (shared GitHub identity). Supersedes #22 (auto-closed when the stacked base branch was deleted on the slice-2 merge); same content, now based on main.

Third slice of ADR #19 — the reconcile step that closes the declare → switch → observe → reconcile loop. Follows #20 (slice-1) and #21 (slice-2, merged).

What:

  • studio-cpprincipal_matches(expected, actual): the read-only IdentityMismatch check. A warning signal, never an authz gate (ADR-2 authz stays deferred). Handles the STS assumed-role vs IAM role shape (expected …:role/R matches actual …:assumed-role/R/SESSION) and a trailing * wildcard. A static user/… never satisfies a role expectation — exactly the fallback we want flagged. Unit-tested, including the incident case (role expected, user/brett.chien resolved → mismatch) and wrong-account.
  • oab-mcpruntime_context now reports expected_principal and identity_matches (null when the binding declares no expectation).

Effect: with a binding's expected_principal set, runtime_context flags on sight when the resolved identity isn't the intended one — today's deploy_list incident would have tripped it (identity_matches: false).

Scope: reconcile is observe-only. Assume-role credential form is the next slice (its AssumeRoleProvider API is version-sensitive; landing it isolated).

Verification: CI on this PR; new unit test covers the matcher. (The prior stacked build already compiled slice-1+2+3 green.)

Relates to #19, follows #21.

🤖 Generated with Claude Code

Closes the declare→switch→observe→reconcile loop: compare the resolved caller
principal against the binding's expected_principal.

- studio-cp: `principal_matches(expected, actual)` — a read-only warning signal
  (never an authz gate). Handles STS assumed-role vs IAM role shape and a
  trailing `*` wildcard; a static `user/...` never satisfies a role expectation
  (exactly the fallback we want flagged). Unit-tested incl. the incident case.
- oab-mcp: `runtime_context` now reports `expected_principal` and
  `identity_matches` (null when no expectation is declared).

Stacks on the slice-2 FleetBinding switch. Assume-role credential form is the
next slice (its provider API is version-sensitive; landing it isolated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@brettchien
brettchien marked this pull request as ready for review August 13, 2026 05:38
@brettchien
brettchien merged commit 47302ea into main Aug 13, 2026
3 checks passed
@brettchien
brettchien deleted the feat/identity-mismatch-slice3 branch August 13, 2026 05:38
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