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
Part I - JILHQ (Dedicated Server)

1. Source Files

JILHQ runs on a dedicated Hetzner CPX52 server at 167.235.150.16 (hq.jilsovereign.com) and serves as the fleet management server. It registers images, signs digests, and orchestrates distribution to all validators.

FilePurpose
services/jilhq/src/index.tsMain Express server (~3200 lines). Distribution endpoints, agent registration, dynamic endpoint lookup
services/jilhq/migrations/009_distribution_jobs.sqlCreates hq_distribution_jobs table
deploy/hetzner/docker-compose.hq.ymlJILHQ service config, SIGNING_SECRET env var
deploy-to-hetzner.shAdded --distribute flag, JILHQ_URL/LOCAL_REGISTRY vars, distribution step [5/5]

2. Database Tables

18 tables across 9 migrations, all residing in JILHQ's PostgreSQL instance (jil-postgres).

#TableMigrationPurpose
1hq_nodes001 (+007,+008)Fleet node registry with agent URLs
2hq_images001Container image registry with signatures
3hq_promotions001Image track promotions (devnet→testnet→mainnet)
4hq_certs001mTLS certificate management
5hq_audit_log001Immutable audit ledger
6hq_configs001Fleet configuration push per jurisdiction
7hq_alert_rules002Alert rule definitions
8hq_alerts002Fired alert instances
9hq_validator_keys003Validator signing key registry
10hq_image_deployments003Per-node image deployment tracking
11hq_auth_decisions003Authorization decision log
12hq_quorum_config004Per-zone quorum configuration
13hq_consensus_rounds005 (+008)Settlement consensus rounds
14hq_consensus_signatures005 (+006)Per-validator consensus signatures
15hq_validator_ed25519_keys006Ed25519 key registry
16hq_equivocation_evidence007Double-signing evidence
17hq_validator_heartbeats008Heartbeat history
18hq_distribution_jobs009Image distribution job tracking
Key distribution tables: hq_nodes (stores agent_url in metadata), hq_images (signed digests), hq_image_deployments (per-node status), hq_distribution_jobs (job tracking), hq_audit_log (all actions logged).

3. REST Endpoints

Distribution Endpoints (new)

MethodPathPurpose
POST/v1/fleet/distributeDistribute signed image to validators
GET/v1/fleet/distribute/:jobIdPoll distribution job status
GET/v1/fleet/distributionsList recent distribution jobs (limit 50)
POST/v1/fleet/nodes/:nodeId/register-agentRegister/update a validator's agent URL
GET/v1/fleet/agentsList all registered agent endpoints

Image Registry Endpoints (existing)

MethodPathPurpose
GET/v1/registry/imagesList all images (filter by ?track=)
POST/v1/registry/imagesRegister new image with digest
POST/v1/registry/images/:name/signSign image digest (HMAC-SHA256)
POST/v1/registry/images/:name/verifyVerify image signature
POST/v1/registry/images/:name/promotePromote devnet→testnet→mainnet

Fleet Endpoints (existing)

MethodPathPurpose
POST/v1/fleet/push-imageRecord deployment intent
POST/v1/fleet/nodes/:nodeId/verify-deploymentVerify running digest matches signed
GET/v1/fleet/deploymentsDeployment status across all nodes

4. Environment Variables

VariableDefaultPurpose
PORT8054HTTP listen port
DATABASE_URLpostgres://jil:jil@jil-postgres:5432/jilPostgreSQL connection
SIGNING_SECRETdevnet-hq-signing-secretHMAC key for signing image digests + distribute payloads
SIGNING_KEY_IDjilhq-signing-key-01Key identifier recorded in signed images
PG_POOL_MAX20PostgreSQL connection pool size

5. HMAC Signing Functions

signDigest - Image Signing

function signDigest(digest: string): { signature: string; algorithm: string; signedBy: string } // HMAC-SHA256 over image digest using SIGNING_SECRET // Returns base64 signature, used by POST /v1/registry/images/:name/sign

signDistributePayload - Distribution Signing

function signDistributePayload(image, tag, digest, timestamp): string // HMAC-SHA256 over JSON.stringify({ image, tag, digest, timestamp }) // Sent to validators with each pull command

verifySignature - Image Verification

function verifySignature(digest: string, signature: string): boolean // Recomputes HMAC-SHA256 and compares against stored signature // Used by POST /v1/registry/images/:name/verify and verify-deployment

6. Image Registry

JILHQ Registry

PropertyValue
Registry167.235.150.16:5000
TypeDocker Registry v2 (self-hosted on dedicated JILHQ server)
AuthHMAC-signed pull commands from JILHQ
SecurityJILHQ pins sha256 digests; validators verify after pull
Architecture decision: Validators pull from the JILHQ registry (167.235.150.16:5000), a self-hosted Docker Registry v2 on the dedicated JILHQ server. JILHQ pins sha256 digests for every image. After pulling, the validator-update-agent verifies all pulled image digests match JILHQ's pinned manifest. If any digest mismatches (e.g., tampered image), the agent refuses to deploy and reports the mismatch.

7. Distribution Pipeline

Triggered by deploy-to-hetzner.sh --distribute

Step 1: docker build on DevNet (Hetzner portal) Step 2: docker save | ssh docker load to portal server Step 3: POST /v1/registry/release → Register + sign + pin digest in JILHQ Step 4: JILHQ sends refresh command to target validators → For each node: → Agent pulls from JILHQ registry (167.235.150.16:5000) → Agent verifies sha256 digests against JILHQ pinned manifest → On match: docker compose up -d (deploy) → On mismatch: REFUSE to deploy, report failure
Part II - Validators (Hetzner TestNet)

1. Source Files

The validator-update-agent is a lightweight sidecar running on each Hetzner validator (port 8055). It receives HMAC-signed pull commands from JILHQ, pulls images from the JILHQ registry, restarts containers, and reports back.

FilePurpose
services/validator-update-agent/src/index.tsExpress server: HMAC-verified pull+restart, self-registration, Docker API via dockerode
services/validator-update-agent/package.jsonDependencies: express, pino, pino-pretty, dockerode
services/validator-update-agent/tsconfig.jsonTypeScript config (ES2022, commonjs, strict)
services/validator-update-agent/DockerfileMulti-stage build (node:20-alpine), exposes 8055
deploy/hetzner/docker-compose.validator.ymlAdded validator-update-agent sidecar with Docker socket mount

2. REST Endpoints

MethodPathAuthPurpose
POST/v1/pullHMAC-SHA256Pull image from registry, restart container
GET/v1/statusNoneList all running containers with digests
GET/healthNoneHealth check (Docker connectivity)

POST /v1/pull Flow

  1. Verify HMAC signature against shared secret
  2. Check timestamp is within 5-minute replay window
  3. docker pull 167.235.150.16:5000/<image>:<tag>
  4. Verify pulled digest matches signed digest
  5. Find running container using that image
  6. Skip if container is validator-update-agent (self-restart prevention)
  7. docker stopdocker removedocker createdocker start
  8. Report back to JILHQ via POST /v1/fleet/nodes/:nodeId/verify-deployment

3. Environment Variables

VariableDefaultPurpose
PORT8055HTTP listen port
NODE_IDnode-primaryThis validator's identifier
JILHQ_URLhttps://hq.jilsovereign.comJILHQ endpoint via Cloudflare (registration + verification)
JILHQ_SHARED_SECRET(production secret)HMAC shared secret (must match JILHQ SIGNING_SECRET)
REGISTRY_URL167.235.150.16:5000JILHQ Registry (image source)
EXTERNAL_IP127.0.0.1This node's external IP (for self-registration URL)
AGENT_URLhttp://${EXTERNAL_IP}:${PORT}Override: full agent URL reported to JILHQ

4. HMAC Verification Functions

verifyHmac - Pull Verification

function verifyHmac(payload: Record<string, unknown>, signature: string): boolean // HMAC-SHA256 over JSON.stringify({ image, tag, digest, timestamp }) // Uses crypto.timingSafeEqual for constant-time comparison (no timing attacks)

checkTimestamp - Replay Protection

function checkTimestamp(timestamp: string): boolean // Rejects requests with timestamp > 5 minutes from now // REPLAY_WINDOW_MS = 300000 (5 min)

5. Docker Service

PropertyValue
Image167.235.150.16:5000/validator-update-agent:latest
Containervalidator-update-agent
Port8055:8055
Volume/var/run/docker.sock:/var/run/docker.sock
Memory128M
Networkjil-network
Restartunless-stopped

6. Firewall & Network Config

iptables/ufw Rules (port 8055)

iptables -I INPUT -p tcp --dport 8055 -s 46.225.232.55 -j ACCEPT ufw allow from 46.225.232.55 to any port 8055 proto tcp

Applied on all 10 Hetzner validators. Only portal IP (46.225.232.55) and JILHQ IP (167.235.150.16) can reach port 8055.

JILHQ Access

// All validators reach JILHQ via Cloudflare: JILHQ_URL=https://hq.jilsovereign.com // Cloudflare Worker routes to Hetzner JILHQ origin (167.235.150.16)

Cloudflare routing provides TLS termination and CDN for JILHQ access.

7. Self-Registration Flow

  1. Agent starts on validator → listens on :8055
  2. After 3 seconds, calls POST ${JILHQ_URL}/v1/fleet/nodes/${NODE_ID}/register-agent
  3. JILHQ upserts hq_nodes.metadata.agent_url (auto-creates node if not exists)
  4. Every 5 minutes, re-registers to keep endpoint fresh
  5. Distribution reads metadata->>'agent_url' from hq_nodes - no hardcoded IPs
Part III - Audit & Verification

1. Security Controls Audit

Authentication & Authorization

ControlImplementationLocationStatus
Image signingHMAC-SHA256 over digestjilhq signDigest()Active
Distribution payload signingHMAC-SHA256 over {image, tag, digest, timestamp}jilhq signDistributePayload()Active
Pull command verificationHMAC-SHA256 with timingSafeEqualvalidator-update-agentActive
Replay protection5-minute timestamp windowvalidator-update-agentActive
Shared secretSIGNING_SECRET / JILHQ_SHARED_SECRET must matchBoth servicesRequired
Image must be signed before distributionChecked in POST /v1/fleet/distributejilhqEnforced
Self-restart preventionAgent skips its own containervalidator-update-agentActive

Network Access Controls

RuleSourceDestinationPortProtocol
Hetzner iptablesPortal IP (46.225.232.55)Validator8055TCP
Cloudflare routingAll validatorshq.jilsovereign.com443HTTPS

Data Integrity

CheckWhereHow
Digest verification after pullvalidator-update-agentCompare pulled RepoDigests against signed digest
Deployment verification callbackagent → jilhqPOST /v1/fleet/nodes/:nodeId/verify-deployment
Signature verification on verify-deploymentjilhqRecomputes HMAC and compares to stored
Audit log on every actionjilhq hq_audit_logAll distribute, sign, register actions logged

Container Security

ControlServiceSetting
Read-only filesystemjilhq (HQ compose)read_only: true
No privilege escalationjilhq (HQ compose)security_opt: [no-new-privileges:true]
Memory limitsAll servicesjilhq: 256M, agent: 128M
Docker socket accessvalidator-update-agent only/var/run/docker.sock mount

2. Code Completeness Checklist

JILHQ

Validators

3. Currently Deployed State

ComponentLocationIP:PortStatus
JILHQ RegistryHetzner167.235.150.16:5000Active
jilhqHetznerhq.jilsovereign.com (167.235.150.16)Healthy
validator-update-agentjil-mainnet-genesis46.225.160.152:8055Registered
validator-update-agentjil-validator-us5.78.117.94:8055Registered
validator-update-agentjil-validator-de46.225.116.22:8055Registered
validator-update-agentjil-validator-eu95.216.146.199:8055Registered
validator-update-agentjil-validator-sg5.223.74.49:8055Registered
validator-update-agentjil-validator-ch46.225.87.88:8055Registered
validator-update-agentjil-validator-jp5.223.49.244:8055Registered
validator-update-agentjil-validator-gb95.217.14.159:8055Registered
validator-update-agentjil-validator-ae91.98.193.101:8055Registered
validator-update-agentjil-validator-br46.224.81.203:8055Registered

4. Key Constants

ConstantValueLocationPurpose
REPLAY_WINDOW_MS300000 (5 min)validator-update-agentTimestamp replay protection
Distribution timeout30000 (30s)jilhq distributePer-node pull timeout
Re-registration interval300000 (5 min)validator-update-agentSelf-registration refresh
Registration delay3000 (3s)validator-update-agentStartup delay before first registration
Container stop timeout10svalidator-update-agentGraceful stop timeout

5. Deployment Verification Commands

# 1. JILHQ is healthy (via Cloudflare) curl -s https://hq.jilsovereign.com/health # Expected: {"status":"healthy","service":"jilhq",...} # 2. HMAC auth enforced on read endpoints (no auth = 401) curl -s https://hq.jilsovereign.com/v1/registry/image-manifest # Expected: 401 {"error":"HMAC authentication required"} # 3. Admin auth enforced on write endpoints (no key = 401) curl -s -X POST https://hq.jilsovereign.com/v1/registry/release -H "Content-Type: application/json" -d '{}' # Expected: 401 {"error":"Admin API key required"} # 4. All agents registered (requires admin API key) curl -s https://hq.jilsovereign.com/v1/fleet/nodes -H "x-api-key: ${HQ_ADMIN_API_KEY}" # Expected: 10 healthy mainnet validators # 5. Agent health on each validator for IP in 46.225.160.152 5.78.117.94 46.225.116.22 95.216.146.199 5.223.74.49 \ 46.225.87.88 5.223.49.244 95.217.14.159 91.98.193.101 46.224.81.203; do curl -s http://$IP:8055/health done # Expected: {"status":"ok","docker":"connected"} for each # 5. End-to-end test ./deploy-to-hetzner.sh --service settlement-api --distribute # Expected: image built, pushed, registered, signed, distributed