Secrets and Workers
On-chain authorization and audit trail, off-chain execution. How contracts call real APIs without putting plaintext credentials anywhere near a public ledger.
TL;DR. Contracts trigger outbound HTTP calls using encrypted API keys stored on-chain. A Vault contract enforces the schedule, authorization, and audit trail; an off-chain Worker, authenticated by its registered public key, handles decryption and execution.
Aevum lets smart contracts trigger outbound HTTP calls using API keys that are encrypted and stored on-chain. The schedule, authorization, and audit trail are all enforced by contract code; the actual decryption and HTTP call happen off-chain, in a Worker process authenticated by its registered public key.
Two on-chain primitives make this work. A Vault stores encrypted secrets and controls who's allowed to request them. Workers are off-chain processes that watch the chain for authorized requests, do the work, and post signed receipts back. Combined with native cron, that's an autonomous, scheduled, auditable HTTP executor governed entirely by contract logic.
The problem
Contracts that touch the real world need to call APIs, and calling APIs needs credentials. Storing them in plaintext on a public chain is obviously wrong. Encrypting them with the contract's own key doesn't help either — contract code is public, so any node operator can replay the decryption.
Most chains sidestep this by leaning on centralized oracles for data, or off-chain bots holding credentials in environment variables. Both approaches quietly move the important decisions — when to execute, which credentials to use, what action to take — off-chain, where the chain can't see them. The blockchain stops being a chain and becomes a billboard for events that the off-chain part of your system mostly ignores.
Architecture
Aevum splits the job: the chain handles authorization and the audit trail, an off-chain Worker handles execution, and encrypted ciphertext is the only thing that crosses between them — readable only by the Worker it's encrypted to.
On-chain:
- A Vault contract storing ciphertext, ownership, authorized callers, and the Worker ID
- Your contract, with cron scheduling and a decryption request that emits a
WorkRequestedevent - A WorkerRegistry for public-key lookup
Off-chain, the Worker daemon watches the chain continuously, reads the ciphertext, decrypts it in memory, checks it against a URL policy, makes the HTTP call, signs the result, and posts a receipt back on-chain. The Worker has no privileged channel into the chain — it signs its fulfillment transaction with a Dilithium3 keypair, the same mechanism every other Aevum account uses, and the Vault checks the signer against the registered Worker ID like it would any other transaction.
Cryptography
Secrets use a hybrid scheme: X25519 plus ML-KEM-768 as the key encapsulation, with ChaCha20-Poly1305 as the symmetric AEAD. Both KEM outputs are combined via HKDF-SHA256 into the symmetric key.
X25519 is the classical half — battle-tested, fast, well-supported across JS runtimes. ML-KEM-768 is the NIST post-quantum KEM standard — since Aevum already signs everything post-quantum, encryption gets the same treatment. ChaCha20-Poly1305 does the actual authenticated encryption on the plaintext.
The hybrid gives defense in depth: if X25519 ever falls to a quantum attack, ML-KEM still holds. If ML-KEM (a newer standard) turns out to have a classical weakness, X25519 still holds. The overhead is roughly 1.2KB per ciphertext — fine for something the size of an environment variable.
Authorization model
A secret's owner declares a closed list of authorized contracts at creation and can change that list later. The Vault's requestDecryption checks msg.sender against that list and rejects anyone not on it.
Two more constraints apply per Worker, enforced off-chain by the Worker itself:
- Integrations allowlist — each Worker ships with a baked-in allowlist of well-known API hosts, and only calls destinations on it. Governance can extend the list; self-hosted Worker operators can add their own via
allow-extra.json. Requests for an off-list host are refused and logged. - Policy hash on-chain — a Worker commits a SHA256 hash of its policy plus version string when it registers, so an auditor can verify exactly which policy a Worker was running at any block height, even after the operator rotates the file.
The chain enforces who can ask; the Worker enforces what it will actually do. Two independent layers, on purpose.
What lives on chain
Every meaningful event leaves a record:
SecretPut,SecretRotated,SecretDeletedSecretAuthorized,SecretRevokedWorkRequested,WorkFulfilledWorkerRegistered,WorkerKeyRotated,WorkerDeregistered
An indexer or explorer can reconstruct the full lifecycle of any secret — when it was created, who's authorized, every job that ran, the hash of every response, which Worker executed it. It reads like enterprise audit logging, except impossible to retroactively edit.
Trust assumptions
Worth being explicit about what this does and doesn't remove:
- You're trusting the Worker operator with plaintext access to whatever's encrypted to that Worker. No transparent blockchain design avoids this.
- You're trusting the Worker to report honestly — the fulfillment transaction carries a response hash, but the response body itself lives in the Worker's memory. A malicious Worker could fabricate one. Running two Workers and requiring matching hashes mitigates this.
- You're not trusting other contracts — the authorization list is the gate.
- You're not trusting validators — they store ciphertext but never see plaintext.
Aevum runs a default free Worker during this phase. Operators who'd rather not trust that host can run their own in about five minutes with npm install @aevumlabs/workers.
Where this is going
- Threshold decryption — secrets encrypted so decryption needs t-of-n Workers cooperating, turning single-Worker trust into quorum trust
- Trusted Execution Environments — Workers running inside Intel SGX or AMD SEV, so even the host operator can't read plaintext
- Response integrity oracles — multiple Workers fulfilling the same job, with contracts accepting the result only when a quorum agrees on the response hash
The current model is enough for most real applications today. These are upgrades for specific threat models, not blockers to using it now.