On this page
Passthrough Credentials
Artery is non-custodial by design. We do not — and cannot — move funds off the upstream venue. The credentials we hold (or transit) only ever grant the narrowest authority needed to read data or place orders.
The two credential shapes
Different platforms model authority differently. Artery mirrors the upstream model:
Hyperliquid and Polymarket use agent wallets approved via EIP-712 typed data signed by the user's master wallet. The agent's private key can place orders but cannot withdraw. Artery issues a unique agent per user and signs trades with it.
master wallet (user-controlled)
└─ approveAgent EIP-712 → agent wallet (Artery-held)
├─ order / cancel / modify ✅
├─ withdraw ❌
└─ approveBuilder/etc ❌
Withdrawals require the master wallet to sign withdraw3 directly.
Artery cannot impersonate the master.
What Artery never holds
| Authority | Who holds it |
|---|---|
| Master/owner wallet private key | User — never sent to Artery |
| Withdraw authority | Master wallet only |
| 2FA / TOTP / passkey | User's auth device |
| Polymarket Safe Module ownership | User's Polygon address |
Credentials at rest (Kalshi RSA only)
Artery uses envelope encryption for the only persisted credential (Kalshi PEM):
- Generate a one-time DEK (256-bit AES key).
- AES-256-GCM encrypt the PEM with the DEK.
- Wrap the DEK with KMS (Cloud KMS in production,
LocalKmsClientin dev). The wrapped DEK is stored alongside the ciphertext. - To decrypt: KMS unwraps the DEK; AES-GCM unwraps the PEM.
ts// apps/api/src/secrets/secrets.service.ts (sketch)
const dek = randomBytes(32);
const ciphertext = aesGcm(dek).encrypt(pem);
const wrappedDek = await kms.encrypt(dek);
return { ciphertext, wrappedDek, iv, tag };KMS keys never leave the KMS HSM. The DEK is in process memory only for the duration of one signing call, then zeroed. The PEM never touches disk unencrypted.
Per-request credentials (EIP-712 chains)
Polymarket and Hyperliquid trade endpoints (planned) accept credentials per request via headers — Artery does not persist them:
| Provider | Header |
|---|---|
| Polymarket | X-Polymarket-Credentials (encrypted blob, decrypted only in-memory) |
| Hyperliquid | X-HL-Agent-Key (one-time agent private key, used and dropped) |
The agent key model means even a full Artery compromise yields only trade-only authority bound to a specific user, not withdrawal authority.
Audit surface
Every credential access (KMS unwrap, agent sign) emits a structured log
record with userId, provider, endpoint, timestamp, and a hash of
the request payload. The hash, not the payload, lets us prove exactly
which signing operations happened without leaking the data.
See also
- Authentication — Artery API key model
- Security architecture — full crypto stack
- Kalshi provider — RSA-PSS signing details