How it works

How Sentinel signs

Two programs on one machine in your AWS account, a key that never leaves an enclave, and an honest list of what’s built and what isn’t yet.

In one paragraph

Sentinel is a signing service for trading systems. It runs as two programs on one EC2 instance in your AWS account: a small host process that your trading code talks to, and an enclave image that runs inside an AWS Nitro Enclave on the same instance. The private key exists only inside the enclave. Your code asks for a signature; the enclave reads the request, checks it and signs it. The key and your orders stay on your instance.

The path of a signature

How a signature is madeInside your AWS account, on one EC2 instance: your trading process sends a request to the Sentinel host process, which passes it over vsock, inside an encrypted session, to a Nitro Enclave. The enclave reads the request, checks it against your policy and signs it with a key that never leaves the enclave. The signature comes back the same way.Your AWS accountOne EC2 instance (the parent)Your tradingprocessSentinelhostNitro Enclaveno disk, no network, no shell1Read the request in place2Check it against your policy3Sign with the keyvsockencryptedrequest, thensignature backHow a signature is madeYour trading process sends a request to the Sentinel host on the same EC2 instance. The host passes it over vsock, encrypted, to a Nitro Enclave, which reads it, checks it against your policy and signs it with a key that never leaves the enclave. The signature comes back the same way.Your AWS accountOne EC2 instance (the parent)Your trading processSentinel hostvsock, encryptedNitro Enclaveno disk, no network, no shell1Read the request in place2Check it against your policy3Sign with the keyThe signature goes back the wayit came. The key never does.
The enclave is carved out of the instance’s own CPUs and memory, and only vsock connects the two.
  1. Your trading code sends a signing request to the Sentinel host process on the same instance.
  2. The host passes it over vsock, the only way into a Nitro Enclave, inside an encrypted session. The enclave sets the session up with the host when it connects, using the Noise protocol.
  3. Inside the enclave the request is read in place, without copying it into new objects (rkyv), checked against your policy, and signed: secp256k1 ECDSA with deterministic nonces (RFC 6979), using RustCrypto’s k256 library.
  4. The signature goes back the same way. No request returns the private key.

The trip in and out of the enclave costs more time than the signature itself: about 120 µs in all, by our estimate. The latency page shows where that comes from.

Where the key lives

Today the enclave creates the key itself and keeps it in memory. When the enclave stops, the key is wiped. So a key lives exactly as long as its enclave, which is the safe default and also the limitation.

Keeping a key across restarts is designed but not built. The plan is to seal it with AWS KMS under a key policy that releases it only to an enclave whose measurement matches the image you approved (the enclave’s PCR0, and the image hash KMS checks with it). That key policy is written, in our Terraform; the enclave’s side of it isn’t wired in yet.

The policy engine

Before anything is signed, a request is meant to pass your rules:

  • a notional limit per transaction, per second and per minute;
  • a cap on signatures per second, with a cooldown;
  • contract addresses you allow or block;
  • the chains you allow;
  • the hours you trade.

The rules live in a YAML file, and the engine is a separate library whose tests pass. Here’s the gap: the enclave doesn’t parse transactions yet, so today it runs the engine against a placeholder instead of the real order. Parsing transactions for the chains and venues of a first pilot comes before anything else.

The kill switch

The enclave watches its own timing. When it sees five critical jitter readings in a row, it refuses new sessions, and the host is told why. Once the readings are clean again for long enough, it opens back up by itself.

A stricter switch is written but not wired in. It also stops when a heartbeat is missed, and once it has stopped, only a person can turn it back on.

What’s built, and what isn’t

PartWhere it stands
Signing: secp256k1 ECDSA with RustCrypto’s k256In the code, with passing tests
An encrypted session over vsock (the Noise protocol)In the code
Reading each request in place, without copying it (rkyv)In the code
Keys created inside the enclave and wiped when it stopsIn the code
Jitter guard: refuses new sessions while timing is offIn the code
Policy engine: size, rate, contracts, chains, trading hoursBuilt and tested as a library; not yet applied to real transactions
Keeping a key across restarts, sealed with AWS KMS and released only to a matching enclaveDesigned: the KMS policy is written; the enclave side isn’t built
A stricter kill switch: stops on a missed heartbeat, only a person restarts itWritten; not wired in
Latency measured inside an enclaveNot yet
Builds that reproduce the same enclave measurementNot shown yet
A security review by a third partyNot yet
Use in productionNot yet

“In the code” means it’s written and part of the prototype; none of it has run under a real workload yet. A pilot is how the right-hand column changes.

What it isn’t

  • Not a custodian. We never hold your keys or your funds; Sentinel runs in your account.
  • Not an exchange connection. Your code still talks to the venue; Sentinel only signs.
  • Not a wallet for people. It’s built for programs that sign many times a second.