Replace the flat future configuration draft with a multi-domain revision, separate denial observation from the non-reclaimable authorization-audit budget, and clarify current runtime behavior. Document lifecycle and denial-oracle rationale and carry the complete transport, lease, invalidation, and conformance obligations into the implementation handoff. Signed-off-by: Cea Stapleton Cordasco <261786559+cea@users.noreply.github.com>
14 KiB
Future corporate identity configuration contract
Historical corporate identity approaches based on provider-specific middleware, unsigned forwarded headers, or a parallel authorization authority are retired guidance. Buzz's provider-neutral contract is NIP-FI.
Availability boundary
This documentation revision defines a proposed configuration contract for a
later NIP-FI implementation. It does not add a parser for
BUZZ_NIP_FI_V1_CONFIG_JSON, remove or reject legacy variables, install a
protected authorization runtime, or activate discovery or enforcement. The
later implementation stack must reconcile this shape with its reviewed code
and executable adapters before claiming any behavior below.
Even after the parser exists, configuring the runtime is not conformance. A deployment must pass the behavioral evidence matrix at its exact deployed revision before NIP-FI discovery or enforcement is advertised, and operators must verify the effective configuration in their deployment; public wording alone is not activation or conformance evidence.
Proposed runtime document
The later implementation stack reserves BUZZ_NIP_FI_V1_CONFIG_JSON as its
sole identity-configuration input. V1 is the reserved input name, while the
document's configuration_contract_revision records breaking shape changes;
neither names or enables a legacy transport profile. The implementation must
provide the following modes and reject the legacy provider-specific variables
rather than treating them as aliases.
Proposed operating modes
- Off:
BUZZ_NIP_FI_V1_CONFIG_JSONis unset. Protected composition is not installed and existing unprotected behavior remains available. - DenyProtected: the document is
{"deny_protected":true}. Every protected route is denied before its handler runs. This mode accepts no other field; an additional field fails startup. - Enforce:
deny_protectedis absent or false and the complete document below is provided. Missing, unknown, empty, duplicate, contradictory, or invalid fields fail startup.
{
"configuration_contract_revision": 2,
"deny_protected": false,
"domains": [
{
"id": "community.example.test",
"authorization_domain_id": "00000000-0000-0000-0000-000000000001",
"authorities": ["community.example.test:443"],
"issuers": [
{
"issuer": "https://issuer.example.test",
"audiences": ["community.example.test"],
"subject_claim": "sub",
"event_author_claim": "nostr_pubkey",
"clock_skew_seconds": 30,
"maximum_token_lifetime_seconds": 3600,
"jwks": {
"jwks_uri": "https://issuer.example.test/.well-known/jwks.json"
}
}
],
"lease": { "maximum_seconds": 300 },
"policy_revision": 1,
"audit": {
"max_events_per_domain": 1000000,
"max_bytes_per_domain": 4294967296,
"max_envelope_bytes": 65536
},
"denial_observation": {
"maximum_records": 100000,
"maximum_bytes": 268435456,
"maximum_record_bytes": 1024
},
"transport": {
"kind": "trusted_proxy_hmac_v2",
"active_secrets_base64url": ["REPLACE_WITH_BASE64URL_SECRET"],
"maximum_provenance_age_seconds": 60,
"future_skew_seconds": 5
},
"enrollment": { "kind": "attested-key" },
"delegation": { "enabled": false }
}
]
}
Revision 2 is an independently reviewed, breaking documentation-first
revision from the earlier flat draft. It does not claim compatibility with a
current parser. The later implementation must update its parser, validation,
fixtures, policy digests, and adapters before claiming this contract.
Proposed document rules and bounds
The future parser must reject unknown and duplicate fields. In Enforce mode:
configuration_contract_revisionis the unsigned integer2anddomainsis non-empty.- Domain
id,authorization_domain_id, and every authority are non-empty and unique across the document. Each domain's authority list is non-empty and contains no duplicates. authorization_domain_idis the canonical lowercase UUID text form. Remove its hyphens and decode the hexadecimal octets from left to right to obtain the exact 16 opaque bytes used by HMAC-v2; any other spelling or length fails startup.- Each authority is the server-configured lowercase ASCII host with an explicit decimal effective port and brackets around IPv6, matching the HMAC-v2 canonical input. Non-canonical or ambiguous authority text fails startup.
- Each domain has at least one issuer. Issuer identifiers are unique within a
domain. Each
issuerand audience is a non-empty string of at most 2048 characters, and each issuer's audience list is non-empty and unique. - The implementation's closed asymmetric algorithm set enters verifier-policy identity through deterministic policy construction. If a later document makes that set configurable, adding or removing an algorithm must change the identity and algorithm order must be normalized.
- Each issuer's
subject_claimdefaults tosub. It and the optionalevent_author_claimare limited to 128 characters. - Each issuer's
clock_skew_secondsdefaults to0and is at most 300. - Each issuer's
maximum_token_lifetime_secondsis required, positive, and at most 86400. - Each issuer's
jwksaccepts exactly one HTTPSjwks_uriordiscovery_uri; credentials, fragments, redirects, and private-network targets are rejected. The source kind and normalized authenticated URI enter verifier-policy identity. - Each domain's
lease.maximum_secondsis required, positive, and at most 3600. Detection bounds derive from this lease limit, immediate version fencing, and bounded post-commit invalidation behavior. Presentation is non-authoritative. - Each domain's
policy_revisionis required and positive. - Each domain's
auditsets the immutable authorization-evidence capacity (max_events_per_domain,max_bytes_per_domain,max_envelope_bytes). Values are positive and finite, validation is overflow safe, andmax_envelope_bytescannot exceedmax_bytes_per_domain. There is no online prune, export, reset, acknowledgement, or recovery workflow. Successful or authorization-affecting operations consume this finite budget; denied operations do not consume it and never create authorization receipts. Legitimate exhaustion is an accepted, unrecoverable, domain-wide fail-closed outage within the installation and domain lineage. Sizing is an irreversible installation-lifetime decision, so operators monitor consumption and alert with substantial headroom. See the threat model's availability and resource exhaustion analysis. - Each domain's
denial_observationhas positive finitemaximum_records,maximum_bytes, andmaximum_record_bytes. Validation is overflow safe andmaximum_record_bytescannot exceedmaximum_bytes. This capacity is independent from authorization audit. Exhaustion permits drop or bounded truncation only and emits aggregate saturation signals where possible; it cannot weaken, delay, retry, reverse, receipt, bind, replay, or otherwise mutate a denial. transportandenrollmentare required non-empty domain objects consumed by matching runtime adapters.enrollment.kindis exactlyattested-key,provisioned, ortofu;delegationremains optional and disabled by omission as described below.transport.kindisclient_attached,trusted_proxy_hmac_v2, or a private registered identifier matchingx-<operator>-<profile>-v<N>and accepted only when its deployment-installed adapter and profile contract satisfy NIP-FI. The example remains stock. Selection occurs before listeners open for each bound route and domain, never from request input, and failure never falls back to another profile.
Issuer-level fields own issuer, audience, claim, time, and JWKS semantics. Domain-level fields own transport, enrollment, lease, policy revision, audit capacity, denial-observation capacity, and delegation. Stable verifier policy identity covers every semantic input, authenticated key-source identity, and the compiled verifier-contract fingerprint.
The future implementation must validate each jwks refresh policy at construction: a fetched document
cannot exceed 4 MiB, a snapshot cannot stay fresh longer than 24 hours, every
refresh bound is finite and nonzero, and an accepted key set contains between
1 and 128 keys. Production deployments may use tighter bounds. Key refreshes are
single-flight and stale verification fails closed.
Delegation
Delegation is disabled by default. Omitting the delegation object or setting
{"enabled": false} disables it, and a disabled delegation object must not
carry capabilities or a lifetime. Enabling it requires enabled: true, a
non-empty unique capabilities list drawn from the closed route-capability
set, and a positive maximum_seconds of at most 3600 that does not exceed
lease.maximum_seconds. Delegated authority is always capability-scoped —
never transport-wide — and the relay's NIP-11 information document does not
advertise delegation.
Corporate-identity delegation is unsupported by this documentation stack. The public production path does not implement complete delegated issuance, owner-bound resolution, expiry, invalidation, reconnect, or protected-transport behavior. Operators must keep delegation disabled, and discovery must report it as false or omit it. Enabling the configuration shape does not add the missing authority and must not be used to advertise support. See the integration guide's availability boundary for the implementation and evidence requirements.
Direct NIP-FI authorization and future delegation are separate capabilities. Delegation can be advertised only after a reviewed delegated-owner implementation passes the complete applicable cross-transport lifecycle and session evidence.
Supported boundary
NIP-FI combines a verified issuer-qualified assertion result with independent fresh Nostr key proof, current durable binding and lifecycle state, server-owned request context, and final application admission. The stock trusted-proxy-hmac-v2 construction binds HMAC provenance to the complete canonical request. A private registered trusted-edge profile may use another reviewed construction only when it satisfies the same normalized-result and final-admission contract. Header presence and network location alone are insufficient.
NIP-FI defines no public corporate directory or identity projection. Issuer-qualified identity and profile claims remain access-controlled enforcement data.
No parallel authority
An enforcing domain has one current NIP-FI authority and policy lineage for every protected ingress. Do not:
- accept a legacy corporate header when NIP-FI denies;
- keep a provider-specific identity path for selected routes;
- infer identity from email or subject without the configured issuer;
- copy assertion expiry into durable binding expiry;
- import revoked, disabled, or retired state as an active binding; or
- expose corporate claims in Nostr events, discovery, logs, metrics, or traces.
NIP-42 and NIP-98 continue to prove control of a Nostr key. They do not replace the additional NIP-FI authority for a protected operation.
Migration plan
- Inventory: enumerate every protected WebSocket and HTTP ingress, existing identity source, forwarded field, policy, binding store, lifecycle action, and fallback.
- Freeze legacy expansion: add no routes, providers, claims, or identities to the legacy authority while migration is in progress.
- Define domains and policies: map each server-owned domain to exact issuer-qualified identities
(iss, sub), accepted semantics, enrollment mode, and transport profile. - Normalize state: represent active durable bindings, immutable provenance, retired pairs, disabled identities, revoked keys, pending replacement lineage, typed history, and versions.
- Verify imports: require independent evidence for imported identity/key pairs. Do not treat a forwarded header, email match, or expired assertion as proof of key control.
- Install without activation: deploy the later exact implementation with discovery and enforcement off, one canonical normalized-result and final-admission contract, and no legacy fallback.
- Run behavior: execute all applicable
FI-TRACE-*adapters at the exact artifact, deployment, and policy digests, including route inventory and deployed-boundary proxy negatives. - Cut over atomically: enable one authority across the complete protected-ingress set and remove the legacy path. Canary isolated domains or deployments, not individual routes under competing authorities.
- Verify and retain: test old headers, old keys, tombstones, conflicts, denial privacy, dependency outages, restore, and rollback; retain privacy-safe evidence.
If historical data lacks proof or unambiguous issuer qualification, keep it non-authoritative until a separately authorized provisioning or recovery transition establishes current state.
Rollback and repair
Rollback returns to a previously conformant artifact with compatible current state, or disables discovery and fails protected operations closed. It never restores unsigned forwarding, a removed verification key, a parallel provider runtime, or an older authority database.
Correct an imported binding or lifecycle fact with a reviewed privileged compensating transition. Preserve typed history and incident evidence; do not delete the record to make ordinary enrollment available again.