Skip to main content

Client installation guide

Audience: the PSP's infrastructure or platform engineer who installs the Hokeka Edge Node on their own servers.

What you are installing. A fraud and AML decisioning node that runs inside your estate. It is the only component that evaluates your transactions. Your API nodes call it over TLS, and it answers ALLOW / ALERT / HOLD / BLOCK in line with the authorisation. It has two local databases that only the engine can reach:

  • the Edge Ledger (PostgreSQL 16): every evaluation, the decision-record outbox, legal holds and audit tables. It is your system of record for transaction data;
  • Aerospike: card history and compliance counters (hourly buckets with a 50 h TTL, daily buckets with a 32-day TTL, card profiles with an 800-day TTL, device and IP profiles with a 400-day TTL) and the active rule bundle (edge-host/.../store/AerospikeFeatureStore.java).

What leaves your network. All traffic is outbound on TCP 443, inside mTLS, opened by the Edge:

  • decision records, one per evaluation: IDs, action, score, rule IDs and compliance flags. No PAN, card hash, amount, currency, country, names or feature values;
  • aggregate metrics, every 60 s (EDGE_METRICS_INTERVAL);
  • the signed rule bundle, pulled down.

The full field-by-field rules are in EDGE_DATA_RESIDENCY_CONTRACT.md §2.

There is no exception. The former Hokeka AI recommendation request, which sent the evaluation's feature values for ALERT and HOLD decisions, was removed in R10c.

Also built (status: work package table):

  • Edge Tunnel (R5). The Edge opens an outbound WebSocket (WSS, TCP 443, mTLS) to edge.hokeka.com. The Console uses it to read transaction details live from your ledger, and each read is audited on both sides (Edge edge_access_log, cloud data access log). You do not need to open any port for it.
  • Edge config and purge (R2). The Edge pulls your retention and other settings from the sealed Edge config document and purges ledger data older than your retention period daily, skipping data under legal hold.

The client documentation set​

DocumentCovers
This guideRequirements, sizing, network, installation, verification, hardening, upgrades
edge-transaction-evaluation.mdHow to send transactions and how decisions are resolved from rules. Read it before wiring your API nodes.
edge-install-troubleshooting.mdInstallation failure modes grouped by root cause
EDGE_DATA_RESIDENCY_CONTRACT.mdWhat data may leave the Edge, and how

Internal reader: install process map: docs/install/README.md. Edge process entry: docs/install/01-client-edge-node.md. Deep technical reference: docs/INSTALL.md. This guide is the client-facing deep dive.


1. Choose your deployment mode​

Container (default)Native (--native)
What runsEngine, Aerospike and the ledger (postgres:16-alpine) as containers on a private bridge networkTemurin JRE 21, Aerospike CE and PostgreSQL 16 on the host; engine as a systemd service
PlatformsLinux, Windows ServerLinux only
DB isolationAerospike and the ledger have no published portBoth bound to 127.0.0.1; ports 3000 and 5432 firewalled
Installed for youContainer runtime, config, TLS, ledger passwordJRE, Aerospike, PostgreSQL 16, config, TLS, ledger role and database, systemd unit
Best forAlmost everyone; the same stack on every platformEstates whose policy forbids containers

Choose container unless container runtimes are prohibited.

1.1 Edge Site: several nodes, one ledger​

An Edge Site is one or more nodes of the same PSP that share one ledger and one Aerospike cluster. A single node is a site whose site id is its edge id. For a multi-node site, run one shared PostgreSQL 16 database and point every node at it:

export HOKEKA_LEDGER_PASSWORD='<password>' # never passed on the command line
sudo -E bash install.sh ... \
--ledger-url jdbc:postgresql://site-db:5432/hokeka_ledger \
--ledger-user hokeka_edge \
--site-id acme-eu

On Windows: -LedgerUrl, -LedgerUser, -SiteId, with the password in $env:HOKEKA_LEDGER_PASSWORD. With --ledger-url the installer does not start a local ledger.


2. Minimum system requirements​

2.1 Supported operating systems​

OSMinimum versionContainer modeNative modeNotes
Ubuntu22.04 LTS✅✅Best-tested path
Debian12 (Bookworm)✅✅
RHEL / Rocky / AlmaLinux9✅✅PostgreSQL 16 from the PGDG repository
SUSE Linux Enterprise / openSUSE15 SP5✅✅zypper
Arch Linuxrolling✅⚠️Native works; Aerospike package is not vendor-provided
Alpine Linux3.19✅✅ x86_64 onlymusl-linked core; see the note below
Windows Server2019 / 2022✅❌Aerospike has no native Windows build
Windows 10 / 1121H2✅❌Evaluation only, not production

Alpine / musl​

A glibc shared library cannot load on musl, so a separate musl-linked core is published: libedge_engine-linux-x86_64-musl.so. The installer detects your C library and downloads the matching one.

musl on x86_64 supports both modes. On Alpine, --native uses Alpine's OpenJDK 21 (Adoptium publishes no apk repository; 21 meets the engine's floor). Aerospike has no Alpine package, so the installer stages the config and points you at aerospike.com/download for the server. Container mode avoids that step.

musl on ARM is refused, because no musl/aarch64 core is published. Use container mode there.

CPU architecture: x86_64 or aarch64. Both are built on native runners with the Java↔Rust boundary executed.

2.2 Retention​

A PSP admin sets retention in Console → Settings → Data Retention:

  • minimum and default 5 years (FATF R.11), maximum 25 years;
  • every change goes through maker-checker (a second admin approves);
  • an increase takes effect on approval; a reduction takes effect 30 days after approval.

Retention is not an installer setting. --retention-days is accepted and ignored with a warning. The Control Plane publishes the value in the sealed Edge config document. The Edge consumer (EdgeConfigPoller) applies it and the daily purge (RetentionPurger) deletes data older than your retention period, so the ledger stabilises at about retention × daily volume.

2.3 Ledger disk: size for 5 years​

The ledger disk is the dominant cost. install.sh --peak-tps N prints this estimate before it installs anything:

evaluations = N × 86 400 × 365 × 5
disk (GiB) = evaluations × 2 048 bytes ÷ 2^30 × 1.3 (30% headroom)
Peak TPSEvaluations in 5 yearsLedger disk (approx.)
1157 M390 GiB
5788 M1 953 GiB
101 576 M3 909 GiB
507 884 M19 548 GiB
10015 768 M39 097 GiB

Read these numbers with care:

  1. They are an upper bound. The formula assumes your peak TPS for 24 hours a day, every day. Use your real daily volume if you know it: disk ≈ daily evaluations × 1 825 × 2 048 B × 1.3.
  2. 2 048 bytes per evaluation is an estimate, not a measurement. It covers the row (IDs, typed columns, decision, about 0.5 KiB of features), its share of the indexes, the outbox row and Postgres overhead. Measure it in your pilot before you commit to storage.
  3. Longer retention scales linearly. For 10 years, double the numbers.
  4. A full disk stops recording. The node then answers HOLD with failClosedCode = LEDGER_UNAVAILABLE (fail-closed). Alert on disk usage.

install.ps1 has no -PeakTps option. On Windows, use the formula above.

2.4 Aerospike and RAM​

Aerospike holds hourly buckets per card (50 h TTL), daily buckets (32-day TTL), card profiles (800-day TTL), device and IP profiles (400-day TTL), compliance counters and the rule bundle (AerospikeFeatureStore.java). The formula below sizes the hourly buckets only; the daily buckets and profiles add records on top and are not sized here. Its primary index costs 64 bytes of RAM per record:

velocity records ≤ min(TPS × 93 600, active cards × 26) (26 hours of buckets)
index RAM = velocity records × 64 bytes

At 100 TPS sustained that is at most about 9.4 M records and 0.6 GB of index RAM. The shipped data file is filesize 4G, which holds about 8 M records at an assumed 512 bytes each (about 90 TPS sustained). Above that, raise it with --data-file-size 16G. The 512-byte figure is not measured.

Starting points for host size (estimates, not benchmarks; validate in the pilot):

TierSustained TPSRAMvCPULedger disk (5 y, at that TPS all day)
Evaluation< 58 GB2see §2.3
Small1016 GB4~3.8 TiB
Medium5032 GB8~19 TiB
Large100+64 GB16~38 TiB+

RAM covers the JVM heap, PostgreSQL shared buffers and page cache, Aerospike and the OS. The ledger needs fast storage: it is written on the authorisation path.

2.5 Software prerequisites​

The installer provisions all of these. The table is what to expect, and what to pre-stage in an air-gapped estate.

ComponentVersionModeNotes
Java runtimeTemurin JRE 21NativeContainer mode uses eclipse-temurin:21-jre. Java 21 is the platform baseline: the engine serves each transaction on a virtual thread
PostgreSQL16BothContainer: postgres:16-alpine (POSTGRES_TAG). Native: distro package, or PGDG where the distro has no 16. scram-sha-256 auth
Aerospike Server CE6.4BothNamespace hokeka, replication-factor 1 (single node)
Container runtimeDocker 24+ / Podman 4+, Compose 2.20+ContainerInstalled via get.docker.com if absent; Docker Desktop via winget on Windows
systemdany currentNativeThe unit is hokeka-edge.service
curl or wgetanyBothArtifact download
gnupg2.2+BothRequired: release signature checks are fail-closed
glibc2.31+NativeSee the musl note in §2.1

Aerospike wants proto-fd-max 15000, so the file-descriptor limit for its user must not be lower.

2.6 Published native cores​

ArtifactPlatformJNI boundary executed on
libedge_engine-linux-x86_64.soglibc, x86_64native x86_64 runner
libedge_engine-linux-aarch64.soglibc, ARM64native ARM runner
libedge_engine-linux-x86_64-musl.somusl, x86_64Alpine container
edge_engine-windows-x86_64.dllWindowsnative Windows runner

Every core has its Java↔Rust crossing run on its own platform before release.

2.7 Disk layout and permissions​

PathContentsMode
/opt/hokeka/bin/edge-host.jar640
/opt/hokeka/lib/libedge_engine.so644
/opt/hokeka/config/edge.env (native) or .env (container)Identity, Control Plane URL, enrollment code, EDGE_LEDGER_*600
secrets/TLS keystore, edge-mtls.pass, edge-ledger.pass600, mounted read-only
/opt/hokeka/data/edge-identity.json, the node's private keys; mtls/edge-client.p12, the mTLS client key and certificate600, the only writable mount
Ledger dataContainer: volume ledger-data. Native: the PostgreSQL 16 data directory—
Aerospike data file/opt/aerospike/data/hokeka.dat—

Back up two things:

  • The Edge Ledger. It is the PSP's multi-year record of every evaluation. Use your normal PostgreSQL backup method (for example pg_dump or a physical backup) and test restores.
  • /opt/hokeka/data/. It holds the node's pinned X25519/Ed25519 identity. Lose it and the node must be re-enrolled. Never recreate it by hand.

Put the ledger and the Aerospike data file on separate SSD/NVMe volumes.


3. Network requirements​

3.1 Inbound​

Nothing from the internet. The only listener is the transaction API:

PortSourcePurpose
8443/tcpYour PSP API nodes onlyTransaction API, TLS 1.3 only

It binds to 127.0.0.1 by default. If your API nodes are on other hosts, bind the private-network address and restrict the source:

--bind 10.0.0.5 --allow-subnet 10.0.0.0/24

Never expose 8443 to the internet. It is an internal decisioning API.

3.2 Outbound: TCP 443 only​

DestinationPortPurposeRequired
edge.hokeka.com443Rule bundle pull, metrics, decision records (mTLS). Also the Edge Tunnel (WSS)Yes, ongoing
packages.hokeka.com443Artifact downloadInstall and upgrade only
Docker Hub (eclipse-temurin:21-jre base image)443Base image for the Edge image the installer buildsInstall and upgrade, container mode
Distro mirrors, get.docker.com, packages.adoptium.net, PostgreSQL PGDG443PrerequisitesInstall only

Cadence: rule bundle poll every 15 s (EDGE_BUNDLE_POLL_INTERVAL), metrics every 60 s (EDGE_METRICS_INTERVAL), decision-record outbox drained every 2 s (EDGE_ASSESSMENT_SHIP_INTERVAL). Records stay in the ledger outbox until the Control Plane acknowledges them, so an outage or a restart loses nothing.

For restricted-egress estates, mirror the artifacts and use --repo-url https://your-mirror/edge, or install offline with --offline.

3.3 Never exposed​

  • Aerospike ports 3000–3003. Container mode publishes no port; native mode binds loopback and firewalls 3000. Aerospike Community Edition has no authentication, so network isolation is its access control.
  • PostgreSQL port 5432. Container mode publishes no port; native mode binds 127.0.0.1 and denies 5432 from the network (ufw or iptables). The ledger role also needs its scram-sha-256 password. A shared site database (§1.1) must be reachable only from that site's Edge Nodes.

3.4 TLS and proxies​

The transaction API is TLS 1.3 only, terminated inside the engine. There is no plaintext listener. The engine refuses to start without a keystore.

A TLS-intercepting proxy on the outbound path breaks the Control Plane channel: it is mTLS with a pinned server identity. Exempt edge.hokeka.com from interception. The Edge Tunnel uses an HTTP/1.1 Upgrade, so the proxy must also pass WebSocket upgrades to that host.


4. Pre-installation checklist​

  • Ledger disk sized for 5 years (§2.3) on a separate, backed-up SSD/NVMe volume
  • Host meets the tier's RAM and CPU (§2.4)
  • OS on the supported list; not musl on ARM if using --native
  • Outbound TCP 443 to edge.hokeka.com open and not TLS-intercepted; no other egress needed after install
  • Inbound 8443 reachable from your API nodes and nowhere else
  • Root or Administrator access
  • From the Hokeka portal: your numeric PSP id, your edge id, and a fresh enrollment code
  • Your CA-issued server certificate (the self-signed one is not for production, §6.1)
  • Backups cover the ledger and /opt/hokeka/data/
  • For a multi-node site: the shared PostgreSQL 16 database, its user, and HOKEKA_LEDGER_PASSWORD

--pspid takes the numeric portal id (for example 42), not a name or slug. Activation compares it with the enrollment code's owner and returns 403 on mismatch. Copy the command from the portal's setup wizard.


5. Installation​

curl -fsSL https://packages.hokeka.com/edge/install.sh -o install.sh

# Read it before running it as root.
less install.sh

sudo bash install.sh \
--pspid 42 \
--edgeid acme-eu-1 \
--controlplane https://edge.hokeka.com \
--enrollment-code ABCD-1234 \
--bind 10.0.0.5 \
--allow-subnet 10.0.0.0/24 \
--peak-tps 20

5.2 Linux — native mode​

sudo bash install.sh --native \
--pspid 42 --edgeid acme-eu-1 \
--controlplane https://edge.hokeka.com \
--enrollment-code ABCD-1234

5.3 Windows Server (Administrator PowerShell)​

.\install.ps1 -PspId 42 -EdgeId acme-eu-1 `
-ControlPlane https://edge.hokeka.com -EnrollmentCode ABCD-1234

5.4 Pinning a version and other flags​

For production change control, pin a version:

sudo bash install.sh --version 1.2.3 ...

Other flags: --channel beta, --repo-url URL, --offline, --data-dir PATH, --tls-client-auth need, --peak-tps N, --data-file-size 16G, --ledger-url URL, --ledger-user USER, --site-id ID, --edge-image REF (use an existing image instead of the one the installer builds locally from the verified release jar and native core, e.g. a private mirror or a pinned digest), --controlplane-signing-key KEY / --controlplane-ingest-key KEY (set the Control Plane public keys explicitly; by default the Edge pins them from its enrolment response).

5.5 What the installer does​

  1. Detects distro, package manager, CPU architecture and C library.
  2. Downloads SHA256SUMS, verifies its GPG signature against a pinned key, then downloads and checksum-verifies each artifact. Any mismatch deletes the file and aborts.
  3. Installs prerequisites: a container runtime, or JRE + Aerospike + PostgreSQL 16.
  4. Isolates the databases (no published ports, or loopback + firewall).
  5. Generates the ledger password into secrets/edge-ledger.pass (mode 600), or reads HOKEKA_LEDGER_PASSWORD for a shared database. Re-runs reuse the existing password.
  6. Native mode: creates the ledger role and the hokeka_ledger database.
  7. Generates a self-signed EC P-384 TLS keystore, mode 600.
  8. Writes .env or /opt/hokeka/config/edge.env, mode 600, with EDGE_LEDGER_URL, EDGE_LEDGER_USER, EDGE_LEDGER_PASSWORD, EDGE_LEDGER_FAIL_CLOSED=true and EDGE_SITE_ID.
  9. Stages the native core into /opt/hokeka/lib.
  10. Starts the service and health-checks it.

At start-up the engine creates its ledger schema (edge_ledger, EDGE_LEDGER_SCHEMA) with its own migrations and creates monthly partitions ahead of time. If the ledger is down at boot, the node starts anyway, keeps retrying, and answers HOLD until the ledger is writable.

On signature failure, stop. It means the checksum manifest was not signed by the Hokeka release key. Do not retry with --insecure-skip-signature; contact Hokeka. Nothing has been installed at that point.


6. Post-installation​

6.1 Replace the TLS certificate — required for production​

The installer generates a self-signed certificate so the engine can start. Replace it with one from your CA, keeping the path and alias:

keytool -importkeystore \
-srckeystore your-ca-issued.p12 -srcstoretype PKCS12 \
-destkeystore /opt/hokeka/secrets/edge-tls.p12 -deststoretype PKCS12 -alias edge

# update EDGE_TLS_KEYSTORE_PASSWORD in .env, then restart

For mutual TLS from your API nodes, install with --tls-client-auth need and point SERVER_SSL_TRUST_STORE / SERVER_SSL_TRUST_STORE_PASSWORD at your client-CA truststore. We recommend this for production: only holders of a certificate you issued can submit transactions.

6.2 Activate the node — it is fail-closed until you do​

On first boot the node generates its key pairs and tries to enrol. Until a Hokeka admin approves the node, the Control Plane answers 202 PENDING_APPROVAL and keeps the enrolment code; the Edge retries every minute and enrols as soon as it is approved, within the code's 24 h life (reissue it with POST /edge/nodes/{id}/enrollment-code). Until the node is approved and enrolled:

  • GET /edge/status reports "authorization": "unauthorized"
  • POST /edge/evaluate returns HOLD; an unapproved node never issues an ALLOW
  • no rule bundle is served (403)

The installer no longer needs the Control Plane keys handed over by a Hokeka operator: at enrolment the /edge/enroll response carries the Control Plane's Ed25519 signing key and X25519 ingest key, and the Edge pins them to controlplane-keys.json (first-use pinning — a later enrolment presenting different keys is refused, never silently re-pinned). If you prefer to pin them ahead of time, you may still set them in .env (native: edge.env); configured keys always win over the enrolment response:

CONTROLPLANE_ED25519_PUBLIC_KEY=<EDGE_BUNDLE_SIGNING_PUBLIC_KEY> # verifies every rule bundle
CONTROLPLANE_X25519_PUBLIC_KEY=<EDGE_METRICS_INGEST_PUBLIC_KEY> # encrypts metrics and decision records

and let the Edge obtain its mTLS client certificate at enrolment. The mTLS client certificate is not installed by hand: at enrolment the Edge generates its key and a CSR, the Control Plane signs it with the Hokeka Edge CA, and the Edge stores it in EDGE_MTLS_KEYSTORE (default /opt/hokeka/data/mtls/edge-client.p12) under the installer-generated EDGE_MTLS_KEYSTORE_PASSWORD, renewing it automatically. Without the Ed25519 key every bundle poll fails before it starts, so no bundle loads and every evaluation answers HOLD NO_BUNDLE.

6.3 Verify​

curl -sk https://127.0.0.1:8443/edge/status | jq
FieldRequired valueIf wrong
authorizationnot unauthorizedNode not yet approved in the portal (§6.2)
evaluatornativefallback-java-interpreter means the Rust core did not load; see §8
featureStorenot unavailableAerospike unreachable; velocity rules cannot fire
ledger.stateOKDOWN or NOT_CONFIGURED: every evaluation answers HOLD. Check docker compose ps ledger or systemctl status postgresql (postgresql-16 on RHEL family) and the EDGE_LEDGER_* values; ledger.reason says why
ledger.outboxBacklogsmall and fallingDecision records are not reaching the Control Plane; check the channel (§3)
ledger.outboxQuarantined0Records the Control Plane kept refusing on their own (reject code QUARANTINED_HTTP_<status>); they stay in the ledger. Send the Edge log to Hokeka support
healthUPsystemctl status hokeka-edge / docker compose ps

featureStore: unavailable is not a benign warning. With the default featurestore.fail-closed=true, every request with a pan_hash answers HOLD FEATURE_STORE_UNAVAILABLE and no rules run. Alert on this field.

6.4 Send a test transaction​

curl -sk https://127.0.0.1:8443/edge/evaluate \
-H 'Content-Type: application/json' \
-d '{"txn_id":"test-1","pan_hash":"<hash>","amount_cents":1000,
"currency":"KES","country_code":"KE","mcc":"5411","merchant_id":"m-1"}' | jq

An approved node returns a decision and writes it to the ledger. A node that returns HOLD for everything is unapproved, or its ledger is down.

Field names are snake_case and are matched literally. pan_hash, not panHash. A misnamed field is not an error; it is a feature the rules never see. See edge-transaction-evaluation.md before wiring your API nodes.

txn_id must not look like a card number. A 13–19-digit value that passes the Luhn check is refused with 422 TXN_REF_LOOKS_LIKE_PAN, and nothing is evaluated or stored.


7. Operating the node​

7.1 Day-to-day​

systemctl status hokeka-edge # native
journalctl -u hokeka-edge -f
docker compose ps # container
docker compose logs -f edge
docker compose logs -f ledger

7.2 What to monitor​

SignalWhy
evaluator ≠ nativeDegraded to the slower Java path
featureStore = unavailableVelocity rules cannot fire (§6.3)
HOLD with LEDGER_UNAVAILABLEThe ledger is down, full or too slow to write
Ledger disk usageGrows until the first rows pass retention, then the daily purge holds it steady; compare with §2.3
authorization changeNode de-authorised centrally; it will HOLD
Aerospike disk vs filesizeEviction begins when the file fills
Decision latency p99It is on the authorisation path
Certificate expiryServer certificate and mTLS client certificate

7.3 Restart behaviour​

The verified rule bundle is kept on your premises: Aerospike set rules / key active, and rule-bundle.ir beside the node identity (EDGE_RULE_BUNDLE_FILE overrides the path). Start-up loads that file even when Aerospike is down, so a restarted node enforces rules at once. A Control Plane outage does not stop an enrolled node from deciding, and decision records wait in the ledger outbox until the Control Plane is back.

7.4 Upgrades​

curl -fsSL https://packages.hokeka.com/edge/install.sh | sudo bash -s -- --native --version 1.3.0

Re-running is idempotent. The TLS keystore, edge.env, the ledger password, the ledger data and the pinned node identity are kept. Only the jar and native core are replaced, then the service restarts. Ledger schema migrations run at start-up.

Rolling back means re-installing an earlier --version. There is no automatic revert and no canary, so upgrade one node first and verify §6.3 before the rest.


8. Troubleshooting​

SymptomCauseFix
Install aborts: signature verification failedManifest not signed by the Hokeka keyStop. Contact Hokeka. Do not bypass
Install aborts: "no pinned release signing key"Unofficial or older installer buildGet an official installer from Hokeka
--ledger-url needs the database password in HOKEKA_LEDGER_PASSWORDShared ledger without a passwordExport HOKEKA_LEDGER_PASSWORD and run with sudo -E
Engine refuses to start, TLS errorMissing keystore or passwordBy design. Check /opt/hokeka/secrets/ and EDGE_TLS_KEYSTORE_PASSWORD
evaluator: fallback-java-interpreterNative core absent or unloadableCheck /opt/hokeka/lib/libedge_engine.so; on musl see §2.1; check the arch
featureStore: unavailableAerospike down or unreachabledocker compose ps aerospike; check the data file has not filled
Everything returns HOLDNode not approved, or ledger downApprove in the portal (§6.2); check the ledger service and disk
No rule bundles arrivingMissing pinned keys, missing mTLS cert, or TLS interception§3.4 and §6.2
202 PENDING_APPROVAL during activationnode not yet approvedApprove it at /edge-nodes (§6.2); the Edge enrols on its next retry
403 during activation--pspid wrong or not numeric; code unknown, used or expired; PSP not activeUse the numeric portal id (§4); reissue the code with POST /edge/nodes/{id}/enrollment-code
422 TXN_REF_LOOKS_LIKE_PANtxn_id is a card numberSend your own transaction reference, never the PAN

Collect for a support ticket: /edge/status output, journalctl -u hokeka-edge --since -1h (or docker compose logs), the installed version, distro and arch (uname -a), and your edge id. More: edge-install-troubleshooting.md.


9. Uninstall​

# native
sudo systemctl disable --now hokeka-edge
sudo rm /etc/systemd/system/hokeka-edge.service && sudo systemctl daemon-reload

# container (keeps the volumes, including the ledger)
cd /opt/hokeka && docker compose down

The ledger holds records you must keep for your retention period. docker compose down -v deletes the ledger-data volume. Back up the ledger and /opt/hokeka/data/ before you remove anything, and only delete ledger data when your retention obligations allow it.


10. Security summary​

GuaranteeEnforced byDepends on you
Transaction data stays in your estateOnly decision records (IDs, action, score, rule IDs) and aggregates are shipped—
No inbound connection from HokekaThe Edge opens every connection, outbound on 443Not opening ports yourself
No plaintext transaction APITLS 1.3 in-process; the engine refuses to start without a keystoreReplacing the self-signed cert (§6.1)
The databases are reachable only by the engineNo published ports / loopback + firewall; ledger passwordNot publishing 3000 or 5432; isolating a shared site database
Only your API nodes can submit transactions--bind + --allow-subnet, and mTLS with --tls-client-auth needConfiguring these
Rules cannot be forged or replayedEd25519 signature and replay guard on every bundlePinning the Control Plane keys (§6.2)
An unapproved node cannot approve itselfFail-closed HOLD until portal approval—
No decision without a recordFail-closed HOLD when the ledger cannot be written (EDGE_LEDGER_FAIL_CLOSED=true)Sizing and monitoring the ledger disk
Artifacts cannot be tampered with in transitGPG-signed checksums, verified against a pinned keyNot using --insecure-skip-signature