arcenkey

Architecture

Three parts, one trust boundary.

Arcenkey separates the thing that holds secrets from the thing that can decrypt them. Hosts keep ciphertext. One server keeps the HSM credential. A hardware device does the cryptography. None of the three is useful on its own.

The parts

What runs where, and what each part never holds.

ComponentRuns whereHoldsNever holds
arcenkey client Every host that uses secrets Its own encrypted file, and the host's client certificate in a small local daemon. Plaintext at rest. The HSM credential.
arcenkey-server One server, plus an optional standby or active-active secondary The HSM credential, the allowlist of hosts, the private CA, the audit stream. Ciphertext. Any secret, in any form.
YubiHSM 2 Attached to each server The wrap key, generated on the device. The wrap key never leaves it.

A read, step by step

What happens when a script asks for a secret.

  1. A script runs arcenkey -r. The client finds the entry in the host's encrypted file by the one-way hash of its name and hands the ciphertext to the local daemon over a Unix socket. Which local users may do that can be restricted by group, by socket permissions, or by a per-user access list.
  2. The daemon presents the host's client certificate to arcenkey-server over mutually authenticated HTTPS. Callers that cannot carry a certificate, such as CI runners and ad-hoc tooling, can use a scoped bearer token instead. Tokens are opt-in and minted by an administrator.
  3. The server checks the host against its allowlist, applies its rate limits, and asks the attached YubiHSM 2 to unwrap the value. The device performs the operation with a key that never leaves the hardware.
  4. The plaintext returns along the same authenticated path to the calling script. It is never written to disk anywhere.

Storing a secret is the mirror image. The value travels to the HSM to be wrapped, and the result lands in the host's file as one more line, with its own version number, timestamp, and metadata. With envelope encryption on, only a fresh per-secret data key makes that trip and the value itself is encrypted on the host.

Two optional layers

Turn on per secret, per host, or not at all.

Envelope encryption

Generates a fresh random key for the one secret, encrypts the value on the host, and sends only that small key to the HSM to be wrapped. The value never leaves the host in the clear, and secrets are no longer limited by the device's message size. Every read still makes one trip to the HSM to unwrap the data key, so there is no offline decryption.

Host-binding

Wraps the entry a second time under a key that lives only on that host. Decrypting then needs both the HSM and that host's key, so a file copied elsewhere stays sealed. It is file-pair separation, not a hardware lock: a whole-system restore that brings both files back together still works, by design, and the documentation spells out exactly what it does and does not defend against.

Identity, access, and audit

Every host is known. Every call is attributed.

  • Each host gets a certificate from a private CA built into the server. Enrollment is self-service from the host, approved by an administrator. Revocation is one allowlist change.
  • On shared hosts the calling user's identity is attached to each request, so the audit log says which person ran the command, not just which machine.
  • Every operation is logged with caller, host, action, and the secret's hash. Entries go to the system journal and from there to any SIEM. The web dashboard reads the same stream.
  • Requests are rate-limited, with a separate, tighter budget for failed authentication. Prometheus metrics expose request rates, errors, and HSM health for whatever you already monitor with.

Staying up

Hardware fails. Servers fail. Reads keep working.

  • Clients list more than one server and fail over on their own.
  • A second server, with its own YubiHSM 2 holding the same wrap key, runs as a secondary. It pulls the authorization state from the primary over mutual TLS and serves cryptography active-active. The CA private key never leaves the primary. Enrolling a secondary is two commands.
  • Each server can be backed by a hot-standby HSM.
  • Integrity verification decrypts every entry in a file to prove a restore is good before anything depends on it.
  • When no server answers, clients fail fast with a distinct exit code rather than hanging. Listing and inspection keep working locally. Service resumes the moment a server is reachable, with nothing to restart.

Keeping copies in step

One owner, many followers.

Some credentials have to exist on more than one host at once: the password a pair of application servers both present to the same database, for instance. Arcenkey handles that without a shared store. One host owns the secret and pushes every change to its peers within seconds, ciphertext only, over SSH. A retry timer brings back any peer that was down. It is configured per secret and off unless configured.

What a deployment looks like

Two installers, no platform.

  • Server. One Linux host with a YubiHSM 2 attached (USB passthrough works on virtual machines), the server daemon, and a plain-text configuration file. No database, message broker, or container platform.
  • Clients. A small Bash command-line tool and a socket-activated daemon, installed as native systemd services on Red Hat Enterprise Linux and its Rocky and Alma relatives, versions 8 through 10. Support for additional Linux distributions is planned. The client depends only on Bash and standard system tooling and the server is a single Go binary, so adding a distribution is a matter of packaging and validation rather than a port.
  • Windows. A wrapper that proxies through SSH to a Linux host running the real client, so plaintext never touches the Windows filesystem.
  • Java and Tomcat. Call the command-line tool at start-up. No native library to adopt.
  • Operators. A REST API documented with an OpenAPI specification, a web dashboard for hosts, tokens, audit, and health, and man pages for the tools.

The rest of the detail

What this page leaves out.

This page describes the design at the level we share publicly. The wire protocol, the on-disk format, the server's HSM session handling, and the key-rotation procedure are documented in full, and that documentation does not leave ICP without an agreement in place.