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

# Security

> How BundleUp protects your users’ credentials and data, and what you’re responsible for.

BundleUp holds credentials to your customers’ accounts. This page explains where those credentials live, who can use them, and what never leaves BundleUp.

## Where secrets live

```mermaid theme={null}
flowchart LR
    subgraph Browser["User's browser"]
        BR["Sees: client ID, code, state<br/>Never sees: tokens, API key,<br/>connection ID"]
    end
    subgraph Backend["Your backend"]
        BK["Holds: API key, connection IDs"]
    end
    subgraph BU["BundleUp"]
        DB[("Tokens and integration secrets<br/>encrypted at rest")]
        EDGE["Edge: decrypts in memory<br/>for one request only"]
    end
    P[Provider]

    Browser -->|"authorize: client_id"| BU
    Backend -->|"API key + connection ID"| EDGE
    DB --> EDGE
    EDGE -->|"user's access token"| P
```

The browser only ever handles public or single-use values. Your backend holds the API key and connection IDs. BundleUp keeps tokens and integration secrets encrypted, and decrypts them in memory only for the request that needs them.

## Encryption

* **Access tokens, refresh tokens and integration secrets** (your OAuth apps’ client secrets) are encrypted at rest with **AES-256-GCM**.
* The primary store uses **envelope encryption**: each value is encrypted with its own data key, and data keys are protected by a key management service (AWS KMS).
* In the primary store, each encrypted value is bound to its workspace, connection and purpose, so a ciphertext copied to another record can’t be decrypted there.
* At the edge, tokens are decrypted **only in memory, only for the request that needs them**, with keys held in a secrets store separate from the data.
* **API keys** are stored only as SHA-256 hashes. BundleUp can’t show you a key after creating it.

## Isolation between workspaces

Every request resolves its API key to a workspace first. A connection is only usable if it belongs to that same workspace. A connection ID used with another workspace’s key is treated as not found. Integrations, logs and webhooks are scoped the same way.

## The authorization flow

The flow is designed so that nothing usable passes through the browser:

* Your **API key is never used in the browser**. It’s only needed for the server-to-server code exchange.
* The **connection ID is never put in a URL**. The redirect carries a one-time `code` instead.
* The code **expires after 5 minutes**, works **once**, is tied to your `redirect_uri` and workspace, and is **useless without your API key**.
* BundleUp only redirects to **redirect URIs you registered**.
* The `state` parameter lets you protect against CSRF. See [Protect the flow with state](/docs/guides/auth/authorization-flow#protect-the-flow-with-state).

## What BundleUp doesn’t store

* **Request and response bodies.** The Proxy streams responses straight through. Logs record method, URL, status, duration and IDs only.
* **Headers** you send, other than the ones BundleUp consumes.
* **MCP tool arguments or results.**

## When tokens leave BundleUp

Tokens are sent only to the provider, on every request, in the `Authorization` header. That’s their purpose.

Your BundleUp **API key** is sent to a third party only if you choose [model-hosted MCP](/docs/guides/mcp/clients#model-hosted-mcp), where the model provider calls BundleUp on your behalf.

## Revocation

Deleting a connection asks the provider to revoke its token, where the provider supports it, and then deletes the stored credentials.

## Your responsibilities

* **Keep API keys secret.** Server-side only, in a secrets manager, one per service. Rotate any key that may have leaked. See [API keys](/docs/concepts/api-keys).
* **Map connections to users correctly.** Any API key in a workspace can use any connection in it. Your application decides which user may use which connection.
* **Verify webhook signatures.** See [Verifying signatures](/docs/guides/webhooks/verifying).
* **Request minimal scopes.** See [Choosing scopes](/docs/guides/integrations/scopes).
* **Limit who has access** to the dashboard, and separate production into its own workspace. See [Team & members](/docs/platform/team).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.