Network Authority API¶
The Network Authority exposes HTTP endpoints for enrollment, policy, revocation, and health.
flowchart TB
home["Browser console<br/>/"]
health["Health and metrics<br/>/healthz /readyz /metrics"]
public["Public network data<br/>/sovereign.json /genesis /policy /crl"]
enrollment["Enrollment<br/>/join"]
node_ops["Node operations<br/>/heartbeat /renew"]
admin["Admin operations<br/>/admin/invite /admin/revoke /admin/policy"]
sovereign["Sovereign trust<br/>/sovereign-revocation-feed"]
connectome["Connectome<br/>/recognition-graph /connectome"]
auth["Operator signature headers"]
node_sig["Node proof-of-possession signature"]
auth --> admin
node_sig --> enrollment
node_sig --> node_ops
home --> health
home --> public
enrollment --> public
admin --> public
admin --> sovereign
sovereign --> public
sovereign --> connectome
The public read surface¶
This is the authoritative classification of what this service answers to an
unauthenticated caller. The same classification is generated into the live
/api-reference page and /swagger.json from
genesis_mesh/na_service/operator_console/surfaces.py, so it cannot drift from
what the service actually exposes.
Class |
Meaning |
|---|---|
Public |
Answers any caller. Discloses no membership inventory. |
Internal |
Not gated in code; must be restricted by deployment (management interface or firewall). |
Operator |
Requires operator signature headers. |
Node |
Requires node proof-of-possession. |
Surface |
Class |
Rate limit |
Notes |
|---|---|---|---|
|
Public |
— |
Liveness and readiness only. |
|
Internal |
— |
Aggregate counters. Prometheus cannot perform signed-envelope auth, so restrict by deployment. |
|
Public (count) / Operator (roster) |
— |
The roster carries keys, roles and remote addresses. |
|
Public |
— |
Peer discovery protocol. Returns matching descriptors. |
|
Public (count) |
— |
Does not enumerate the registry. |
|
Public |
— |
Signed trust material, public by design. |
|
Public |
60/min per IP |
Stateless signature checking. Public by protocol design; see below. |
|
Node |
varies |
Node-signed. |
|
Operator |
30/min per IP |
Operator-signed. |
Why the verification endpoints are public¶
The nine */verify endpoints — /consensus/verify, /agreements/verify,
/disclosure/verify, /trust-evidence/verify, /boundary/verify,
/data-usage/verify, /attestations/verify, /recognition-treaties/verify and
/attestations/verify-with-treaty — let any party check a signature on material
they already hold. That is deliberately open: verification is a protocol
service, it is stateless, and it discloses no inventory. Because they are open,
each is rate limited to 60 requests per minute per source address so they
cannot be used as a free oracle or a traffic amplifier.
Error Responses¶
All JSON API failures use one shared envelope. Routes raise typed business failures; the Network Authority error layer translates them into HTTP status codes, safe messages, and a correlation ID.
{
"error": {
"code": "treaty_not_found",
"message": "Treaty not found",
"details": {},
"request_id": "8d2e6a0f-0e57-4f1b-b8f2-12de680d32fd"
}
}
The same request ID is also returned in the X-Request-ID response header.
Clients may send X-Request-ID to correlate their own logs with Network
Authority logs.
Common statuses:
Status |
Meaning |
|---|---|
|
Malformed request or invalid request parameters. |
|
Missing or invalid operator/node signature. |
|
Authenticated principal is not allowed to perform the action. |
|
Referenced resource does not exist. |
|
Request conflicts with persisted trust state, such as a stale sequence. |
|
JSON body is syntactically valid but fails schema/model validation. |
|
Request exceeded the configured rate limit. |
|
Unexpected server error. The response is sanitized and never includes stack traces, secret tokens, private keys, file paths, or internal implementation details. |
Browser Console¶
GET /¶
Returns a human-readable Network Authority home page with links to public, health, node, and operator routes. It is intended for operators opening the NA from a browser and does not replace signed API clients for write operations.
GET /dashboard¶
Returns the read-only sovereign health and trust dashboard. The page summarizes readiness, Connectome counts, treaty lifecycle risk, revocation-feed freshness, recent trust-state changes, and links to raw JSON/reference surfaces.
GET /dashboard.json¶
Returns the same dashboard model in machine-readable form for automation and independent verification. This endpoint does not create, mutate, authorize, or revoke trust.
Health¶
GET /healthz¶
Liveness probe. Does not perform dependency checks.
GET /readyz¶
Readiness probe. Verifies database connectivity and migration state.
GET /nodes¶
Returns the number of recently active, non-revoked nodes. Rows are considered active when their latest join or heartbeat timestamp is within the Network Authority active-node window.
{ "count": 2 }
The per-node roster — public keys, roles, heartbeat status, the address each
node connected from, and certificate expiry — is operator-authenticated.
Send the standard admin headers (X-Admin-Key-Id, X-Admin-Timestamp,
X-Admin-Nonce, X-Admin-Signature, signed over an empty body) to receive it:
{ "count": 2, "nodes": { "<cert_id>": { "node_public_key": "...", "roles": ["role:anchor"], "remote_addr": "..." } } }
Presenting admin headers that do not verify returns 401; it does not fall back
to the public response.
GET /metrics¶
Returns Prometheus text metrics for Network Authority operations. The endpoint includes counters and gauges for issued certificates, recently active nodes, revoked certificates, active CRL sequence, and persisted policy versions.
Classification: internal. These are aggregate counters with no per-node detail, and Prometheus cannot perform this service’s signed-envelope authentication, so the endpoint is not gated in code. Bind it to the management interface or firewall it; do not expose it to untrusted networks.
Public Network Data¶
GET /genesis¶
Returns the active genesis block.
GET /sovereign.json¶
Returns operator-safe public metadata for a sovereign. This is the preferred discovery surface for another operator before forming a recognition treaty.
Response excerpt:
{
"sovereign_id": "USG-NB",
"network_name": "USG-NB",
"network_version": "v0.1",
"endpoint": "http://164.92.250.135:8443",
"network_authority": {
"public_key": "<base64-ed25519-public-key>",
"valid_from": "<iso8601>",
"valid_to": "<iso8601>"
},
"root_public_key": "<base64-ed25519-public-key>",
"supported_surfaces": {
"genesis": "http://164.92.250.135:8443/genesis",
"recognition_treaties": "http://164.92.250.135:8443/recognition-treaties",
"sovereign_revocation_feed": "http://164.92.250.135:8443/sovereign-revocation-feed",
"connectome": "http://164.92.250.135:8443/connectome.json"
}
}
The response intentionally excludes private keys, operator signatures, local filesystem paths, and database paths.
GET /policy¶
Returns the active policy manifest. The policy is backed by SQLite; if no policy has been published, the service creates and returns a default signed policy.
GET /crl¶
Returns the active signed certificate revocation list. If no certificates have been revoked, the service returns a signed empty CRL.
Enrollment¶
POST /join¶
Requests a join certificate.
Request:
{
"node_public_key": "<base64-ed25519-public-key>",
"invite_token": "<single-use-token>",
"validity_hours": 168,
"timestamp": "<iso8601>",
"nonce": "<unique-nonce>",
"signature": "<base64-ed25519-signature>"
}
The Network Authority assigns roles from the invite token and ignores client-supplied role claims. The signature proves possession of the node private key before the invite token is consumed.
Response: a signed JoinCertificate.
Node Operations¶
POST /heartbeat¶
Updates node liveness. The request must prove possession of the node private key and is rejected if the certificate is expired, not yet valid, or revoked.
POST /renew¶
Requests certificate renewal. The request must prove possession of the node private key. Roles are preserved from server-side state, expired or revoked certificates cannot renew, and requested validity is capped by the original invite validity policy stored with the issued certificate.
Admin Endpoints¶
Admin endpoints require operator-key authentication headers:
Header |
Description |
|---|---|
|
Operator key identifier. |
|
Request timestamp. |
|
Unique nonce scoped to the operator key. |
|
Signature over the canonical admin payload. |
POST /admin/invite¶
Creates a single-use invite token.
{
"roles": ["role:anchor"],
"max_validity_hours": 168,
"token_expiry_hours": 24
}
Response:
{
"token_id": "<secret-token>",
"expires_at": "<iso8601>"
}
POST /admin/revoke¶
Revokes a certificate and publishes a new CRL.
{
"cert_id": "<certificate-id>",
"reason": "key_compromise"
}
Allowed reasons are key_compromise, cessation_of_operation, superseded,
and unspecified.
Operator tiers¶
Every configured operator key declares a tier. The Network Authority refuses to start if any key has no tier — there is deliberately no default, because defaulting to privileged would leave every key all-powerful and defaulting to standard would silently strip revocation from the keys an operator reaches for during an incident.
Tier |
May do |
|---|---|
|
Day-to-day work: invitations, reads, and routine operations. |
|
Everything a standard key may do, plus anything that grants trust, withdraws trust, or changes policy. |
Privileged satisfies a standard requirement; the reverse is not true.
Privileged routes — POST /admin/revoke,
POST /admin/operator-keys/{key_id}/revoke, POST /admin/policy,
POST /admin/policy/rollback, POST /admin/attestations,
POST /admin/attestations/{id}/revoke, POST /admin/recognition-treaties,
POST /admin/recognition-treaties/{id}/revoke,
POST /admin/recognition-policy,
POST /admin/sovereign-revocation-feeds/import.
Every other admin route requires standard.
A key that authenticates but lacks the tier receives 403 insufficient_operator_tier — deliberately distinct from the 401 an unknown
or revoked key receives, so that “who are you?” and “you may not do that” stay
separable in an incident log. Denials are audited as admin_authz_denied with
the holder and required tiers.
Configure tiers with --operator-key-tier key-id=standard|privileged or the
OPERATOR_KEY_TIERS_JSON environment variable, alongside the existing key
configuration.
POST /admin/operator-keys/{key_id}/revoke¶
Switches an operator key off at runtime. The key stops authenticating on the next request; no restart and no configuration edit is required.
{ "reason": "key_compromise" }
The check runs before signature verification and before the nonce is consumed, so a revoked key cannot perform any admin action — including revoking other operators.
Terminal. There is no un-revoke endpoint; a revoked key_id stays revoked
for the life of the deployment. Restoring one means editing configuration and
restarting, deliberately.
Response |
Meaning |
|---|---|
|
Revoked. |
|
No such key in the configured operator key map. |
|
Refused: revoking would leave zero usable operator keys and make the service unmanageable without a restart. Configure another operator key first. |
A caller presenting a revoked key receives 401 with Unknown admin key —
identical to an unrecognised key, so a stolen key reveals nothing about whether
its compromise was detected. The audit log records the true reason
(admin_auth_failed with reason: revoked_key) plus an operator_key_revoked
event naming who performed it.
POST /admin/policy¶
Publishes and activates a signed policy version.
GET /admin/policy/history¶
Lists persisted policy versions.
POST /admin/policy/rollback¶
Activates a previously persisted policy version.
{
"policy_id": "<policy-id>"
}
Agent Discovery (v0.7+)¶
Agents announce their capabilities to the Network Authority so peers can find them by capability tag rather than by hardcoded node public key. The registry is TTL-based; agents refresh on a periodic timer.
POST /agents¶
Register or refresh a signed AgentDescriptor. The descriptor is signed by
the registering node’s join-certificate key; the NA verifies the signature
against the public key embedded in the descriptor.
{
"agent_id": "llm-1",
"node_public_key": "<base64-ed25519-public-key>",
"network_name": "USG",
"capabilities": ["llm:chat", "llm:openai/gpt-4o-mini"],
"endpoint": {
"host": "127.0.0.1",
"port": 7448,
"scheme": "ws"
},
"registered_at": "<iso8601>",
"expires_at": "<iso8601>",
"metadata": {"model": "gpt-4o-mini"},
"signatures": [
{
"key_id": "<base64-ed25519-public-key>",
"sig": "<base64-ed25519-signature>"
}
]
}
Rejection conditions:
400— malformed descriptor, inverted expiry window, or wrongnetwork_name401— missing or invalid signature403— node has no active join certificate, or the key appears in the CRL429— rate-limited
Success response:
{
"status": "registered",
"expires_at": "<iso8601>"
}
GET /agents¶
Capability discovery. Expired entries are evicted before the query runs.
Pass capability to receive the matching descriptors. This is the peer
discovery operation and is public by design — a peer already knows the one
capability it is looking for.
GET /agents?capability=llm:chat
Without a capability filter the endpoint returns a count only and does not
enumerate the registry:
{ "count": 12, "capability": null }
Listing every registered agent and its capabilities would hand any caller a map of what the network can do and which key provides it.
Response:
{
"count": 1,
"capability": "llm:chat",
"agents": [
{
"agent_id": "llm-1",
"node_public_key": "<base64>",
"network_name": "USG",
"capabilities": ["llm:chat", "llm:openai/gpt-4o-mini"],
"endpoint": {"host": "127.0.0.1", "port": 7448, "scheme": "ws"},
"registered_at": "<iso8601>",
"expires_at": "<iso8601>",
"metadata": {"model": "gpt-4o-mini"},
"signatures": [{"key_id": "<base64>", "sig": "<base64>"}]
}
]
}
GET /agents/<node_public_key>¶
Returns the registration for a specific node key, or 404 if not registered.
DELETE /agents/<node_public_key>¶
Voluntary deregistration. Requires a signed delete envelope in the body:
{
"version": "v1",
"signed_at": "<iso8601, within ±5 minutes>",
"signature": "<base64 signature of 'delete-agent|v1|<node_public_key>|<signed_at>'>"
}
Returns 200 on success, 401 if the signature does not verify under the
node key, 404 if the agent is not currently registered.
Sovereign Trust Revocation (v0.11+)¶
Cross-sovereign revocation uses signed revocation feeds. The issuer sovereign publishes revoked membership-attestation IDs. An accepting sovereign verifies the feed under a recognized issuer key, imports it, and rejects matching attestations during treaty-backed verification.
GET /sovereign-revocation-feed¶
Returns the current signed SovereignRevocationFeed for the local sovereign.
The feed contains membership attestations revoked by this Network Authority.
Response:
{
"feed_id": "<uuid>",
"issuer_sovereign_id": "sovereign-b",
"sequence": 1,
"issued_at": "<iso8601>",
"revoked_attestation_ids": ["<attestation-id>"],
"revocation_reasons": {
"<attestation-id>": "key_compromise"
},
"issued_by": "<na-public-key>",
"signatures": [
{
"key_id": "<na-public-key>",
"sig": "<base64-signature>"
}
]
}
POST /admin/sovereign-revocation-feeds/import¶
Imports a signed revocation feed from another sovereign. The endpoint requires operator-key authentication.
Request:
{
"feed": {
"feed_id": "<uuid>",
"issuer_sovereign_id": "sovereign-b",
"sequence": 1,
"issued_at": "<iso8601>",
"revoked_attestation_ids": ["<attestation-id>"],
"revocation_reasons": {
"<attestation-id>": "key_compromise"
},
"issued_by": "<issuer-key-id>",
"signatures": [
{
"key_id": "<issuer-key-id>",
"sig": "<base64-signature>"
}
]
},
"issuer_public_keys": {
"<issuer-key-id>": "<base64-ed25519-public-key>"
}
}
If issuer_public_keys is omitted, the Network Authority attempts to verify
the feed using subject public keys from active recognition treaties for the
feed issuer.
Responses:
200when the feed is verified and imported400for malformed feeds or invalid signatures409for stale feed sequences
Connectome Operator View (v0.12+)¶
The Connectome endpoints derive operator-facing views from /recognition-graph.
They do not create a second trust source.
GET /recognition-graph¶
Exports the raw sovereign recognition graph:
sovereignsrecognition_edgesactive_treatiesrevoked_trust_material
GET /connectome.json¶
Returns a summarized Connectome view for dashboards and automation.
Response excerpt:
{
"summary": {
"sovereign_count": 2,
"recognition_edge_count": 1,
"active_edge_count": 1,
"revoked_edge_count": 0,
"revoked_trust_material_count": 1,
"imported_revocation_count": 1
},
"recognition_edges": [
{
"from": "sovereign-a",
"to": "sovereign-b",
"status": "active",
"treaty_id": "<treaty-id>"
}
],
"revocation_blast_radius": [
{
"type": "membership_attestation",
"issuer_sovereign_id": "sovereign-b",
"affected_accepting_sovereigns": ["sovereign-a"],
"reason": "key_compromise"
}
]
}
GET /connectome/trust-path¶
Explains current trust between two sovereigns.
GET /connectome/trust-path?from=sovereign-a&to=sovereign-b
Response:
{
"from": "sovereign-a",
"to": "sovereign-b",
"trusted": true,
"reason": "active_treaty_path",
"hop_count": 1,
"path": [
{
"from": "sovereign-a",
"to": "sovereign-b",
"status": "active",
"treaty_id": "<treaty-id>"
}
]
}
Missing from or to returns 400 with a controlled error.
GET /connectome¶
Renders a self-contained HTML operator page with summary cards, recognition edges, revoked trust material, and revocation blast-radius rows.