Files
buzz/docs/CORPORATE_IDENTITY.md
Cea Stapleton Cordasco 633260e404 docs(nip-fi): close outstanding review findings
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>
2026-08-12 17:31:07 -05:00

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_JSON is 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_protected is 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_revision is the unsigned integer 2 and domains is 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_id is 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 issuer and 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_claim defaults to sub. It and the optional event_author_claim are limited to 128 characters.
  • Each issuer's clock_skew_seconds defaults to 0 and is at most 300.
  • Each issuer's maximum_token_lifetime_seconds is required, positive, and at most 86400.
  • Each issuer's jwks accepts exactly one HTTPS jwks_uri or discovery_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_seconds is 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_revision is required and positive.
  • Each domain's audit sets 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, and max_envelope_bytes cannot exceed max_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_observation has positive finite maximum_records, maximum_bytes, and maximum_record_bytes. Validation is overflow safe and maximum_record_bytes cannot exceed maximum_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.
  • transport and enrollment are required non-empty domain objects consumed by matching runtime adapters. enrollment.kind is exactly attested-key, provisioned, or tofu; delegation remains optional and disabled by omission as described below.
  • transport.kind is client_attached, trusted_proxy_hmac_v2, or a private registered identifier matching x-<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

  1. Inventory: enumerate every protected WebSocket and HTTP ingress, existing identity source, forwarded field, policy, binding store, lifecycle action, and fallback.
  2. Freeze legacy expansion: add no routes, providers, claims, or identities to the legacy authority while migration is in progress.
  3. Define domains and policies: map each server-owned domain to exact issuer-qualified identities (iss, sub), accepted semantics, enrollment mode, and transport profile.
  4. Normalize state: represent active durable bindings, immutable provenance, retired pairs, disabled identities, revoked keys, pending replacement lineage, typed history, and versions.
  5. 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.
  6. 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.
  7. Run behavior: execute all applicable FI-TRACE-* adapters at the exact artifact, deployment, and policy digests, including route inventory and deployed-boundary proxy negatives.
  8. 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.
  9. 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.

Operator references