Skip to main content
OMS Wallet is built on WaaS (Wallet as a Service), the embedded wallet service that manages user keys and signs on behalf of users entirely inside an AWS Nitro Enclave. Clients create and operate wallets without any direct access to private key material: all cryptographic operations occur within the enclave’s trusted execution environment. Keys are generated, used, and stored (encrypted) within the enclave boundary. No unencrypted key material ever leaves enclave memory. The non-custodial guarantee is enforced by infrastructure, not by policy. No party, including Polygon and its infrastructure administrators, can unilaterally access user keys or sign transactions on a user’s behalf. This is a structural property of the system, not a contractual promise. The architecture shifts the question from “do you trust the operator?” to “can you verify the cryptographic chain of custody?” The answer is yes: the PCR0 hash is public, audits are independent, KMS policies are operated by independent organizations, and hardware attestation is included with every API response. This page covers the trust model, attestation, encryption, request signing, and ceremony controls that make the guarantee structurally enforceable. For recovery flows that function without the operator, see Timed Recovery.

Trusted execution environment

AWS Nitro Enclaves provide hardware-enforced isolation for the WaaS service. The enclave runs in a separate memory space that is invisible to the host operating system: even a process running as root on the host cannot read enclave memory. There is no SSH access to the enclave, no persistent local storage, and no general network interface. The enclave cannot be interactively inspected at runtime by anyone, including the operator. The only communication channel between the host and the enclave is a VSOCK connection (a virtual socket interface). The ingress proxy running on the host machine bridges external HTTP traffic to the enclave over this channel. The ingress proxy is untrusted by design: it relays opaque HTTP and has no access to encryption keys, private key material, or enclave memory. All outbound HTTP from the enclave uses a custom transport that routes through the same VSOCK channel. TLS handshakes for external connections occur inside the enclave, so the host proxy sees only encrypted traffic and cannot inspect or tamper with the content of requests or responses. Enclave code is identified by an Enclave Image File (EIF) and a set of PCR (Platform Configuration Register) measurements computed deterministically at build time. PCR0 is the hash of the enclave image, PCR1 is the kernel hash, and PCR2 is the application hash. Because the build is deterministic, a specific source commit always produces the same PCR0. These measurements are the cryptographic identity of the running code and form the foundation for all attestation and KMS access control described in this page.

Cryptographic attestation

Every API response from WaaS includes an X-Attestation-Document response header containing a Base64-encoded AWS Nitro attestation document. The document is signed by the Nitro Security Module (NSM) inside the enclave using a key that is hardware-bound and cannot be extracted. Clients can use this document to verify independently that a specific response came from the audited enclave code and has not been modified in transit. The attestation document contains the following fields:
  • PCR measurements: cryptographic hashes identifying the exact code running in the enclave. PCR0 is the image hash, PCR1 is the kernel hash, and PCR2 is the application hash.
  • User data: a binding between the attestation document and the specific request-response pair. The format is Sequence/1:<base64(SHA-256(METHOD + " " + PATH + "\n" + REQUEST_BODY + "\n" + RESPONSE_BODY))>, where the hash covers the HTTP method, path, request body, and response body joined with a literal space between method and path and a newline between the remaining parts.
  • Nonce: the value the client supplied in the X-Attestation-Nonce request header, proving the attestation document is fresh and was not replayed from a prior request.
  • Timestamp: when the attestation was generated by the NSM.
  • AWS certificate chain: the chain from the NSM’s key up to AWS’s root certificate, allowing any verifier to confirm the document was produced by a genuine Nitro Enclave.
To verify a response, a client follows these steps:
1

Validate the AWS certificate chain

Confirm the document was generated by a genuine Nitro Enclave and not constructed by a third party.
2

Check PCR0

Compare the PCR0 value in the document against the known-good enclave image hash published for the current release, confirming the expected code is running.
3

Verify the nonce

Confirm the nonce in the document matches the X-Attestation-Nonce value sent in the original request, confirming the document is fresh.
4

Recompute the user-data hash

Compute SHA-256(METHOD + " " + PATH + "\n" + REQUEST_BODY + "\n" + RESPONSE_BODY), encode it as Sequence/1:<base64(hash)>, and compare it to the document’s user-data field, confirming the response has not been modified.
Any client who completes these steps can confirm that the response came from the audited enclave code, that it corresponds to the request they sent, and that no intermediate party modified it.

Request signing

Every RPC request to WaaS must include an Oms-Wallet-Signature header formatted according to HTTP Structured Field Values (RFC 8941). This header proves the request was issued by a specific authenticated credential and has not been replayed or modified. The header carries the following fields:
FieldDescription
algSigning algorithm: ecdsa-p256k-eip191 or ecdsa-p256-sha256
scopeProject scope identifier
credCredential address (the client’s public key address)
nonceMonotonically increasing integer
expOptional expiration timestamp in Unix seconds
sigThe cryptographic signature over the request
The client SDK holds a credential keypair locally and signs every request with that keypair. The signed message is structured: a request line (method and path), the header metadata fields alphabetically ordered (only exp, nonce, and scope are included when present), a blank line, and the full request body. The enclave’s credential middleware recovers or verifies the signer address from the signature and makes the credential identity and scope available to request handlers. Replay protection uses monotonic nonces. Each credential stores the last accepted nonce value in DynamoDB. An incoming request must carry a nonce strictly greater than the stored value. Both the nonce update and a per-credential usage counter are applied atomically using DynamoDB conditional writes. A concurrent request with the same or a lower nonce causes the conditional write to fail and the request is rejected. Rate limiting is also applied per credential using a sliding time window, counted in the same atomic operation. Combined with user authentication, request signing ensures every wallet operation is bound to the authenticated user’s local device key. The operator does not hold client credential private keys and cannot produce valid signatures on the user’s behalf.

Encryption at rest

All sensitive data in WaaS, including private keys, credentials, and authentication state, is encrypted with AES-256-GCM before being written to DynamoDB. The database stores only ciphertext. No plaintext key material is persisted outside enclave memory at any point. Encryption uses a pool of data-encryption keys (DEKs). During key generation, 32 bytes of random key material come from the Nitro Security Module’s entropy source. When encrypting a record, the pool selects one DEK at random from the active pool, generates a 12-byte random nonce from the enclave’s entropy source, and writes the encrypted output in a versioned ciphertext envelope alongside the CipherKeyRef (which DEK was used) and a CiphertextHash (SHA-256 of the ciphertext, used for indexing). Every encrypted record carries authenticated associated data (AAD) that binds the ciphertext to its specific storage location: a composite of the table name and the record’s primary key, for example Wallet/{WalletID}. The AAD is authenticated by AES-GCM but is not itself encrypted. This binding prevents two attack classes available to an adversary with direct database access:
  • Cross-table record moves: moving a record to a different table causes the table name in the AAD to not match, so GCM authentication fails.
  • Within-table record swaps: swapping ciphertext between records in the same table causes the primary key in the AAD to not match, so GCM authentication fails.
After a record is decrypted, a CorrespondsTo() check compares every unencrypted index column in the database record against the corresponding field in the decrypted plaintext. A mismatch indicates that a database-level attacker modified index metadata without being able to re-encrypt the payload to match. The record is rejected.

Shamir-split KMS keys

Each DEK in the cipher pool is split into N shares using Shamir’s Secret Sharing over GF(2^8). Reconstructing the DEK requires at least T of the N shares (the threshold). With fewer than T shares, no information about the original key is revealed: this is an information-theoretic guarantee, not a computational hardness assumption. Each of the N shares is independently encrypted by a separate AWS KMS key. To reconstruct a DEK, the enclave must successfully call at least T of those KMS services and obtain T decrypted shares. Each KMS key policy is pinned to specific PCR measurements: KMS enforces that decryption requests come from a verified Nitro Enclave presenting an attestation with the expected PCR0. A request from outside a verified enclave, or from an enclave with a different PCR0, is rejected by KMS before any share material is returned. Reconstruction of a DEK happens only inside the enclave at the moment of decryption. The reconstructed 32-byte DEK exists only in enclave memory for the duration of the decryption operation and is not persisted anywhere. This design means that decrypting wallet data requires two independent conditions: a valid Nitro Enclave running the approved code (enforced by PCR measurements in KMS policies), and cooperation from at least T independent KMS key holders. Neither condition alone is sufficient.

Trusted Third Party council

In production, the KMS keys that encrypt the Shamir shares are operated by three independent organizations: Polygon, Quantstamp, and CoinCover. Each operates its own AWS account and KMS infrastructure under its own legal entity and jurisdiction. These organizations form the Trusted Third Party (TTP) council. Each TTP’s KMS key policy is pinned to a specific PCR0 measurement. Decryption is only authorized when the requesting enclave produces a valid attestation matching the whitelisted PCR0. A TTP cannot grant access to arbitrary code: the KMS policy is a cryptographic enforcement mechanism, not a discretionary access decision. TTPs hold KMS keys that encrypt individual Shamir shares; they do not hold shares directly, they do not have access to wallet data in the database, and a single share reveals nothing about the underlying DEK. The production threshold is 2-of-3. No single TTP can unilaterally decrypt wallet material. If one TTP’s infrastructure is fully compromised, the attacker holds one encrypted share per DEK, which is cryptographically insufficient to reconstruct any key. The system continues to operate as long as any two TTPs remain available. Transitioning council membership or rotating a TTP’s KMS keys produces a new pool generation. Generation changes are explicit, auditable governance events. Older generations remain decryptable as long as the threshold of those TTPs still cooperates, preserving continuity across council changes.

Deployment ceremonies

The EIF is built deterministically from public source code. A specific commit always produces the same EIF and therefore the same PCR0 hash. The PCR0 is immutable once computed: it is the cryptographic fingerprint of the exact code and configuration baked into the image. Configuration parameters, including KMS key ARNs, encryption pool settings, and network endpoints, are baked into the EIF at build time. A configuration change is therefore a code change: it produces a different PCR0 and is subject to the full audit and ceremony process. There is no path to silently modify runtime configuration without changing the PCR0. Before any new enclave image is deployed, it must pass an independent security audit. Quantstamp performs the independent audit. Polygon participates in sign-off in its capacity as a TTP council member, not solely as the operator. Only after all parties have completed sign-off does the full TTP council run a coordinated deployment ceremony: each TTP independently updates its KMS key policy to add the new PCR0 to the allowlist. Until each TTP individually updates its policy, the new enclave cannot obtain the required number of KMS shares and cannot decrypt any existing wallet data. Any code that has not passed audit and full council sign-off is cryptographically locked out of all wallet material. This makes silent enclave modification structurally impossible: any change produces a different PCR0 that must pass audit and ceremony before it can access anything.

Non-custodial guarantee

The non-custodial property of OMS Wallet rests on splitting control four ways: the user (authentication and device key), the attested enclave code (the execution boundary), a threshold of independent TTP KMS keys (decryption authorization), and independent auditors (gatekeeping every code change). No single party controls all four, and any combination that falls short of the threshold is cryptographically insufficient.
What the operator cannot do, by construction:
  • Cannot extract, reconstruct, or export a user’s private key.
  • Cannot decrypt wallet material unilaterally; doing so would require a threshold of TTPs to cooperate.
  • Cannot deploy code that gains access to existing wallets without independent audit and independent KMS policy updates by each TTP in the council.
  • Cannot sign a transaction without the user’s fresh authentication.
  • Cannot silently modify the enclave; any change produces a new PCR0 that every unmodified TTP KMS policy would reject.
  • Cannot unilaterally freeze, seize, or transfer user assets.
On-chain continuity provides an additional guarantee independent of WaaS. The wallet is an on-chain smart account: its existence, configuration, and asset state live on the blockchain and do not depend on WaaS infrastructure being available. User-authenticated recovery (see Timed Recovery Technical Reference) functions without any cooperation from the operator. If WaaS infrastructure became permanently unavailable, users would retain the cryptographic means to authenticate and control their accounts through the on-chain smart contract.

Threat model

The table below summarizes the principal threats and the mitigations in place for each.
ThreatMitigation
Compromised host OSNitro Enclave isolation places enclave memory outside the host’s address space. Root access on the host cannot read enclave memory. The VSOCK channel is the only path between host and enclave, and the host proxy sees only TLS-encrypted traffic.
Compromised databaseAll DynamoDB records are AES-256-GCM ciphertext. AAD binding makes record swaps detectable at decryption time. CorrespondsTo() checks detect metadata tampering. Database access alone cannot yield usable plaintext.
Compromised networkAll requests carry a credential signature. All responses carry a Nitro attestation document. Connections to external services use TLS terminated inside the enclave, so the network path sees only ciphertext.
Replay attacksMonotonic nonces, updated atomically in DynamoDB, prevent request replay. Attestation nonces in X-Attestation-Nonce bind each attestation document to a specific request. Credential TTLs limit session duration.
Credential theftCredential lifetimes are configurable and bounded. Request signatures bind each credential to the holder’s local device private key: a stolen credential identifier is useless without the corresponding private key. Wallet-binding limits cap the number of wallets reachable per credential.
Enclave image tamperingPCR measurements are computed by the NSM at enclave boot time and cannot be forged. Both client verifiers and TTP KMS policies independently check PCR0 against the known-good hash before granting any access.
Configuration tamperingAll runtime configuration is baked into the EIF at build time. Any configuration change produces a different PCR0, which must pass independent audit and full TTP council sign-off before the image can decrypt any wallet data.

References