Platform

Overview

How It Works

Beneficiary Identity

Policy Corridors

Deterministic Finality

Architecture

Security Model

Governance

Integration

Solutions

Corridors Overview

Institutional Overview

Pricing

All Scenarios

Humanitarian Impact Fund

Assurance

Technical Assurance

Verify Receipt

Receipt Example

Developers

Documentation

APIs & Bridges

Architecture Docs

Glossary

BID API

Company

About

Team

Partners

Roadmap

Investors

Contact

Blog

All Documentation

Schedule Consultation
Security Specification

Secure Boot from Zero

Minimal footprint validator provisioning. A freshly provisioned server receives only Docker, the agent container, and one API key. No secrets, no configs, no application code. Zero-trust onboarding with encrypted secret delivery and a 10-phase hard-fail verification sequence.

10 Hard-Fail Phases
0 Secrets on Disk at Boot
NaCl Secretbox Encryption
24h Consensus Authorization
The Problem

The previous bootstrap model writes all secrets to .env before the agent even contacts JILHQ.

The provisioning script generates passwords, JWT secrets, Redis credentials, MPC encryption keys, and killswitch secrets - then writes them all as plaintext environment variables directly to disk. The agent only authenticates with JILHQ after Docker Compose starts, meaning there is a window between server creation and successful handshake where every secret sits unencrypted on the filesystem.

Attack Surface:

If the server is compromised before boot completes - via a supply chain attack on the hosting provider, a malicious SSH key, a rogue base image, or even a timing attack during provisioning - the attacker gets everything in plaintext: database passwords, JWT signing keys, MPC encryption material, and consensus credentials. There is no recovery path short of rotating every secret across the entire fleet.

The old model treats provisioning as a trusted phase. Secure Boot from Zero treats provisioning as adversarial by default: the server is untrusted until it proves its identity, receives encrypted secrets, and passes every verification gate.

The Solution

Identity-only bootstrap. Encrypted secret delivery. 10-phase hard-fail verification.

A freshly provisioned server receives only Docker, the agent container, and one API key (its identity credential). No secrets, no configs, no application code, no database passwords. The bootstrap .env contains nothing that would be valuable to an attacker - just enough information for the agent to identify itself and contact JILHQ.

The agent boots, authenticates with JILHQ by proving possession of its API key (via SHA256 hash - the key never crosses the wire), receives approval, and then gets all secrets delivered encrypted with NaCl secretbox (xsalsa20-poly1305). Only after decrypting and verifying integrity does the agent proceed through the remaining verification phases. Every single phase is a hard-fail gate: if any phase fails, the boot sequence halts immediately and no services start.

Zero-Knowledge Bootstrap:

At boot time, the server knows nothing except who it is (NODE_ID) and where to call home (JILHQ_URL). All operational secrets - database passwords, JWT keys, MPC material, signing keys - arrive encrypted after identity verification. A compromised server at boot time yields zero usable credentials.

Bootstrap Configuration

Minimal Bootstrap .env

The bootstrap .env file contains only identity and connectivity variables. Compare the old approach (20+ secrets in plaintext) with the new minimal footprint.

Old Approach - Full .env at Boot

NODE_ID=jil-validator-de
ZONE_ID=DE_BAFIN
AUTHORIZED_ZONES=DE_BAFIN
EXTERNAL_IP=46.225.116.22
JILHQ_URL=https://hq.jilsovereign.com
JIL_API_KEY=hq_ak_...
POSTGRES_PASSWORD=f8a3...9c1e
REDIS_PASSWORD=r3d1...s7k2
JWT_SECRET=jwt_...x9f2
JILHQ_SHARED_SECRET=hmac_...k8p1
MPC_ENCRYPTION_KEY=mpc_...t4w7
KILLSWITCH_SECRET=kill_...m2n5
PROOFLAYER_SIGNING_KEY=proof_...v3b8
LBP_SECRET=lbp_...q6j4
RAMPS_SECRET=ramps_...d1c9
ADMIN_KEY=admin_...h5e3
+ 10 more secrets...
20+ secrets written to disk before agent even starts

New Approach - Identity-Only .env

NODE_ID=jil-validator-de
ZONE_ID=DE_BAFIN
AUTHORIZED_ZONES=DE_BAFIN
EXTERNAL_IP=46.225.116.22
JILHQ_URL=https://hq.jilsovereign.com
REGISTRY_URL=167.235.150.16:5000
PULL_MODE=true
PORT=8055
JIL_API_KEY=hq_ak_...
# That's it.
# No passwords.
# No JWT secrets.
# No MPC keys.
# No signing material.
# Secrets arrive encrypted
# after identity verification.
0 secrets on disk - only identity credentials
Variable Example Purpose Sensitive?
NODE_IDjil-validator-deUnique node identifier in JILHQ registryNo
ZONE_IDDE_BAFINPrimary compliance zone assignmentNo
AUTHORIZED_ZONESDE_BAFINComma-separated zones this node can processNo
EXTERNAL_IP46.225.116.22Public IP for peer discovery and DNSNo
JILHQ_URLhttps://hq.jilsovereign.comFleet management server endpointNo
REGISTRY_URL167.235.150.16:5000JILHQ Docker image registryNo
PULL_MODEtrueEnables pull-based provisioning with HQNo
PORT8055Agent HTTP listener portNo
JIL_API_KEYhq_ak_...Identity credential for HQ authenticationLow*
*Note on API key sensitivity:

The API key is an identity credential, not an operational secret. It proves the node's identity to JILHQ but cannot be used to access databases, sign transactions, decrypt MPC shares, or perform any privileged operation. Even if leaked, an attacker cannot bootstrap a rogue validator without also passing image digest verification, key challenge-response, and obtaining a time-limited authorization token from JILHQ.

Boot Sequence

10-Phase Secure Boot Sequence

Every phase is a hard-fail gate. If any phase returns an error, the entire boot sequence halts immediately. No services start. No containers launch. The agent reports the failure to JILHQ and enters a dormant retry loop.

Phase 1

AUTHENTICATE - Handshake

The agent sends a POST /v1/fleet/handshake request to JILHQ containing its NODE_ID, ZONE_ID, EXTERNAL_IP, software version, and a SHA256 hash of its API key. JILHQ looks up the node in its registry, verifies the API key hash against the stored (encrypted) key, and returns an approved or rejected status.

Failure mode: Node not found in registry, API key hash mismatch, or node marked as decommissioned. Agent enters 60-second retry loop (max 10 attempts).

Phase 2

FETCH SECRETS - Encrypted Delivery

After authentication, the agent requests its operational secrets via POST /v1/fleet/secrets/:nodeId. The request body contains SHA256(api_key) to prove identity without transmitting the key itself. JILHQ encrypts the full secrets payload using NaCl secretbox (xsalsa20-poly1305) with a symmetric key derived from the API key bytes.

Failure mode: Hash mismatch (identity unproven), decryption failure (key derivation mismatch), or integrity hash mismatch (payload tampered). Agent halts immediately.

Phase 3

REGISTRY AUTH - Docker Login

JILHQ provides registry credentials for the Docker image registry at 167.235.150.16:5000. The agent configures Docker login with the credential. The credential is short-lived.

Failure mode: Registry authentication rejected, credential expired, or Docker daemon unavailable. Agent halts.

Phase 4

FETCH CONFIG - Signed Bundle

The agent fetches its configuration bundle from GET /v1/registry/config/:nodeId. The bundle contains docker-compose.yml, zone-specific policies, validator configuration (validator.toml), and environment variable templates. The entire bundle is HMAC-signed by JILHQ.

Failure mode: HMAC signature mismatch (possible MITM or config tampering), bundle parsing failure, or missing required config keys. Agent halts.

Phase 5

PULL IMAGES - Download from Manifest

Using the authenticated Docker session from Phase 3, the agent pulls every container image listed in the configuration manifest. For full nodes this is 17 images; for compact nodes, 14 images. The pull is all-or-nothing: if any single image fails to download, the entire boot halts.

Failure mode: Network timeout, registry unavailable, image not found, or disk space exhausted. Agent halts and reports which image(s) failed.

Phase 6

VERIFY DIGESTS - SHA256 Hard-Fail

After pulling all images, the agent fetches the pinned digest manifest from GET /v1/registry/images/digests. The agent computes the local digest of each pulled image and compares it against the pinned value. Every single digest must match exactly. A single mismatch means the pulled image is not the same binary that JILHQ approved.

Failure mode: Any image digest mismatch. Agent halts immediately, reports the mismatched image(s) to JILHQ, and refuses to start any containers. HARD FAIL with no override.

Phase 7

VERIFY KEYS - Ed25519 Challenge-Response

JILHQ issues a cryptographic challenge to the agent via POST /v1/fleet/verify-keys. The challenge is a random 32-byte nonce. The agent must sign this nonce with each of its 5 registered key types (ed25519_consensus, hmac_shared, api_key, ssh_keypair, hsm_signing) and return the signatures. JILHQ verifies each signature against the public keys stored in the hq_node_keys table.

Failure mode: Any key type fails verification. Agent halts. A compromised or cloned node cannot pass this gate. HARD FAIL.

Phase 8

GET AUTH TOKEN - 24h Consensus Authorization

After passing all verification gates, the agent requests a consensus authorization token from POST /v1/fleet/authorize-consensus. JILHQ verifies that all previous phases passed, checks that the node is not suspended or decommissioned, and issues a time-limited token valid for 24 hours.

Failure mode: JILHQ refuses authorization (node suspended, quorum policy violation, or manual hold). Agent halts - will not start services without consensus authorization.

Phase 9

START SERVICES - Docker Compose Up

With secrets decrypted, config verified, images verified, keys proven, and authorization obtained, the agent writes the final .env (combining bootstrap variables + decrypted secrets), writes the verified docker-compose.yml, and executes docker compose up -d. The agent monitors container startup and waits for all services to report healthy status.

Failure mode: Docker Compose returns non-zero exit, any container exits unexpectedly, or health checks fail after 120-second timeout. Agent runs docker compose down and halts.

Phase 10

COMPLETE - Handshake Complete

The agent sends POST /v1/fleet/handshake/complete to JILHQ, reporting successful boot with a manifest of running containers, their versions, health status, and the time elapsed for each phase. JILHQ marks the node as consensus-ready in its registry and includes the node in quorum calculations.

Failure mode: Completion handshake rejected (rare - indicates state inconsistency). Agent continues running but JILHQ does not mark node as consensus-ready until manually resolved.

Cryptographic Protocol

Encrypted Secret Delivery

The secret delivery protocol ensures that operational secrets never cross the wire in plaintext and that only the intended recipient can decrypt them. The encryption is end-to-end: JILHQ encrypts on its side, the agent decrypts on its side, and the shared key is derived from material that both parties already possess (the API key).

Protocol Flow:

1. Agent sends POST /v1/fleet/secrets/:nodeId with body { "apiKeyHash": SHA256(api_key) }
2. JILHQ looks up node, decrypts stored API key using MASTER_ENCRYPTION_KEY (AES-256-GCM)
3. JILHQ verifies SHA256(decrypted_api_key) === request.apiKeyHash - proves identity without the agent transmitting the key
4. JILHQ derives symmetric key: HMAC-SHA256(api_key_bytes, "jil-secrets-v1") - first 32 bytes used as NaCl secretbox key
5. JILHQ assembles secrets JSON, computes SHA256(secrets_json) as integrity hash
6. JILHQ encrypts secrets JSON with xsalsa20-poly1305 (NaCl secretbox) using derived key + random 24-byte nonce
7. Response: { "encrypted": base64(nonce + ciphertext), "integrityHash": sha256_hex }
8. Agent derives same symmetric key locally: HMAC-SHA256(api_key_bytes, "jil-secrets-v1")
9. Agent extracts nonce (first 24 bytes), decrypts ciphertext with NaCl secretbox
10. Agent verifies SHA256(decrypted_json) === response.integrityHash
11. Agent parses secrets JSON and holds values in memory only (never written to disk as separate file)

Why NaCl Secretbox?

NaCl secretbox (xsalsa20-poly1305) provides authenticated encryption: the ciphertext includes a MAC that prevents any modification without detection. Combined with the SHA256 integrity hash over the plaintext, this gives two independent layers of tamper detection. The 24-byte nonce ensures that even if the same secrets are delivered twice, the ciphertext is completely different. xsalsa20-poly1305 is also constant-time, preventing timing side-channels during decryption.

Delivered Secrets
Secret Purpose Used By
POSTGRES_PASSWORDPostgreSQL database authenticationAll DB-connected services
REDIS_PASSWORDRedis cache authenticationcompliance-api, fraud-firewall, others
JWT_SECRETJWT token signing and verificationwallet-api, settlement-api, others
JILHQ_SHARED_SECRETHMAC signing for HQ-agent communicationvalidator-update-agent
MPC_ENCRYPTION_KEYMPC shard encryption at restmpc-cosigner
KILLSWITCH_SECRETEmergency pause authorizationconsent-killswitch
PROOFLAYER_SIGNING_KEYProof layer attestation signingproof-verifier
LBP_SECRETLaunchpad backend signinglaunchpad-api
RAMPS_SECRETFiat on/off ramp authenticationramps-api
ADMIN_KEYAdministrative API authenticationsettlement-api admin routes
VALIDATOR_NAMEHuman-readable validator display nameexplorer-api, dashboard
PG_POOL_MAXPostgreSQL connection pool sizeAll DB-connected services
ZONE_IDVerified zone assignment (may differ from bootstrap)settlement-consumer, compliance-api
AUTHORIZED_ZONESVerified zone list (authoritative from HQ)settlement-consumer
Enforcement Model

Hard-Fail Enforcement

The previous boot model used soft-fail behavior: if a verification step failed, the agent would log a warning and continue anyway. This was pragmatic for early development but unacceptable for production. Secure Boot from Zero enforces hard-fail on every gate - a single failure stops the entire boot sequence.

Check Old Behavior SOFT FAIL New Behavior HARD FAIL
Bundle signature mismatch Warning logged, config applied anyway ABORT - possible MITM or config tampering detected
Image digest mismatch Warning logged, container started anyway ABORT - unverified images will not be executed
Key verification failed Warning logged, degraded authentication mode ABORT - cannot prove key ownership, node may be cloned
Image pull failure Warning logged, missing containers skipped ABORT - cannot run without all required images
Auth token refused Skipped, services started without consensus auth ABORT - not authorized for consensus participation
Docker Compose failure Error logged, partial service set tolerated ABORT - all containers torn down, no partial state
Secret decryption failure N/A (secrets were on disk) ABORT - cannot operate without credentials
Integrity hash mismatch N/A (no integrity verification) ABORT - secret payload may be corrupted or tampered
Design principle:

It is always better to refuse to start than to start in an unverified state. A validator that does not boot is safe. A validator that boots with tampered images or unproven keys is a threat to the entire network. Hard-fail enforcement ensures that the network never admits a node that has not passed every single verification gate.

Security Guarantees

Security Properties

The Secure Boot from Zero protocol provides the following security guarantees.

Property Mechanism
No secrets on disk at boot Bootstrap .env contains only identity credentials (NODE_ID, ZONE_ID, JIL_API_KEY). All operational secrets delivered encrypted after authentication.
Encrypted secret delivery NaCl secretbox (xsalsa20-poly1305) with HMAC-SHA256 derived symmetric key. Random 24-byte nonce per request. Authenticated encryption prevents undetected modification.
Identity verification Agent sends SHA256(api_key) to prove identity without transmitting the key. JILHQ decrypts stored key and verifies hash match. Key never crosses the wire.
Code integrity Every pulled Docker image digest is compared against SHA256 digests pinned by JILHQ at build time. Any mismatch halts boot immediately.
Key ownership Ed25519 challenge-response across all 5 key types. Agent must sign a random nonce with each key. JILHQ verifies against registered public keys.
Authorization gate 24-hour time-limited consensus token issued only after ALL verification phases pass. Token must be renewed before expiry. Revocable by JILHQ at any time.
Hard-fail enforcement ANY failed phase halts the boot sequence. No services start. No partial state. No degraded mode. The agent enters a dormant retry loop.
Ephemeral registry credential JILHQ registry credential used for Docker login, short-lived. Credential does not persist on filesystem.
Audit trail Every phase transition logged with timestamp, duration, and result. Failures reported to JILHQ via handshake status update. Full history queryable via /v1/fleet/control/:nodeId/history.
Rate limiting Maximum 3 secret delivery requests per node per hour. Prevents brute-force attempts against the secret delivery endpoint. Exceeded requests return 429.
Migration

Backwards Compatibility

Secure Boot from Zero is fully backwards-compatible with existing validators. No migration or downtime is required for the current fleet. The system detects the provisioning model at startup and adapts automatically.

📁

Legacy Nodes (PULL_MODE=false)

Validators provisioned with the old model already have all secrets on disk. These nodes skip the entire Secure Boot sequence and start services directly using docker compose up with their local configuration. They continue to register with JILHQ via the standard handshake but do not go through Phases 2-8.

🔄

Hybrid Nodes (PULL_MODE=true, secrets on disk)

Validators that have PULL_MODE=true but already have secrets written will detect that secrets are already present and skip Phases 2-3 (secret delivery and registry auth). They will still go through Phases 4-10 (config fetch, image pull, digest verification, key verification, authorization, service start, completion).

New Nodes (Minimal .env + PULL_MODE=true)

Freshly provisioned validators with the minimal bootstrap .env go through the complete 10-phase sequence. This is the recommended provisioning model for all new validators going forward.

Scenario Phases Executed Notes
PULL_MODE=false (legacy) 1, 10 only Handshake + completion. Services start from local config.
PULL_MODE=true, secrets on disk 1, 4, 5, 6, 7, 8, 9, 10 Skips Phases 2-3. Full verification of config, images, and keys.
PULL_MODE=true, no secrets (new) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 Complete 10-phase Secure Boot. Recommended for all new nodes.
Migration path:

Existing validators can be upgraded to the Secure Boot model by rotating their secrets through JILHQ, removing plaintext secrets from .env, and rebooting the agent. The next boot will trigger the full 10-phase sequence. This can be done on a rolling basis without affecting network quorum.

API Reference

API Endpoints

All endpoints are served by JILHQ on port 8054. Authentication is via JIL_API_KEY header or HMAC signature depending on the endpoint. All responses are JSON.

Endpoint Method Phase Purpose
/v1/fleet/handshake POST 1 Agent authentication - proves identity via API key hash, receives approved/rejected status
/v1/fleet/secrets/:nodeId POST 2 Encrypted secret delivery - NaCl secretbox encrypted payload with integrity hash
/v1/registry/config/:nodeId GET 4 Signed configuration bundle - docker-compose.yml, policies, validator.toml, HMAC signature
/v1/registry/images/digests GET 6 Pinned image digests - SHA256 for every approved container image
/v1/fleet/verify-keys POST 7a Issue key verification challenge - random 32-byte nonce for all 5 key types
/v1/fleet/verify-keys/response POST 7b Verify challenge response - agent submits signatures, JILHQ verifies against registered public keys
/v1/fleet/authorize-consensus POST 8 Issue 24h consensus authorization token - required for validator to participate in consensus
/v1/fleet/handshake/complete POST 10 Boot completion - agent reports running containers, versions, health status, phase timings
Rate Limits
Endpoint Rate Limit Window Rationale
/v1/fleet/secrets/:nodeId3 requests1 hourPrevents brute-force secret extraction
/v1/fleet/handshake10 requests10 minutesAllows retry loop during boot
/v1/fleet/verify-keys5 requests1 hourPrevents challenge flooding
/v1/fleet/authorize-consensus3 requests1 hourToken issued once per boot cycle
Validator Security

Zero secrets on disk. 10 hard-fail gates. Every validator verified before it serves a single request.

Secure Boot from Zero ensures that no validator joins the JIL network without proving its identity, verifying its code integrity, and obtaining cryptographic authorization from JILHQ.