Skip to content

docs(spec): operator provisioning plane — Tamarin S9 model + TLA/conformance prose (stacked on #1657)#1664

Open
tlongwell-block wants to merge 2 commits into
mainfrom
eva/operator-plane-model
Open

docs(spec): operator provisioning plane — Tamarin S9 model + TLA/conformance prose (stacked on #1657)#1664
tlongwell-block wants to merge 2 commits into
mainfrom
eva/operator-plane-model

Conversation

@tlongwell-block

Copy link
Copy Markdown
Collaborator

Stacked on #1657 (mini/community-provisioning) — the formal-model and prose follow-through for the operator provisioning plane. Docs-only: no code changes; merge after #1657.

Tamarin: new S9 section (docs/spec/MultiTenantAuth.spthy)

Models POST /operator/communities as a protocol surface: operator-signed NIP-98 requests whose signed preimage includes the payload hash h(<host, owner>), a relay provision rule and a converge/rotate rule both gated on the !OperatorKey allowlist (RELAY_OPERATOR_PUBKEYS), and a UniqueHostBinding restriction importing the append-only host map from ensure_configured_community's ON CONFLICT upsert.

Three new safety lemmas (+3 exists-trace probes, incl. the create-then-converge lifecycle end to end):

Lemma Claim
provisioning_requires_operator_authorization every owner bootstrap/rotation names an operator-registered key — no compromise disjunct, since compromising a secret doesn't extend the allowlist
provision_accepts_only_operator_signed_payload the accepted (host, owner) pair is exactly one the operator signed — a captured Authorization header can only replay (benign convergence), never re-target
rotation_confined_to_host_community rotation lands only in the request host's bound community (S5/S6 single-witness framing)

Verified: full run green, all 38 lemmas (32 existing + 6 new), Tamarin 1.12.0 / Maude 3.5.1, ~141 s.

Three mutations confirmed red (each uncommented in isolation and falsified):

  • MUTATION_Provision_Unsigned_Body — models the review finding that buzz-auth's NIP-98 payload tag is verified only if present; falsifies the payload-binding lemma in an 8-step trace. This makes require-the-payload-tag on this endpoint a conformance obligation, not a review nit.
  • MUTATION_Provision_Any_Client — allowlist replaced by "any valid signature"; falsified, 8 steps.
  • MUTATION_Rotate_Ignore_Host — rotation escaping the named host's community; falsified, 12 steps.

TLA+: stated assumption, no remodel (docs/spec/MultiTenantRelay.tla)

Comment-only header note P-HOST-APPEND: HostCommunity stays a constant-per-segment function because the host map is append-only — provisioning extends the domain, never re-points a binding — so every existing TLC result remains valid across provisioning events. SANY-checked; the .cfg harness is untouched and no TLC re-run is needed.

Prose (docs/multi-tenant-relay.md)

  • S9 added to §Authorization soundness.
  • P-HOST-APPEND conformance row: append-only admission via the upsert, a migration lint (no UPDATE communities SET host), and the two endpoint obligations — payload tag required, allowlist checked against the NIP-98 signer.
  • §Mechanized Verification + verification-status figures updated (32 → 38 lemmas, current run time; noted that older per-lemma step counts predate the model growth).
  • Machine-check-hygiene classification for the new lemmas; fixed two stale .spthy line references.

npub1qvn3cujt28pg06ehlstrxyz6ayzp06t4uc7r566vxwwgrv24hglq9zju0n and others added 2 commits July 8, 2026 14:38
Co-authored-by: npub1qvn3cujt28pg06ehlstrxyz6ayzp06t4uc7r566vxwwgrv24hglq9zju0n <03271c724b51c287eb37fc1633105ae90417e975e63c3a6b4c339c81b155ba3e@sprout-oss.stage.blox.sqprod.co>

Signed-off-by: npub1qvn3cujt28pg06ehlstrxyz6ayzp06t4uc7r566vxwwgrv24hglq9zju0n <03271c724b51c287eb37fc1633105ae90417e975e63c3a6b4c339c81b155ba3e@sprout-oss.stage.blox.sqprod.co>
…rose

Stacked on #1657 (mini/community-provisioning). The operator plane
(POST /operator/communities) is the first runtime surface that can mint
tenancy, so it gets the same mechanized treatment as the rest of the
multi-tenant model:

Tamarin (docs/spec/MultiTenantAuth.spthy, new S9 section):
- Rules: Register_Operator / Compromise_Operator_Key, operator-signed
  provision + rotate requests (NIP-98 preimage includes the payload hash
  h(<host, owner>) — payload binding mandatory), relay provision +
  converge/rotate gated on the !OperatorKey allowlist, and the
  UniqueHostBinding restriction importing the append-only host map.
- Lemmas: provisioning_requires_operator_authorization (allowlist gate,
  no compromise disjunct — compromise doesn't extend the allowlist),
  provision_accepts_only_operator_signed_payload (payload binding),
  rotation_confined_to_host_community (S5/S6-style single witness), plus
  three exists-trace probes incl. the create-then-converge lifecycle.
- Full run: all 38 lemmas verified green (Tamarin 1.12.0 / Maude 3.5.1,
  ~141 s). Three commented mutations confirmed red:
  MUTATION_Provision_Unsigned_Body (the optional-payload-tag gap from the
  #1657 review; 8-step trace), MUTATION_Provision_Any_Client (8 steps),
  MUTATION_Rotate_Ignore_Host (12 steps).

TLA+ (docs/spec/MultiTenantRelay.tla, comment-only): stated assumption
P-HOST-APPEND — HostCommunity stays a constant-per-segment function
because the host map is append-only (ensure_configured_community's
ON CONFLICT upsert never re-points a bound host), so runtime
provisioning needs no TLC remodeling. SANY-checked.

Prose (docs/multi-tenant-relay.md): S9 section under Authorization
soundness, verification-status update (32 -> 38 lemmas, current run
figures), P-HOST-APPEND conformance row (incl. the require-payload-tag
and signer-checked-allowlist obligations), Mechanized Verification
bullet, machine-check-hygiene classification for the new lemmas, and a
stale spthy line-reference fix (:403/:413 -> :427/:437).

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Base automatically changed from mini/community-provisioning to main July 8, 2026 23:56
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