Key material
- Peer registry, identities, initiator key, authorizer keys, passwords and the chain code were generated on a secure, ephemeral workstation that was wiped afterwards.
- Node private keys are encrypted at rest (
generate-identity --encrypt) and decrypted only in memory at start-up. - The initiator’s private key lives only with citadel-api; no node has a copy.
- Share-store passwords and identity passwords are in a secrets manager, never in
config.yaml, task definitions, environment variables, images or version control. - The chain code is stored with the same care as a password and is identical on every node.
- Backups of the share store, identity files and passwords exist, are tested by an actual restore, and are stored separately from the nodes.
Hosts and containers
- Nodes run as an unprivileged user (
citadel-coreon hosts, UID65532in containers) with a read-only root filesystem and all capabilities dropped. - The configuration directory is root-owned and read-only to the service; only the data directory is writable.
- On hosts, the systemd unit keeps
NoNewPrivileges,ProtectSystem,ProtectHome,PrivateTmpand the system-call filter from the unit Blockops provides. - Nodes run on infrastructure with no public IP address, in private subnets or an isolated namespace.
- Storage holding the share store is encrypted at rest at the platform level as well (EFS encryption, encrypted persistent volumes, disk encryption on hosts).
Network
- Egress from nodes is limited to NATS, Consul, and (on ECS) S3, Secrets Manager and ECR through VPC endpoints.
- Ingress to nodes is limited to the other nodes (and the health port from the orchestrator).
- NATS uses TLS with client certificates and credentials;
environment: productionis set so the node refuses to connect otherwise. - Consul ACLs are enabled and the nodes’ token can read and write only the peer registry.
Operations
- Exactly one instance of each node runs at a time (
desired_count = 1on ECS; a StatefulSet on Kubernetes). - Logs are retained centrally with a retention period set, and the
--debugflag is off. - Health checks are wired to readiness, not liveness.
- Upgrades are applied one node at a time and never take the cluster below threshold.
- Access to hosts, the cluster and the cloud account is restricted, logged and reviewed: an operator who can read a node’s memory and its password can extract a share.
- The resharing and node-replacement procedures in Operate a cluster have been rehearsed.

