Pilot Deployment Profile¶
The supported shape for running a sovereign in a pilot. It is the v1
deployment profile of the Security Review for v1, made
concrete, and CI rehearses it on every change
(scripts/pilot_rehearsal.py, .github/workflows/pilot-readiness.yml).
A pilot run this way can produce the evidence that 1.0.0 does not claim: an
operator outside Genesis Core holding its own keys, infrastructure, policy
and revocation (see ops/plan-v1.0.0.md, Workstream 2).
Shape¶
Choice |
Profile |
|---|---|
Process |
|
Instances |
One instance on SQLite, or two or more on PostgreSQL with |
Network |
TLS terminated by the operator’s reverse proxy or load balancer; |
Signing key |
|
Operator keys |
Generated by the operator on its own machines. One privileged key per person who may change trust; standard keys for automation that only evaluates and records |
Governed workloads |
|
Clients |
The TypeScript SDK (full governed lifecycle), Go or .NET SDK, or raw HTTP |
Configuration¶
GENESIS_FILE=/config/genesis.signed.json
NA_KEY_ID=pilot-na-2026
NA_KEY_PROVIDER=azure-keyvault # or env, with NA_PRIVATE_KEY_SEED from the secret store
AZURE_KEY_VAULT_URL=https://<vault>.vault.azure.net
NA_KEY_SECRET_NAME=na-signing-seed
DATABASE_URL=postgresql://... # omit for a single SQLite instance (DB_PATH)
NA_HA_MODE=on # with PostgreSQL and two or more instances
OPERATOR_PUBLIC_KEYS_JSON='{"alice":"<base64>","ci":"<base64>"}'
OPERATOR_KEY_TIERS_JSON='{"alice":"privileged","ci":"standard"}'
BOUNDARY_POLICY_ENFORCEMENT=required
EVIDENCE_STORE=on
NA_PROXY_HOPS=1
All settings are in Configuration Reference. The database needs code-point (C) collation; see High Availability.
What the rehearsal proves¶
Every change runs this flow between two independently keyed sovereigns, each a gunicorn NA configured from the environment (one on SQLite, one in HA mode on PostgreSQL):
Each operator generates its own root, NA and operator keys; only public material crosses between sovereigns.
Sovereign A exports and validates B’s trust bundle, takes B’s key from B’s live
/sovereign.json, and issues a scoped treaty. A standard-tier key is refused.B attests a member; A accepts it under the treaty and rejects a role the treaty does not grant.
B revokes the member; A imports B’s signed feed and rejects the member. A replayed feed and a feed signed by another key are refused.
A’s database is backed up, restored into a new instance and verified with
na verify-db; the restored instance still holds the treaty and still rejects the revoked member.
The recovery drill (scripts/recovery_drill.py) does the same for
PostgreSQL: pg_dump, pg_restore into a new database after the original
is dropped, and a new instance verifying every record and decision.
Sizing and corporate networks¶
Rate limits are per client address. Each governed action makes one
/admin/boundary/evaluatecall and one evidence submission, and the admin limit defaults to 30 requests per minute. Behind a corporate proxy or NAT every client shares one address, and therefore one budget. RaiseNA_RATE_LIMIT_ADMIN_PER_MINUTE(andNA_RATE_LIMIT_EVIDENCE_PER_MINUTE) to the pilot’s peak, for example 600, and keepNA_PROXY_HOPScorrect so the limits apply to real client addresses.TLS-inspecting proxies. Where outbound TLS is re-signed by a corporate proxy (Zscaler and similar), clients must trust the proxy’s CA:
NODE_EXTRA_CA_CERTS=/path/to/proxy-ca.pemfor the TypeScript SDK. Python 3.13 and later also reject proxy CAs that do not mark their basic constraints critical; use the operating system’s trust store through thetruststorepackage for the CLI and Python clients, or run them from a network path without inspection.Memory. One VM with PostgreSQL, two NA instances of two workers and a reverse proxy uses about 750 MB; give it 2 GB, or 1 GB plus swap for tests.
Operations¶
Task |
How |
|---|---|
Back up |
SQLite: |
Restore |
Into a new database or file, then |
Upgrade |
Upgrade and Rollback: back up, upgrade, verify; rollback is a restore |
Readiness |
|
Revocation propagation |
Import partners’ feeds on a fixed schedule (RFC-007); the stale window is the import interval |
Audit |
|
Leaving |
Roles for the pilot¶
Fill these in before the pilot starts and keep them with the pilot’s runbook.
Role |
Responsibility |
Who |
|---|---|---|
Operator |
Holds the keys, decides recognition and revocation, runs the NA |
pilot operator |
Incident owner |
First response to a security or availability incident; follows Incident Response Runbooks |
to be named |
Release owner |
Ships a fix release (1.0.x) and confirms the upgrade path |
to be named |
Managing partner (if any) |
Assists within Managing Partner Control Boundary |
optional |
Limits¶
The NA signing key cannot yet be rotated while keeping the sovereign’s identity (security review SR-06). Keep it in Key Vault; a compromise means a new identity.
Imported revocation feeds have no enforced maximum age (SR-07); schedule imports to the pilot’s tolerance.
Mesh routing nodes, the Rust gateway and beta surfaces are outside the profile (see Public Contract).