[FEAT] Server federation: capability tokens, the pull gate on sync and blob, and the lifecycle around them - #472
Open
justin13888 wants to merge 2 commits into
Conversation
…e module context Land `capsule-server::federation` (S-E2, S-E5, S-C49): the EdDSA-JWT capability a peer presents on the existing sync and blob reads, the codec that mints and reads it under the same Ed25519 key session tokens are signed with, and the two ports behind it. `CapabilityStore` records every capability this server issued and implements `RevocationList`: the store is the list `/.well-known/capsule/revoked-jti` serves, so "is this jti revoked" has one answer. `PeerStore` holds the peers an operator has pinned and the server-level blocklist as a column on the same row. Both have in-memory adapters and one conformance suite, which now also carries the four cases the retired `discovery::revocation::InMemoryRevocations` had. The claim set is design/federation.md's table verbatim, with RFC 3339 instants checked against the injected clock, the 24 h ceiling enforced at mint and at verify, and every instant at whole seconds so a stored grant re-signs byte-for-byte for an idempotent refresh. A session token is unreadable to the capability codec and a capability to the session verifier, by construction. `FederationContext` joins `App`/`Modules`, `boot` and the test fixture; `boot` builds the codec from the same DER as the session signer and asserts the published key is the one capabilities verify under. `FEDERATION_URL` opts a deployment in and is published as `server-info.federation_url`. Four `error.federation.*` catalog keys are added for the lifecycle routes that follow, and `capsule-server::federation` leaves `planned-modules.txt`.
…server-federation-406
Deploying capsule with
|
| Latest commit: |
0b7fe30
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://21b0ee6a.capsule-22k.pages.dev |
| Branch Preview URL: | https://feat-server-federation-406.capsule-22k.pages.dev |
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.
Description
capsule-server::federation(slicesS-E2,S-E5,S-C49): the capability token a peer server presents on the existingGET /v1/sync?album_id=andGET /v1/blob/{hash}reads, the store it is issued from and revoked into (which is now the revocation list/.well-known/capsule/revoked-jtiserves), the peers this server pins and blocks, and the lifecycle around it. Stacked on #458 (feat/server-album-membership-405); the PR targets that branch.Status: in progress. Delivered in ordered commits, each leaving the tree coherent; this body is updated as slices land. No human has approved the plan below — it was executed under the run's unattended declaration and is published here for review.
Related Issues
Refs #406
Contributor Checklist
Summary
Landed so far:
federation/{mod,capability,store,peers,memory,conformance}.rs. EdDSA-JWT capability with the design's claim set verbatim (RFC 3339 instants, 24 h ceiling, whole-second instants so a stored grant re-signs byte-for-byte for idempotent refresh), signed by the same Ed25519 key as session tokens;CapabilityStore(implementsRevocationList— the store is the list) andPeerStore(pinned keys, blocklist column) with in-memory adapters and one conformance suite;FederationContextwired intoApp/Modules/boot/the fixture;Config.federation_url(FEDERATION_URL) published onserver-info;InMemoryRevocationsretired (its cases moved into the conformance suite); fourerror.federation.*keys added;capsule-server::federationremoved fromplanned-modules.txt.Validation
See the per-commit list below; every gate is recorded with its exact command and observed outcome. Failures are classified
caused/pre-existing/flaky/unavailable/unclassified.cargo nextest run -p capsule-server -E 'test(federation) | test(discovery) | binary(well_known) | binary(conformance) | test(boot::) | test(config::)'— 82 passed (commit 1)cargo clippy -p capsule-server -- $CLIPPY_FLAGS— clean (commit 1)cargo fmt --check -p capsule-server— clean (commit 1)cargo run -q -p capsule-server -- gen-openapi --check— document up to date (commit 1; no route change yet)mise run i18n-check,mise run i18n-guard— clean (commit 1)mise run check-docs-truth— 476 links, 101 citations, 119 paths all resolve (commit 1)mise run check-rust,mise run test-rust, container-gatedpostgres_conformancesuite — to run at the end of the series; not yet observed.Risks and rollout
discovery::revocation::InMemoryRevocationsis gone;bootand the test fixture hand oneInMemoryCapabilitiesto both discovery and federation. The published list's behaviour (prune on read, order by expiry, refuse past the ceiling, idempotent revoke) is pinned byfederation::conformance.FEDERATION_URLunset (the default) changes nothing observable: nofederation_urlonserver-info, and the lifecycle writes refuse403 error.federation.not_configuredonce they land.Decisions taken
The plan's record, verbatim, followed by the decisions this run took while delivering it.
Unresolved review notes
nbfis honoured with zero leeway on the issuer's own clock; the verifier in v1 is always the issuer, so the skew tolerance the table givesnbfis nil here. Recorded, not changed.