## What Comprehensive NIP-FI against `main`: one normative core plus four separately claimable profiles, replacing the single-document structure of #3726 (which was based on #1485's branch, not `main`). Six documents, 1,975 lines, docs only. - **`NIP-FI.md` (core, 632 lines)** — issuer-qualified identity `(iss, sub)`, independent Nostr proof, client-attached assertion, partial bijection with durable tombstones, atomic final admission, bounded leases, private denials with a closed response vocabulary, retire/revoke/rotate, two contract identities (`assertion_policy_id`, `transport_contract_id`), per-policy `skew` / `maximum_assertion_age` / `maximum_status_age` with missing configuration denying, a closed token-class rule (`at+jwt`, `nip-fi+jwt`, named compatibility; ID tokens always deny), declared freshness class (`offline-jwt` | `current-status`), server-declared body authorization relevance (NIP-98 payload-binding fix, including a `payload` tag on an irrelevant-body operation), BCP 14, "equivalent" defined over identity / bounds / provenance classes, a compact non-normative worked wire example, and a non-normative comparison with DPoP, mTLS-bound tokens, and HTTP Message Signatures. FI-INV-01..16 are normative core text. The behavioral-oracle table lists exactly 30 oracle IDs, one per row, with no shorthand. - **`NIP-FI-EDGE.md`** — trusted-edge surface: the `trusted-proxy-hmac-v2` envelope + canonicalization, or a private authenticated-edge adapter under a reviewed contract; `authorization_domain_id` derivation (exact 16 RFC 9562 UUID bytes); `proof_transport_code` registry (0x01 NIP-42, 0x02 NIP-98; 0x03 Git smart-HTTP and 0x04 Blossom reserved pending their transport contracts; 0x05–0x7f unassigned pending published stable specifications) + extension procedure; body-acquisition bounds; three normative test vectors. An independent Nostr proof (the NIP-98 event in `Authorization`, which reaches the verifier byte-identical, or the NIP-42 event after connect) is the only decision input outside the MAC; absent or incomplete provenance on an edge-required route is `missing_evidence`, present-but-failing provenance is `evidence_rejected`. Header-trust-without-provenance is nonconformant. - **`NIP-FI-LIFECYCLE.md`** — provision / disable / re-enable / administrative expiry (`binding_not_after`) / pending-replacement lineage, one conformance trace per privileged transition; every binding-creating transition declares whether it continues or establishes a grant; a private-condition table for CONF enumeration agreement. - **`NIP-FI-DELEG.md`** — delegated agents; explicit temporal boundaries matching core's inclusive-`nbf`/exclusive-`exp` idiom, with the delegated `skew` configured by this profile; lease deadline anchored to the lease issue instant; strict path separation — a delegated request carries no assertion or provenance field, so it cannot traverse an edge-provenance route and uses ingress on which NIP-FI-EDGE is not required. - **`NIP-FI-CONF.md`** — conformance evidence: an immutable claim tuple including the governing document revision and exit fixture digest; the complete 16-row denial-fixture enumeration with three mechanical enumeration-agreement checks; mutation adequacy with a countable denominator — one retained killed mutant per literal oracle-table row (30 core + 6 EDGE + 11 LIFECYCLE + 7 DELEG + 4 CONF = 58), rows selected structurally by their first cell, never by section title, with the release gate and CONF's own oracle rows stated in the same listed-oracle terms and a mutant defined for CONF's own report- and suite-subject oracles; an interoperability exit test compared over signing inputs (per-transport NIP-01 serialization for the NIP-98 and NIP-42 proofs; decoded protected header and claims as JSON values for the assertion), with a shared exit fixture pinning complete pre-signature header/claim JSON and complete unsigned event fields for both transports, and mandatory negative controls. `FI-CONF-INTEROP-EXIT` is `deferred` with reason `no-independent-implementation` until a second independent implementation exists; the canonical fixture is editor-authored at `docs/nips/fixtures/nip-fi-conf-exit.json` and is **not in this PR** — until it is published a claim records `pending-canonical-fixture`, valid only while the exit test is deferred. Explicit not-applicable dispositions, including `offline-jwt` deployments for the two current-status oracles and absence of a revocation-bounded external capability projection for `FI-TRACE-CAPABILITY-REVOCATION`. - **`NIP-FI-MODEL.md`** — non-normative companion; defines no requirement or conformance claim and is not claimable. ## Why The prior draft rated 9 (soundness) / 6 (minimalness) / 7 (elegance) / 7 (correctness) in adversarial + comparative review. This restructure keeps the two-invariant spine untouched, makes everything else a claimable profile, and collapses five stacked versioning mechanisms into two contract identities. Mutation adequacy counts one mutant per literal oracle-table row — a set two implementers enumerate identically — instead of "each normative requirement," which had four defensible readings. Resolved product calls (owner-approved): 1. Enrollment/denial posture is private — boolean enrollment discovery, TOFU extension claim not self-advertised, `key_mismatch → authorization_denied` joins the denial anonymity set, and replayed evidence is classed `authorization_denied` so resubmission reveals nothing about commit. 2. Revocation honesty — only `current-status` deployments may advertise an unconditional residual-revocation bound; `offline-jwt` advertises unbounded/unknown. Access tokens keep RFC 9068 `at+jwt`; `nip-fi+jwt` is reserved for a separately minted Buzz assertion. ## Acceptance bar - Nothing in core is deletable without losing a stated core guarantee. - From the core document plus the CONF exit fixture, a second implementer can produce a valid request equal over the request compared object (signing inputs), and a byte-exact public denial per class — no reference implementation. - Every oracle-table row ships a retained killed mutant satisfying only the entry it was selected for. - Both deployment profiles (trusted proxy = EDGE, client-held OIDC = core client-attached) pass the same lifecycle conformance suite. ## Status Ready at heade720a5cda. Every revision below is on this branch: the 2026-08-17 and 2026-08-18 review laps (Wren, Dawn, Perci, Sami, Mari, Quinn) closed at513e03b06,17d455a9b, and 4f913a813; the 2026-08-20 external line-by-line review (R1–R10, R12) closed across 56e74141e..772ba7a72; the 2026-08-20/21 adversarial lap (#6437) squash-merged as b8db13d88; the round-3 external review (R13, R14), the DELEG×EDGE composition note, and three terminology nits closed at e720a5cda; R11 is this description. Oracle census: 58 (30 core, 6 EDGE, 11 LIFECYCLE, 7 DELEG, 4 CONF). Known follow-ups, filed after merge and out of scope here: adapter-only edge deployments and FI-EDGE claimability; an EDGE private-condition table for CONF's enumeration-agreement check; an enumerable definition of the positive/negative oracle sets used by the global mutation controls; NIP-OA's clock-free verification versus NIP-FI-DELEG's wall-clock expiry. Supersedes #3726 as the spec vehicle; #1485 remains the design-history anchor. --------- Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Signed-off-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz> Signed-off-by: Perci <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz> Signed-off-by: Wren <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@buzz.block.builderlab.xyz> Signed-off-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@buzz.block.builderlab.xyz> Signed-off-by: Tyler Longwell <tlongwell@squareup.com> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Co-authored-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz> Co-authored-by: Perci <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz> Co-authored-by: Wren <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@buzz.block.builderlab.xyz> Co-authored-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@buzz.block.builderlab.xyz> Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
8.4 KiB
NIP-FI-DELEG
Delegated agent authorization profile
draft optional relay
Protocol dependency: NIP-FI core.
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", and "MAY" in this document are to be interpreted as described in BCP 14 (RFC 2119 and RFC 8174) when, and only when, they appear in all capitals.
Scope
This profile authorizes a delegate key from separately validated delegation
evidence rooted in a currently eligible NIP-FI owner binding. The delegate
proves its own key. It does not present a federated assertion and never receives
or inherits the owner's binding. Because a trusted edge inserts assertion and
provenance fields on every request it forwards, and FI-DELEG-PATH-SEPARATION
denies any such field on a delegated request, delegated requests cannot traverse
a route that requires edge provenance; they use ingress on which NIP-FI-EDGE is
not required.
This profile defines the normalized delegation result and its additional preparation, final-admission, and lease witnesses. It does not define a wire format for creating delegation relationships; NIP-OA or another protocol may supply the evidence if it satisfies this contract.
Delegation evidence
A validator returns this closed result:
DelegationEvidence = (
domain,
owner_key,
delegate_key,
relationship_id,
relationship_revision,
audience,
operations,
conditions,
resource_or_target,
not_before?,
mandatory_expiry
)
relationship_id and relationship_revision are deployment-local dependency
identifiers. All other fields are interoperability-critical in meaning even
when their concrete encoding belongs to the supplying delegation protocol.
The evidence authenticates every field, has one unambiguous owner and delegate,
matches the server-owned domain and exact request or target, and has a finite
expiry satisfying now < mandatory_expiry; equality at an expiry is expired.
Optional not_before satisfies not_before <= now + skew, using the
configured delegated skew; arithmetic is overflow-safe. A missing
configured skew denies. The proven actor equals delegate_key.
[FI-DELEG-EVIDENCE-CLOSED]
A delegated request carries fresh request-appropriate Nostr proof and no
Nostr-Federated-Identity or profile provenance field. Mixed direct and
delegated evidence denies rather than selecting a path. [FI-DELEG-PATH-SEPARATION]
Private denial conditions
This profile defines exactly this private condition identifier and owning public class for NIP-FI-CONF enumeration agreement:
| Private condition identifier | Public class |
|---|---|
delegation_not_current |
authorization_denied |
The identifier is a fixture name, not a wire value. Adding, removing, renaming, or reclassifying it requires the same change in NIP-FI-CONF's denial-fixture table.
Preparation
Preparation resolves the exact server-owned domain, target context, operation, resource, and proven delegate actor before validating delegation evidence. It then atomically reads:
- the active owner binding and exact binding version;
- every owner tombstone, key-revocation, administrative, and profile lifecycle gate applicable to that binding;
- the exact relationship identifier and revision;
- current local policy and resource versions; and
- every invalidation dependency and deadline.
The owner binding is current and authorization-eligible at preparation. A cached owner lease is not authority. The requested capability is the intersection of the delegation's operation, audience, conditions, and target with current local policy; an unsupported operation or empty intersection denies. [FI-DELEG-OWNER-CURRENT]
Preparation remains read-only under FI-INV-08. It cannot create or change an
owner or delegate binding, identity, provenance, lifecycle fact, relationship,
last-seen value, replay claim, receipt, lease, or application effect.
[FI-DELEG-NO-BINDING]
Final admission
Core final admission additionally requires:
- the exact delegation evidence and delegate proof remain live;
- domain, actor, target, audience, operation, resource, and relationship match the prepared value;
- the exact current owner binding and binding version remain eligible;
- relationship identity and revision remain current;
- current capability intersection equals the prepared intersection; and
- changed dependencies are reread and the complete delegated decision is recomputed before atomic commit.
Any mismatch, expiry, owner retirement, owner key revocation, owner binding version change, relationship change, unreadable dependency, or unsupported capability denies. Rotation makes the former owner key non-current; its relationships do not transfer to the new key. [FI-DELEG-OWNER-CURRENT]
The delegated path creates no owner or delegate binding and cannot consume an enrollment opportunity. Its receipt identifies the delegate actor and exact owner-binding and relationship dependencies without publishing identity material. [FI-DELEG-NO-BINDING]
Delegated leases
A deployment configures a positive finite delegated maximum and a non-negative
finite delegated skew. The lease deadline is no later than the minimum of:
- delegation expiry;
- delegate proof or connection bound;
- owner binding administrative bound, when applicable;
- current relationship bound;
- local policy bound;
- the lease issue instant plus the configured delegated maximum; and
- any stronger owner-assertion bound the deployment requires.
Missing finite configuration denies. Equality is expired and arithmetic is overflow-safe. [FI-DELEG-LEASE-BOUND]
Before each protected use, the service checks the delegate actor, owner binding and version, relationship and revision, capability intersection, target, resource, local policy, deadline, and invalidation state. It closes or rejects the lease within the deployment's tested revocation-detection bound after any owner or relationship dependency becomes ineligible. The claimed bound is no smaller than measured worst-case detection plus enforcement delay. [FI-DELEG-INVALIDATION-BOUND]
Owner retirement, revocation, rotation, disablement under NIP-FI-LIFECYCLE, or binding replacement invalidates dependent delegates on the same effective schedule as owner authority. A delegate lease never authorizes another delegate or owner key on the same connection. [FI-DELEG-OWNER-CURRENT]
Discovery
A relay claiming this profile MAY add "delegation": true to the NIP-11
federated_identity object only when owner-current resolution, the positive
finite maximum, uniform final admission, and all profile oracles are active. It
does not advertise relationship IDs, owner keys, private delegation protocol
names, or policy detail. [FI-DELEG-DISCOVERY]
Behavioral oracles
| ID | Required outcome |
|---|---|
FI-DELEG-EVIDENCE-CLOSED |
Valid closed evidence passes; unauthenticated, ambiguous, wrong-domain/actor/target/audience, not-yet-valid, and expiry-equality variants deny. |
FI-DELEG-PATH-SEPARATION |
Delegation plus any direct assertion/provenance field denies; neither path falls back to the other. |
FI-DELEG-OWNER-CURRENT |
Exact current owner succeeds; retirement, revocation, rotation, replacement, stale owner version, stale relationship, and unreadable owner state deny without inheritance. |
FI-DELEG-NO-BINDING |
Successful, denied, and concurrent delegated requests create or change no owner/delegate binding or lifecycle state. |
FI-DELEG-LEASE-BOUND |
Every authority bound and equality boundary closes the lease; absent finite maximum denies. |
FI-DELEG-INVALIDATION-BOUND |
Measured owner/relationship revocation closes prepared evidence and live leases within the claimed detection bound. |
FI-DELEG-DISCOVERY |
Discovery is false/absent until the complete active profile passes; public output contains no relationship or owner detail. |
NIP-FI-CONF defines evidence packaging and mutation adequacy. Each uppercase requirement above names the oracle that detects its violation.
Security considerations
Delegation expands authority only by intersection and never by copying owner capabilities. A stolen delegation still requires the delegate key. A stolen delegate key is bounded by the relationship and finite lease. Owner rotation cannot silently transfer delegation because the exact owner key and binding version are dependencies. Implementations should invalidate by dependency index rather than wait for incidental delegate traffic.