FSD-004 post-fold surface (rc5 authority triad) + registry-core fold build + PortalService GetUser authz - #141
Merged
Conversation
… / verify 16.1 (#76) Pins the substrate to exactly the tags CIRISServer 0.5.217 and its in-tree ciris-lens-core carry, so absorbing registry-core adds no second persist/edge/verify rev to the composed build. No source changes needed across the gap. Each git pin gains a `version = "N"` major guard (the lens-core convention); bin rust-version aligned to the workspace 1.86. Also fixes /v1/identity serving 4-of-6 keys: since CIRISEdge#333 the Reticulum transport refuses `signer: None`, so edge_runtime's identity init had been failing (WARN) since v3.0.0. It now gets the registry's own federation identity via HybridCrypto::build_edge_local_signer. Verified: workspace tests + db_integration green; v3.0.0 -> this build boot upgrade on Postgres 16 applies persist V136-V152 and serves 6/6 identity keys. Rollback floor recorded in CHANGELOG: v3.0.0 will not boot against a DB that has V136+ applied (dual-write on). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
Both RPCs did no authorization: any valid JWT could read any user and all of their org memberships. Now: the user themself, SYSTEM_ADMIN, or a caller with any role in an org the target belongs to (the visibility ListOrgMembers already grants at Viewer). Non-admins get the same PermissionDenied for not-found as for not-allowed, so ids and emails cannot be probed. Denials are audit-logged. Verified over gRPC against Postgres 16: stranger (by id, by email, nonexistent id) denied; self, shared-org Viewer, SYSTEM_ADMIN allowed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
…an depend on
FSD-004 (draft) maps every registry route and RPC to its post-fold path,
substrate call, caller tier (public / signed / org-member / owner /
loopback / blessed infra:* key / accord quorum) and node posture
(client / proxy / unblessed / blessed server), with nine decisions
listed before any new route or capability name ships.
ciris-registry-core gains a `standalone` default feature holding sqlx,
tonic, persist's postgres backend, the gRPC services and the full HTTP
router. Built without default features it carries none of them, and CI
now fails if any returns to that graph. fold::router(engine, key_id)
serves the KEEP routes that already ran on persist alone
(/v1/steward-key, /v1/trust-root/bundle, /v1/agent_files/{kind}); the
standalone router mounts the same handlers. tests/fold_router.rs mounts
it on a SQLite Engine and passes in both builds.
No wire change in the standalone build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
…gation) CC 2.4.1.2.1 (rc5, #100 with the CIRISPersist#814 ruling) makes licensure, grant and delegation three objects with three wire shapes, and only delegation chains. The registry's LicenseType / partner_record path folded all three into one "license". - Rule 4 states the triad and its consequence for the surface. - New caller tier A, licensing authority: the authority_id key or a license-scoped delegate resolving to it; an org names itself by its org UUID (#139). Q stays walled off from A and M (CC 4.2.1). - RegisterPartner splits into recognition (partner_record, steward quorum) and licence issuance (licensure:{authority_id} status rows, eight statuses, suspended reversible / revoked terminal, a set not a scalar). RevokeEntity(license) becomes a status row by the authority. - New GET /v1/licensure/{key_id}?authority= returning the per-authority fold; negative licensure answers are per authority. - §4.5 maps every licence-ish field to its leg and states that there is no community licence to issue: standing is the CC 3.2 T1 self-root, the bond stays off-wire. Portal becomes CIRISClient CSDs, with the missing licensure / grant CSDs named. - Rule-4 obligations on the fold router: emitter-resolves-to-authority fold, status sets, directional exact scope matching, no walks over licences or grants. - Decisions: custodial signing settled as DROP (CC 4.1.1); Portal settled in direction; two new decisions on what rc5 still carries that contradicts this (partner_role community values, partner_record.license_type) and the Verify transition. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
…d_until vs lapsed, tier heading Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Carry the 2026-09-22 ruling (CIRISServer#537): the ciris-canonical community's founders are accord-conferred, human-rooted steward keys; installs join as members and hold standing, never a vote; the admission quorum is the accord's. FSD-004 rule 1 no longer quotes "a vote, never a verdict" (that sentence was never in MISSION §1.5; it came from the server's REGISTRY_FOLD_DERISK.md, which the ruling also re-cuts). A node gains neither. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
This was referenced Sep 26, 2026
Rewrite §2.1 on the 2026-09-22 ruling (CIRISServer#537). The per-install steward keypairs casting a 2-of-3 are withdrawn. Two kinds of key, never fused: steward keys (human, accord-conferred, sign licences and partner_record, confer infra:attest) and install keys (owner-bound, admitted as members of ciris-canonical, serve and replicate, no vote and no verdict). The rotation arc is re-cut with every step human-signed. §1.2 item 4 and §2.1.1 follow; two §6 open questions are answered (consumers pin the GenesisBundle; installs are admitted, not bootstrapped). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Three things, in three commits, all toward folding
ciris-registry-coreinto CIRISServer.1. Security fix (own commit):
PortalService.GetUser/GetUserByEmailhad no authorization. Any valid JWT could read any user record and all of that user's org memberships. Both RPCs now require the caller to be the user, a SYSTEM_ADMIN, or hold a role in an org the target belongs to (the visibilityListOrgMembersalready grants at Viewer). Non-admins get the samePermissionDeniedfor not-found as for not-allowed, so ids and emails cannot be probed. Denials are audit-logged. Verified over gRPC against Postgres 16: stranger by id, by email and for a nonexistent id denied; self, shared-org Viewer and SYSTEM_ADMIN allowed.2. FSD-004, the post-fold registry surface. No document in either repo specified what each registry route and RPC becomes once the slice composes into CIRISServer. FSD-004 maps every one to its post-fold path, substrate call, caller tier and node posture, and lists the decisions needed before any new route ships. It is revised for CC 1.0-rc5's authority triad (CC 2.4.1.2.1: licensure, grant, delegation are three objects, and only delegation chains):
authority_idkey or itslicense-scoped delegate; an org names itself by its org UUID per CC 3.3.9 / licensure authority_id must be the org_id, not PartnerRecord.organization_id (CC 3.3.9 ruling, rc5) #139);RegisterPartnersplit into recognition (partner_record, steward quorum) and licence issuance (licensure:{authority_id}status rows, eight statuses,suspendedreversible andrevokedterminal, a set not a scalar);GET /v1/licensure/{key_id}?authority=returning the per-authority fold, with a stranger's row admitted as testimony only;GenerateKeyPair/RequestSignature) settled as DROP under CC 4.1.1;partner_rolecommunity values,partner_record.license_type).3.
ciris-registry-corebuilds two ways.standalone(default, unchanged deployment) keeps sqlx, tonic, persist'spostgresbackend, the gRPC services and the full HTTP router. Built without default features it carries none of them, which is what CIRISServer can depend on; CI now fails if sqlx, tonic or tokio-postgres returns to that graph.fold::router(engine, node_key_id)serves the KEEP routes that already ran on persist alone (/v1/steward-key,/v1/trust-root/bundle,/v1/agent_files/{kind}); the standalone router mounts the same handlers, so the two cannot drift.tests/fold_router.rsmounts it on a SQLite Engine and passes in both builds. No wire change in the standalone build.Found, not changed:
POST /v1/integrity/authreportsauthorized: truefor anyBearerprefix without validating the token (FSD-004 §7). Its consumers need checking before the fix.Issue
Relates to #62 (fold epic), #133, #139, #41. Fixes the GetUser authorization gap (no issue filed).
AI-assistance disclosure
Checklist
FSD/CEG/**: not touched; FSD-004 adds no wire fieldscargo test --locked --workspace,cargo test -p ciris-registry-core --no-default-features, clippy clean in both builds🤖 Generated with Claude Code
https://claude.ai/code/session_017Hhka84Xw4xHjSfBq1fuw8
Generated by Claude Code