> ## Documentation Index
> Fetch the complete documentation index at: https://docs.walletsuite.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Security Overview

> The non-custodial, cross-surface trust model behind WalletSuite — MPC threshold signing, server-owned tool profiles, and deny-by-default policy.

WalletSuite's security model has three orthogonal axes:

| Axis                                | Members                                                                                                                                     |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Surface** (how you integrate)     | Hosted MCP · SDK · REST API                                                                                                                 |
| **Signing layer** (where keys live) | Non-custodial MPC threshold signing · External BYO (KMS / HSM / multisig — SDK or REST)                                                     |
| **Cross-cutting controls**          | Tool profiles & scopes · Policy gates · Decision provenance · Audit trail · Structured errors · Input validation · Secret isolation · HTTPS |

## Trust Model

| Component                           | Layer    | Holds keys?       | What it can access                                                                                                                                       |
| ----------------------------------- | -------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **WalletSuite REST API**            | Surface  | No                | Blockchain data, transaction preparation, fee estimation                                                                                                 |
| **Hosted MCP endpoint**             | Surface  | No                | Tool orchestration, input validation, tool-profile gating                                                                                                |
| **SDK** (`@walletsuite/wallet-sdk`) | Surface  | No                | Typed client; signer-agnostic                                                                                                                            |
| **Agent key**                       | Identity | No                | Scoped, revocable agent identity; held server-side and used to authorize the agent. Grants no signing authority on its own                               |
| **WalletSuite cosigner share**      | Signing  | 1 of 2 key shares | Fully-managed cosigner; envelope-encrypted at rest behind the scenes; releases its share only after policy clears                                        |
| **Customer share**                  | Signing  | 1 of 2 key shares | Held customer-side in your own storage (database, HSM, device, or passkey-wrapped envelope); the WalletSuite cosigner never assembles it into a full key |
| **External Signer** (BYO)           | Signing  | Customer-managed  | KMS / HSM / multisig — outside WalletSuite                                                                                                               |
| **Your LLM / chat**                 | Caller   | No                | Proposes tool calls and reads responses. Holds no authority — the policy engine decides, not the model                                                   |

Trust boundary: no single party ever holds enough to sign alone, regardless of which surface initiates the request.

## Defense in Depth

### 1. Tool Profile · *Agent surfaces*

An agent's callable surface is the **server-owned tool profile bound to the agent, narrowed by the scopes in its short-lived token**. Tools outside that intersection are never registered in the MCP schema handed to the agent — the model cannot discover, name, or call them, so a poisoned prompt or hostile tool output has nothing to invoke. The profile is set on WalletSuite's side, never by the caller. SDK and REST have no equivalent: they expose their full surface to whatever code holds the key.

See [Execution Levels](/ai-agents/execution-levels) and [Security & Trust (AI Agents)](/ai-agents/security-model).

### 2. Policy Gates · *Signing layer*

A deterministic policy decision point evaluates every signing intent before it can be signed. Your allowlist rules are opt-in and deny-by-default once armed: each rule matches on chain, operation type, contract address, method selector, an optional destination pin, and an optional per-transaction amount cap in base units, with a mandatory expiry. Intents on chains you're not entitled to are denied, as are operations that can't be typed. Rules roll out in stages: off, shadow, enforce. No LLM sits in the decision path, and the same gate applies whether the call comes from MCP, SDK, or REST.

See [Policy Gates](/core-concepts/policy-gates).

### 3. Structured Errors · *MCP + SDK*

Every error includes a `category` and `code`. `flow` errors include a `requiredAction`. Agents recover programmatically.

See [Structured Errors](/core-concepts/structured-errors).

### 4. Input Validation · *All surfaces*

Zod schemas (MCP/SDK) and request validators (REST) check inputs before they reach the API:

* Address format per chain family (0x-prefixed for EVM, T-prefixed for Tron)
* Amounts as positive numeric strings (no scientific notation)
* Mutually exclusive fields (`amount` vs `amountWei`)
* Token contracts validated when provided

### 5. Secret Isolation · *All surfaces*

Long-lived credentials stay server-side and never reach a tool argument, request body, or the model:

* **Agents:** the agent's key stays server-side and authorizes the agent; the raw key never reaches the model, a prompt, or a downstream MCP call. See [Connect Your Agent](/ai-agents/token-exchange).
* **SDK / REST:** the `x-api-key` credential is sent only as a request header.

Secrets stay out of prompt history, tool-argument logs, and MCP traffic.

### 6. HTTPS Enforcement · *All surfaces*

Every WalletSuite endpoint and callback is HTTPS-only. External URLs (chain RPCs, webhook targets) are validated as HTTPS before use.

### 7. Audit Trail · *Signing layer*

Every `sign_transaction` and `send_transaction` operation appends a receipt to a hash-chained, append-only JSONL log — tamper-evident and exportable to your SIEM.

See [Audit Trail](/security/audit-trail).

### 8. Decision Provenance · *Signing layer*

WalletSuite records a decision on every signing intent at the point it is authorized. Each record carries a `policyDecisionId`, the decision reason, and the matched rule when one admitted the operation. Allowed and denied intents alike are written to the signing-intents ledger, so a denial is durable evidence, not a silent drop.

See [Policy Decisions](/core-concepts/policy-decisions).

## Surface-Specific Notes

### Hosted MCP

* The tool profile and token scopes bound which tools exist in the agent's schema
* Tool arguments carry only wallet identifiers, chain ids, and unsigned tx hex — never key material
* The agent's key stays server-side; the agent connects with a short-lived token — see [Connect Your Agent](/ai-agents/token-exchange)
* Closed-source orchestration; trust is enforced architecturally, not via source review

### SDK

* Signer-agnostic: composes with MPC or External BYO (KMS/HSM/multisig)
* No tool profile — the SDK exposes its full surface to whatever code imports it
* Typed errors share the `category` / `code` taxonomy with MCP

### REST API

* Stateless HTTPS with `x-api-key` header
* Same input validation and structured error envelope as the SDK
* Customer brings the signer (External BYO) or routes signing through hosted MPC

## Non-Custodial Architecture

### MPC threshold signing

WalletSuite operates a fully-managed cosigner holding one share; you hold the other share in your own storage (database, HSM, device, or passkey-wrapped envelope). Both are required for every signature.

```
Any surface (MCP/SDK/REST) → prepare unsigned tx (no key access)
                           → policy engine authorizes the intent
                           → customer share signs (customer-side storage)
                           → WalletSuite cosigner share signs (only after policy clears)
                           → combined threshold signature → broadcast
                           → neither party ever held a full key
```

No full private key ever exists. Both shares are required to produce a signature, and neither party can sign alone. See [Key Management](/security/key-management).

## Attack Model

**Hosted MCP endpoint compromised / poisoned prompt:**

* The model only ever sees its bounded tool surface — tools outside its profile and scopes were never registered, so there is nothing to invoke
* No full key is exposed — no full key ever exists
* Every signing intent still clears the policy engine; `send_transaction` additionally requires `confirmBroadcast=true`

**WalletSuite cosigner share compromised:**

* Attacker has 1 of 2 shares — cannot produce a valid signature without the customer share
* Internal access is M-of-N gated and audit-logged

**Customer share compromised:**

* Attacker has 1 of 2 shares — cannot produce a valid signature without WalletSuite's cosigner share
* Policy gates are still evaluated on every co-signing request

**Read-only agent (Read level):**
Worst case is information disclosure (balances, prices, transaction history). No signing scope is present, so no value can be moved. See [Execution Levels](/ai-agents/execution-levels).

## What WalletSuite Does Not Do

* Hold a full private key (one of two key shares only)
* Custody funds
* Sign transactions alone — both shares are required
* Move funds without a passing policy decision

## Remaining Risks

Non-custodial does not mean zero risk. Operator-side risks:

* Granting a broader tool profile than the workflow needs
* Leaking the agent's key or an API key
* Enabling signing before arming policy rules

**Mitigation:** Grant the narrowest tool profile, arm deny-by-default rules on the signing layer, and keep credentials server-side.

## Practical Guidance

| Control      | Default                          | When to change                                                                                                          |
| ------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Tool profile | `read`                           | Raise to `prepare` / `execute` / `governed` as the workflow needs — see [Execution Levels](/ai-agents/execution-levels) |
| Policy rules | None active                      | Arm deny-by-default rules before enabling signing — see [Policy Gates](/core-concepts/policy-gates)                     |
| Broadcast    | Requires `confirmBroadcast=true` | Confirm only transactions the agent presented clearly                                                                   |

See [Production Checklist](/production-checklist).

## Related

* [Key Management](/security/key-management) - MPC share custody and lifecycle
* [Audit Trail](/security/audit-trail) - co-signing event logging and SIEM export
* [Execution Levels](/ai-agents/execution-levels) - tool profiles and scopes per agent
* [Security & Trust (AI Agents)](/ai-agents/security-model) - the tool profile as prompt-injection boundary
* [Policy Gates](/core-concepts/policy-gates) - deny-by-default authorization on the signing layer
* [Responsible Disclosure](/security/responsible-disclosure)
