Retype grant identity fields to PrincipalId (#200) - #245
Conversation
Retype TaskGrant.user, RootAuthority.user, and SelectionToken.user/selected_by from String to the serde-transparent PrincipalId(Ulid) newtype (#199). Clean cutover of every composition, read, and SQL site across schemas, authority, kernel, and gate; production owner/kernel string shapes now resolve to the real owner PrincipalId. Wire format unchanged, so existing sealed grant MACs verify unmodified (D-005). Adds a MAC-preimage + wire byte-preservation test and three compile_fail doctests proving String literals no longer type-check. Closes #200
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 51 minutes Limit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (47)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What & why
Phase 2 of typed owner identity (spec #197). Retypes the grant identity fields
from
Stringto the serde-transparentPrincipalId(Ulid)newtype landed by#199, so owner identity is typed end-to-end and the pre-#200 non-Ulid
usershapes (
"owner","kernel", a stringified i64) become unrepresentable byconstruction.
TaskGrant.user,RootAuthority.user, andSelectionToken.user/selected_byare nowPrincipalId.RootAuthority::from_grantdrops the
Stringclone (PrincipalId isCopy);canonical_bytesisuntouched —
PrincipalIdserializes transparently as the bare Ulid string.openspine-authority,openspine-kernel, andopenspine-gatemigrated.Production grants now carry the real owner
PrincipalId(
state.owner_principal_id), replacing"owner"/"kernel"/owner_user_idstring shapes.
WorkerIdentity.ownerandOperationAuthorization.owner_principal_idremain
String(documented downstream cutover) and convert via.to_string().store::load_owner_miner_audit_slicetakes aPrincipalId; thejson_extract('$.user')predicate still binds text, the app-level recheck isnow a typed equality.
Wire format
Unchanged.
PrincipalIdis#[serde(transparent)]overUlid, so a grant thatsealed a stringified Ulid in
userverifies identically after the retype(D-005). Proven by a new MAC-preimage + serialized-
userbyte test ingrant_chain/tests.rs.Type safety
Three
compile_faildoctests onPrincipalIdassert aStringliteral can nolonger be assigned to
TaskGrant.user,RootAuthority.user, orSelectionToken.user. (Built-in doctests instead oftrybuild: no newdependency / network fetch and no compiler-version-fragile
.stderrgoldens.)Verification
./scripts/check.shgreen (fmt, clippy-D warnings, full workspace testsincl. kernel E2E against the real shell binary, file-size/claims/omp-ceremony
checks, OpenSpec
--all --strict). Kernel suite: 1128 passing.Notes (implementation-notes 5-line summary)
TaskGrant.user,RootAuthority.user,SelectionToken.user/selected_byfrom
Stringto the serde-transparentPrincipalId(Ulid)newtype from Introduce PrincipalId newtype and OwnerPrincipal aggregate #199.kernel, and gate — production owner/kernel/owner_user_id shapes now resolve to
the real owner
PrincipalId; no compatibility shims.PrincipalIdserializes as the bare Ulid string, soexisting sealed grant MACs verify unmodified (D-005).
compile_faildoctests proving
Stringliterals no longer type-check for the identity fields../scripts/check.shgreen; full workspace suite passes.Deviations worth a reviewer's eye
PrincipalId::OWNER/KERNELconstants exist in Introduce PrincipalId newtype and OwnerPrincipal aggregate #199, so kernel-authoredsynthetic grants (
kernel_notify_grant,mint_reconfirm_grant) — which helduser: "kernel"— were threaded the ownerPrincipalId(AD-146 single owner;no code reads
user == "kernel"as a discriminator).issued_byintentionally staysString(out of ticket scope).user: &strlabel mapped through a newdeterministic
test_support::principal(label)(SHA-256 → Ulid) soowner-distinctness security regressions (
regressions.rs,portability.rs)stay meaningful.
Closes #200
Summary by cubic
Retypes grant identity fields from String to a typed
PrincipalId(Ulid)to make owner identity unambiguous and compile‑time safe. PreviouslyTaskGrant.user,RootAuthority.user, andSelectionToken.user/selected_byaccepted free‑form strings (e.g., "owner", "kernel", stringified i64); now they require aPrincipalId. Wire format is unchanged becausePrincipalIdis#[serde(transparent)]over Ulid.openspine-schemas, with clean cutover acrossopenspine-authority,openspine-kernel, andopenspine-gate. Kernel‑authored synthetic grants that used"kernel"now carry the actual ownerPrincipalId.Store::load_owner_miner_audit_slicetakes aPrincipalId; we still bind the JSON extract as text and compare viaPrincipalId::to_string().compile_faildoctests prove rawStringassignments no longer type‑check.Bolded section titles are not used because all content above is essential and minimal for review and rollout.
Written for commit 3fda22b. Summary will update on new commits.