mirror of
https://github.com/block/buzz.git
synced 2026-11-06 01:11:33 +00:00
docs(nip-fi): document the runtime configuration contract
- CORPORATE_IDENTITY.md: document BUZZ_NIP_FI_V1_CONFIG_JSON (Off / DenyProtected / Enforce), the complete runtime document with its field bounds, JWKS refresh limits, the 120-second status renewal bound, the removed legacy identity-provider variables that now fail startup, and the delegation default and enablement rules - .env.example: replace the placeholder identity section with the commented document example and the legacy-variable removal note - NIP_FI_DEPLOYMENT.md / NIP_FI_RUNTIME_OPERATIONS.md: document the single configuration input consistently and map the install-without- discovery step to the operating modes - deploy READMEs: pgcrypto requirement for managed PostgreSQL, identity configuration pass-through with secret-handling guidance, and audit-capacity sizing guidance Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Cea Stapleton Cordasco <261786559+cea@users.noreply.github.com>
This commit is contained in:
25
.env.example
25
.env.example
@@ -54,12 +54,25 @@ RELAY_URL=ws://localhost:3000
|
||||
# -----------------------------------------------------------------------------
|
||||
# Federated identity (NIP-FI)
|
||||
# -----------------------------------------------------------------------------
|
||||
# This revision contains contract documentation only. It defines no supported
|
||||
# NIP-FI runtime environment variables and does not activate enforcement.
|
||||
# Review-only policy shape: docs/examples/nip-fi-stock-domain.json.example
|
||||
# Do not convert that example into environment variables or trust a legacy
|
||||
# corporate identity header. A later implementation release must document its
|
||||
# exact adapter/configuration surface and matching behavioral evidence.
|
||||
# Provider-free protected authorization is configured only through one JSON
|
||||
# document. If BUZZ_NIP_FI_V1_CONFIG_JSON is absent, the runtime is Off. To
|
||||
# deny every protected route during an emergency, use:
|
||||
# BUZZ_NIP_FI_V1_CONFIG_JSON={"deny_protected":true}
|
||||
#
|
||||
# Full Enforce mode requires every RuntimeDocument field shown below. Replace
|
||||
# the example endpoints and transport secret before enabling it. Delegation is
|
||||
# disabled unless the document explicitly enables it with a non-empty closed
|
||||
# capability list and a bounded maximum_seconds value.
|
||||
# BUZZ_NIP_FI_V1_CONFIG_JSON={"issuer":"https://issuer.example","audience":"buzz-relay","subject_claim":"sub","event_author_claim":"nostr_pubkey","clock_skew_seconds":30,"maximum_token_lifetime_seconds":3600,"jwks":{"jwks_uri":"https://issuer.example/.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},"client_status_admission":{"max_presentations_per_domain":1000000,"max_presentations_per_actor":10000,"max_presentations_per_peer":10000},"transport":{"kind":"trusted_proxy_hmac_v2","active_secrets_base64url":["replace-with-base64url-secret"],"maximum_provenance_age_seconds":60,"future_skew_seconds":5},"enrollment":{"kind":"canonical_admission"},"restore":{"kind":"operation_manifest"},"delegation":{"enabled":false}}
|
||||
#
|
||||
# The complete document contract, field bounds, and activation gates are in
|
||||
# docs/CORPORATE_IDENTITY.md and docs/NIP_FI_DEPLOYMENT.md. Configuring
|
||||
# Enforce is not conformance evidence.
|
||||
#
|
||||
# Former identity-provider environment variables
|
||||
# (BUZZ_REQUIRE_CORPORATE_IDENTITY and every BUZZ_CORPORATE_IDENTITY_* name)
|
||||
# are removed. Setting any of them is a hard startup error; they are not
|
||||
# aliases for this document.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Git (NIP-34 bare repositories)
|
||||
|
||||
@@ -52,6 +52,12 @@ See:
|
||||
|
||||
The chart fails at `helm install` / `helm template` time with a clear message if any of these are missing or malformed (see `templates/_validate.tpl`).
|
||||
|
||||
When `externalPostgresql.url` is used, the database must permit the `pgcrypto`
|
||||
extension (schema bootstrap runs `CREATE EXTENSION IF NOT EXISTS pgcrypto`).
|
||||
Most managed PostgreSQL offerings allow it, but the role applying migrations
|
||||
needs the privilege to create it, or an administrator can pre-create the
|
||||
extension.
|
||||
|
||||
## HA (production)
|
||||
|
||||
`replicaCount > 1` hard-requires Redis:
|
||||
@@ -80,16 +86,21 @@ Save these. Losing any of them is data loss. See NOTES.txt printed by `helm inst
|
||||
|
||||
## NIP-FI readiness
|
||||
|
||||
This chart does not expose a NIP-FI runtime adapter, policy schema, trusted-edge
|
||||
topology, secret keys, or conformance runner. Do not advertise or enforce
|
||||
NIP-FI from this chart, and do not use an ingress identity header or
|
||||
provider-specific sidecar as a fallback authority.
|
||||
This chart does not provision a NIP-FI trusted-edge topology, issuer
|
||||
integration, secret keys, or conformance runner. The relay's identity
|
||||
configuration document (`BUZZ_NIP_FI_V1_CONFIG_JSON`, see the
|
||||
[identity configuration contract](../../../docs/CORPORATE_IDENTITY.md)) can be
|
||||
supplied like any other relay environment variable — keep the whole document
|
||||
in `secrets.existingSecret` rather than values, because its
|
||||
`transport.active_secrets_base64url` entries are live secret material. Do not
|
||||
advertise or enforce NIP-FI from this chart, and do not use an ingress
|
||||
identity header or provider-specific sidecar as a fallback authority.
|
||||
|
||||
A later chart release must pin an implementation with an exact adapter and
|
||||
configuration version, keep policy separate from secret values, isolate
|
||||
verifier ingress for `trusted-proxy-hmac-v1`, include every fail-closed
|
||||
dependency in readiness, and link an immutable exact-head behavioral report.
|
||||
A rendered chart and healthy pod do not prove those behaviors. See the
|
||||
An activating deployment must pin an exact image, keep policy separate from
|
||||
secret values, isolate verifier ingress for `trusted-proxy-hmac-v1`, include
|
||||
every fail-closed dependency in readiness, and link an immutable exact-head
|
||||
behavioral report. A rendered chart and healthy pod do not prove those
|
||||
behaviors. See the
|
||||
[provider-neutral deployment guide](../../../docs/NIP_FI_DEPLOYMENT.md) and
|
||||
[runtime operations guide](../../../docs/NIP_FI_RUNTIME_OPERATIONS.md).
|
||||
|
||||
|
||||
@@ -36,6 +36,18 @@ keypair.
|
||||
`buzz-admin migrate` before starting the relay when bootstrapping a fresh
|
||||
database. Auto-migration requires an image that includes embedded SQLx
|
||||
migrations.
|
||||
- PostgreSQL must allow the `pgcrypto` extension — schema bootstrap and
|
||||
migrations run `CREATE EXTENSION IF NOT EXISTS pgcrypto` (used for
|
||||
`gen_random_uuid()` and digest hashing). On managed PostgreSQL, ensure the
|
||||
extension is permitted for the migration role or pre-create it as an
|
||||
administrator.
|
||||
- Relay-verified identity (optional, off by default) is configured with
|
||||
`BUZZ_NIP_FI_V1_CONFIG_JSON` (see the
|
||||
[identity configuration contract](../../docs/CORPORATE_IDENTITY.md)). Its
|
||||
`audit` bounds are a one-way lifetime budget per community domain — size
|
||||
`max_events_per_domain` from expected identities × lifecycle operations with
|
||||
generous headroom and monitor consumption, because exhaustion fails closed
|
||||
and denies authorization-affecting operations rather than dropping evidence.
|
||||
- The stack uses Postgres, Redis, MinIO, and a git data volume because
|
||||
those are real Buzz dependencies today. Minimal mode can simplify this later.
|
||||
|
||||
@@ -43,16 +55,19 @@ Run `./run.sh backup-hint` for the backup checklist.
|
||||
|
||||
## NIP-FI readiness
|
||||
|
||||
This Compose bundle does not wire a NIP-FI runtime adapter, policy schema,
|
||||
trusted edge, or conformance runner. Do not advertise or enforce NIP-FI from
|
||||
this bundle, and do not add a provider-specific sidecar or unsigned corporate
|
||||
identity header as a substitute.
|
||||
This Compose bundle does not provision a NIP-FI trusted edge, issuer
|
||||
integration, or conformance runner. The relay's identity configuration
|
||||
document (`BUZZ_NIP_FI_V1_CONFIG_JSON`, see the
|
||||
[identity configuration contract](../../docs/CORPORATE_IDENTITY.md)) passes
|
||||
through like any other relay environment variable, but do not advertise or
|
||||
enforce NIP-FI from this bundle, and do not add a provider-specific sidecar
|
||||
or unsigned corporate identity header as a substitute.
|
||||
|
||||
A later implementation release must pin an exact image, document its supported
|
||||
configuration and adapter version, isolate verifier ingress when
|
||||
`trusted-proxy-hmac-v1` is enabled, deliver HMAC keys through a secret store,
|
||||
and pass the complete exact-head behavioral matrix before activation. A valid
|
||||
Compose render or healthy relay does not close those gates. See the
|
||||
An activating deployment must pin an exact image, isolate verifier ingress
|
||||
when `trusted-proxy-hmac-v1` is enabled, deliver HMAC secrets through a
|
||||
secret store rather than `.env`, and pass the complete exact-head behavioral
|
||||
matrix before activation. A valid Compose render or healthy relay does not
|
||||
close those gates. See the
|
||||
[provider-neutral deployment guide](../../docs/NIP_FI_DEPLOYMENT.md) and
|
||||
[runtime operations guide](../../docs/NIP_FI_RUNTIME_OPERATIONS.md).
|
||||
|
||||
|
||||
@@ -2,22 +2,120 @@
|
||||
|
||||
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](nips/NIP-FI.md).
|
||||
|
||||
## Current status
|
||||
## Runtime configuration
|
||||
|
||||
This documentation revision does not include a NIP-FI runtime adapter, activate identity enforcement, or establish conformance. Do not deploy a legacy identity sidecar or trust an identity header as a temporary substitute. A later exact-head implementation and deployment must pass the [behavioral evidence matrix](nips/NIP-FI-CONFORMANCE.md) before discovery or enforcement is enabled.
|
||||
The relay's protected authorization runtime is configured only with the
|
||||
`BUZZ_NIP_FI_V1_CONFIG_JSON` environment variable. The former
|
||||
identity-provider variables (`BUZZ_REQUIRE_CORPORATE_IDENTITY` and every
|
||||
`BUZZ_CORPORATE_IDENTITY_*` name) are removed: setting any of them fails
|
||||
startup instead of weakening policy, and none of them is an alias for the
|
||||
document below.
|
||||
|
||||
### Delegation availability
|
||||
Configuring the runtime is not conformance. A deployment must pass the
|
||||
[behavioral evidence matrix](nips/NIP-FI-CONFORMANCE.md) 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.
|
||||
|
||||
### Operating modes
|
||||
|
||||
- **Off:** leave `BUZZ_NIP_FI_V1_CONFIG_JSON` unset. Protected composition is
|
||||
not installed and existing unprotected behavior remains available.
|
||||
- **DenyProtected:** set the document to `{"deny_protected":true}`. Every
|
||||
protected route is denied before its handler runs. `deny_protected` takes
|
||||
precedence over every other field in the document.
|
||||
- **Enforce:** provide the complete document below. Missing, unknown, empty, or
|
||||
invalid fields fail startup.
|
||||
|
||||
```json
|
||||
{
|
||||
"issuer": "https://issuer.example",
|
||||
"audience": "buzz-relay",
|
||||
"subject_claim": "sub",
|
||||
"event_author_claim": "nostr_pubkey",
|
||||
"clock_skew_seconds": 30,
|
||||
"maximum_token_lifetime_seconds": 3600,
|
||||
"jwks": {
|
||||
"jwks_uri": "https://issuer.example/.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
|
||||
},
|
||||
"client_status_admission": {
|
||||
"max_presentations_per_domain": 1000000,
|
||||
"max_presentations_per_actor": 10000,
|
||||
"max_presentations_per_peer": 10000
|
||||
},
|
||||
"transport": {
|
||||
"kind": "trusted_proxy_hmac_v2",
|
||||
"active_secrets_base64url": ["replace-with-base64url-secret"],
|
||||
"maximum_provenance_age_seconds": 60,
|
||||
"future_skew_seconds": 5
|
||||
},
|
||||
"enrollment": { "kind": "canonical_admission" },
|
||||
"restore": { "kind": "operation_manifest" },
|
||||
"delegation": { "enabled": false }
|
||||
}
|
||||
```
|
||||
|
||||
### Document rules and bounds
|
||||
|
||||
The document rejects unknown fields. In Enforce mode:
|
||||
|
||||
- `issuer` and `audience` are required non-empty strings of at most 2048
|
||||
characters each.
|
||||
- `subject_claim` defaults to `sub`. It and the optional `event_author_claim`
|
||||
are limited to 128 characters.
|
||||
- `clock_skew_seconds` defaults to `0` and is at most 300.
|
||||
- `maximum_token_lifetime_seconds` is required, positive, and at most 86400.
|
||||
- `jwks` accepts exactly one HTTPS `jwks_uri` or `discovery_uri`; credentials,
|
||||
fragments, redirects, and private-network targets are rejected.
|
||||
- `lease.maximum_seconds` is required, positive, and at most 3600.
|
||||
- `policy_revision` is required and positive.
|
||||
- `audit` sets the immutable authorization-evidence capacity
|
||||
(`max_events_per_domain`, `max_bytes_per_domain`, `max_envelope_bytes`).
|
||||
There is no online prune, export, reset, or acknowledgement workflow — size
|
||||
the budget for the installation's lifetime with generous headroom, because
|
||||
exhaustion denies further authorization-affecting operations instead of
|
||||
dropping evidence.
|
||||
- `client_status_admission` limits are positive;
|
||||
`max_presentations_per_domain` cannot exceed `audit.max_events_per_domain`,
|
||||
and the per-actor and per-peer limits cannot exceed the per-domain limit.
|
||||
- `transport`, `enrollment`, and `restore` are required non-empty objects
|
||||
consumed by the matching runtime adapters. Production ingress requires the
|
||||
exact `trusted_proxy_hmac_v2` transport configuration shown above; the
|
||||
trusted-proxy provenance verifier is constructed at startup, before
|
||||
listeners open.
|
||||
|
||||
The `jwks` refresh policy is validated 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 uses tighter bounds. Key refreshes are
|
||||
single-flight and stale verification fails closed. Current-status
|
||||
presentation renews within 120 seconds, so active connections observe
|
||||
authoritative policy changes within that polling bound.
|
||||
|
||||
### 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 currently unsupported. 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. A legacy or downstream configuration flag does not add the missing
|
||||
authority and must not be used to advertise support.
|
||||
|
||||
This documentation-only revision does not change runtime code or configuration
|
||||
defaults. Operators must verify the effective setting in their deployment;
|
||||
public wording alone is not activation or conformance evidence. See the
|
||||
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](NIP_FI_INTEGRATION.md#delegation-availability)
|
||||
for the implementation and evidence requirements.
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
# NIP-FI stock deployment
|
||||
|
||||
This guide describes a provider-neutral stock deployment for the normative [NIP-FI contract](nips/NIP-FI.md). It does not define runtime configuration keys or activate support.
|
||||
This guide describes a provider-neutral stock deployment for the normative [NIP-FI contract](nips/NIP-FI.md). It does not by itself activate support.
|
||||
|
||||
## Current status
|
||||
## Runtime configuration
|
||||
|
||||
This documentation revision ships no NIP-FI runtime adapter, configuration schema, image capability, or conformance report. The current Compose and Helm bundles must not advertise or enforce NIP-FI. A later implementation release must document its exact adapter and configuration surface and pass the [behavioral evidence matrix](nips/NIP-FI-CONFORMANCE.md) at the deployed revision before activation.
|
||||
The relay accepts exactly one identity-configuration input: the `BUZZ_NIP_FI_V1_CONFIG_JSON` environment variable. Absent means Off, `{"deny_protected":true}` denies every protected route before its handler runs, and only the complete document enables Enforce mode. The document contract, field bounds, and startup rejection rules — including the removed legacy identity-provider variables, which fail startup when set — are documented in the [identity configuration contract](CORPORATE_IDENTITY.md).
|
||||
|
||||
The files under [`docs/examples`](examples/) are review templates. They are not accepted runtime schemas and contain no deployable secrets.
|
||||
Configuring Enforce is not conformance. A deployment must not advertise or enforce NIP-FI until it passes the [behavioral evidence matrix](nips/NIP-FI-CONFORMANCE.md) at the deployed revision.
|
||||
|
||||
The files under [`docs/examples`](examples/) are review templates. They are not accepted runtime schemas — the only runtime input is the environment variable above — and they contain no deployable secrets.
|
||||
|
||||
## Stock topology
|
||||
|
||||
@@ -41,7 +43,7 @@ A source scan, config parse, rendered manifest, healthy process, or documentatio
|
||||
|
||||
Use one reviewed policy object per server-selected domain. The review-only [stock domain example](examples/nip-fi-stock-domain.json.example) records the required decisions without claiming a runtime schema.
|
||||
|
||||
At minimum, the later runtime schema must represent:
|
||||
The runtime document and its fixed verifier semantics together represent:
|
||||
|
||||
- exact domain identity and trusted listener or route mapping;
|
||||
- accepted issuer and audience values;
|
||||
@@ -101,7 +103,7 @@ List every protected ingress and its current authorization path. Include WebSock
|
||||
|
||||
### 2. Install without discovery
|
||||
|
||||
Deploy the exact implementation artifact with NIP-FI discovery and enforcement off. Load reviewed policy and secret references. Validate issuer connectivity, JWKS authenticity, state migrations, backup, observability redaction, and route inventory without creating production bindings.
|
||||
Deploy the exact implementation artifact with NIP-FI discovery and enforcement off — leave `BUZZ_NIP_FI_V1_CONFIG_JSON` unset, or set `{"deny_protected":true}` where protected routes must already deny. Load reviewed policy and secret references. Validate issuer connectivity, JWKS authenticity, state migrations, backup, observability redaction, and route inventory without creating production bindings.
|
||||
|
||||
### 3. Run isolated behavior
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
This guide covers lifecycle, recovery, restore, and rollback for a conforming Buzz NIP-FI implementation. The normative [specification](nips/NIP-FI.md) and [formal model](nips/NIP-FI-MODEL.md) control when this guide differs.
|
||||
|
||||
## Current status
|
||||
## Runtime configuration
|
||||
|
||||
This documentation revision supplies no runtime adapter or operator command. Command names and request schemas must come from the later exact-head implementation stack. The [recovery-plan example](examples/nip-fi-recovery-plan.json.example) is a review template, not a runtime request.
|
||||
The runtime's sole identity-configuration input is `BUZZ_NIP_FI_V1_CONFIG_JSON`: absent is Off, `{"deny_protected":true}` denies every protected route, and the complete document enables Enforce. Field bounds and the removed legacy identity-provider variables — which fail startup when set — are documented in the [identity configuration contract](CORPORATE_IDENTITY.md). Operator lifecycle command names and request schemas come from the implementation's own operator tooling; the [recovery-plan example](examples/nip-fi-recovery-plan.json.example) is a review template, not a runtime request.
|
||||
|
||||
Do not simulate an operator transition with direct database edits. Every authority change uses a separately authorized, audited transition with fresh target-key proof when a new key is introduced.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user