Skip to main content
With Turnkey Verifiable Cloud (TVC), you can require custom checks before a Turnkey activity completes. A policy sidecar running in TVC receives activity webhooks, evaluates based on your application’s rules, and submits an approval or rejection to Turnkey. Your app takes an activity intent as input and returns an approval decision. Its checks can use your own rules and external data, and can apply to signing, key exports, or administrative changes.

What you can build

The example sidecar validates Aptos signing requests, which Turnkey does not currently parse natively. Other use cases require extending the example.

Architecture

Your application submits activities as an initiator user. Turnkey evaluates the applicable policies and collects approvals. The sidecar runs your custom checks inside a TVC enclave and votes as a separate service user. For signing, the transaction signing key stays in Turnkey. The sidecar uses an API credential derived from its long-lived TVC Quorum Key to approve or reject the activity.
Application initiates activities in Turnkey, which holds the consensus policy and transaction signing key; a separate TVC enclave holds the policy sidecar and its approval credential.
TVC quorum keys: Turnkey supports creating and storing quorum key shares in its key management platform. Hosted quorum keys are secured by Turnkey: key generation, signing, and share re-encryption are all inside enclaves. See the hosted-operator example for setup.

Activity approval flow

The sidecar verifies the webhook signature, freshness, and organization before evaluating the activity.
  1. Your application submits a request; its submission counts as the initiator’s approval.
  2. Turnkey records the activity as awaiting consensus and sends a signed webhook.
  3. The sidecar evaluates the activity and submits an approval or rejection for supported requests.
  4. Turnkey evaluates the vote and completes the activity, rejects it, or continues waiting for approvals.
Six stages: submit a request, await consensus, deliver a signed webhook, evaluate checks and vote, evaluate approvals, and retrieve the activity result.

Choosing an approval model

The same API credential, webhook verification, and voting mechanism provide the foundation for either model. Changes to root membership and threshold require approval from the current root quorum. The example sidecar ignores administrative activities. Before making it a required root member, add explicit validation for the administrative actions it must approve, including root-quorum updates where needed.

Implementation steps

Explore the complete implementation in the TVC policy sidecar example.
1

Deploy the policy sidecar

Follow the example’s deployment instructions. They use hosted operators to create and provision a private Quorum Key. Replace the publicly known quorum key: the sidecar uses the quorum key as a Turnkey credential.Configure the sidecar for your Turnkey organization, approve the deployment, and provision its shares after verification. Once live, keep its public URL for registration.
2

Register the sidecar in Turnkey

Retrieve the deployed sidecar’s public key from GET /turnkey/api_public_key and register it, with the returned curve type, on a dedicated non-root service user. Use the returned key rather than generating another keypair.Create a separate non-root initiator user with its own credential and a Turnkey-owned Ed25519 signing key with an Aptos address. Two credentials on the same user do not provide two independent approvals.
3

Require the sidecar's approval

Create a policy requiring both users, scoped to the intended wallet:
Replace the placeholders with your wallet and user IDs. Keep the policy’s scope aligned with the activities the sidecar can validate.
4

Connect activity webhooks

Create a webhook endpoint in the same organization, using your deployed app’s URL with the path /webhooks/turnkey/activity. Subscribe it to ACTIVITY_UPDATES so the sidecar receives pending activities and can vote.
5

Submit and check a request

Submit a supported Aptos raw-signing request with the initiator’s credential. Confirm that the activity enters ACTIVITY_STATUS_CONSENSUS_NEEDED, then inspect the sidecar’s vote and final activity result.Ignored activities can remain pending. An API submission failure is separate from a policy rejection. Successful signing returns a signature; it does not fund or broadcast the transaction.

Extending the example to Sui and Stellar

Some signing flows submit a transaction digest rather than the full transaction. To apply custom checks, the sidecar needs the original transaction data and must verify that it produces the digest being signed. This requires extending both the client and the example sidecar. Turnkey preserves extra top-level fields in an API-key-stamped activity request. Your application can include a field such as suiContext or stellarContext alongside type, timestampMs, organizationId, and parameters. Turnkey does not interpret this context; your TVC sidecar defines its format and validation rules.
  1. Include the transaction context. For Sui, include the serialized transaction bytes needed to reconstruct the intent message. For Stellar, include the transaction envelope XDR and network passphrase. Add this context before stamping the request, and send the exact body that was stamped. Update the client’s request construction so the extra field is preserved.
  2. Compute the digest as usual. Use your existing signing flow to compute the transaction digest and submit it in parameters.payload, with the additional context alongside the request’s standard fields.
  3. Read the context in the sidecar. After verifying the webhook, fetch the activity in your sidecar logic. The original request is available as a JSON string in the initiating vote’s message within activity.votes, rather than in the parsed intent. Identify the original request by checking that the SHA-256 hash of its exact message bytes matches the activity’s sha256: fingerprint, then read your context field.
  4. Validate before voting. Parse the supplied transaction and independently reconstruct its signing digest, including Sui’s intent prefix or Stellar’s network-specific signature base. Your sidecar should require an exact match with the activity’s signing payload in addition to evaluating the rest of the policies.

Next steps