> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended**:
> ```bash
> npx @scalekit-inc/cli setup
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Security and compliance

How AgentKit protects user credentials: per-environment encryption keys in Google Cloud KMS, what Scalekit stores and for how long, regions and certifications.
AgentKit holds your users' OAuth tokens and API keys, and makes API calls with them on your agent's behalf. This page explains how Scalekit protects those credentials and the data that passes through a tool call, and what your app is responsible for. Use it for a security review, or as a checklist before you onboard real users.

## Certifications

- **SOC 2 Type II** and **ISO 27001** certified.
- **GDPR** and **CCPA** compliant. The [Data Processing Agreement](https://www.scalekit.com/legal/data-processing-agreement) includes Standard Contractual Clauses and lists sub-processors.
- **[HIPAA](https://www.scalekit.com/legal/hipaa) eligible**, with a Business Associate Agreement on Enterprise plans.

Audit reports and penetration test summaries are available under NDA from the [Trust Center](https://www.scalekit.com/trust-center).

## How credentials are stored

Every OAuth token and API key a user connects is encrypted before it's written to the database:

- **A key per environment.** Scalekit encrypts credentials with AES-256-GCM under a data encryption key that belongs to one environment. No two environments share a key.
- **Keys wrapped by Google Cloud KMS.** Each environment's key is itself encrypted by a master key in Google Cloud KMS, which is held apart from the database and the application. A copy of the database alone yields nothing usable.
- **Scoped by environment.** Every read and write of stored credentials is filtered by environment, so one environment's context can't reach another's credentials.
- **Rotation without downtime.** When a key rotates, new values are encrypted with the new key and Scalekit re-encrypts existing values in the background, so existing credentials keep working. To re-encrypt existing data right away, use **Re-encrypt Data** on [Encryption keys](/agentkit/encryption-keys/).
- **Your own key, optionally.** Hold the master key in your own Google Cloud KMS. Revoking Scalekit's access to it makes the stored credentials unusable to Scalekit. See [Encryption keys](/agentkit/encryption-keys/).

Scalekit never returns a user's raw tokens in API responses. Your agent calls tools with `execute_tool` or the [API proxy](/agentkit/tools/custom-tools/), and Scalekit adds the token to the outgoing request.

## What Scalekit stores

- **Users' OAuth tokens and API keys.** Stored: Yes, encrypted as above. Kept for: Until the connected account is deleted.
- **Connection settings, including your OAuth app's client secret.** Stored: Yes. Kept for: Until the connection is deleted.
- **Tool call responses.** Stored: No. Returned to your agent and not kept. Kept for: Not stored.
- **Tool call inputs.** Stored: No. Sent to the app and not kept. Kept for: Not stored.
- **Tool call logs.** Stored: Tool name, connection, connected account, identifier, status, error code, duration and time. Also the app's error response, when **Store connector error details** is on. Kept for: 90 days.
- **Your API client secrets.** Stored: A one-way hash. The secret is shown once, when you create it. Kept for: Until you delete it.

Tool call logs show in **AgentKit** > **Logs**. They never contain a tool's successful response. When a call fails, they keep Scalekit's own error message, and keep the error the app returned only when **Store connector error details** is on in **AgentKit** > **Logs**. That error can include data from the app, so leave the setting off unless you're debugging a connector.

Tool call logs also contain the user's identifier, so use an internal user ID rather than an email address. See [Choose an identifier](/agentkit/concepts/#choose-an-identifier).

## Where data is hosted

Scalekit runs two independent regions on Google Cloud, with no shared application state:

| Region | Location |
| --- | --- |
| US | `us-west2` (Los Angeles) |
| EU | `europe-west3` (Frankfurt) |

You choose the region when you sign up, and your workspace's data stays in it. See [Environments and regions](/agentkit/environments/).

To keep credentials, tool calls and logs inside your own infrastructure, [self-host AgentKit](/agentkit/self-hosted/) with an enterprise license.

## In transit

All Scalekit endpoints require HTTPS with TLS 1.3. If an app only accepts traffic from known addresses, allow Scalekit's [outbound IP addresses](/reference/outbound-ip-addresses/) for your region.

## What your app is responsible for

Scalekit protects credentials once a user connects. Your app decides who connects and who can act as whom:

- **Verify users in production.** Set **AgentKit** > **Settings** > **User Verification** to **Custom user verifier**, so the person who approves access is the user your app meant. With **None**, anyone who opens an authorization link activates the account. See [Verify users](/agentkit/user-verification/).
- **Use a stable, internal identifier.** Pass your app's user ID, never an email address or anything a user can choose. Take it from your server-side session, not from the request body, so one user can't act as another.
- **Keep one user's credentials with that user.** When you hand a credential to an agent runtime, such as a [Virtual MCP session token](/agentkit/mcp/session-tokens/), store it per user and never share it across users.
- **Keep API credentials on the server.** Load your client ID and secret from environment variables or a secret manager, never from browser or mobile code. Rotate a secret by creating a new one before you delete the old one. See [API credentials](/agentkit/api-credentials/).
- **Request only the scopes you need.** A narrower scope limits what a leaked token can do. See [Configure scopes](/agentkit/connections/#configure-scopes).
- **Give agents only the tools they need.** Start with read-only tools, and ask the user before a destructive call. Tool definitions carry `read_only_hint` and `destructive_hint` for this. See [Use built-in tools](/agentkit/tools/scalekit-optimized-tools/).
- **Verify webhook signatures.** Scalekit signs every webhook. Check the signature before you trust a payload. See [Verify each request](/agentkit/account-events/#verify-each-request-and-handle-the-event).
- **Limit who can use the dashboard.** Give teammates the least access their work needs. See [Team members and roles](/agentkit/team-members/).

## Next

  - [Launch checklist](/agentkit/advanced/launch-checklist/): Everything to check before real users connect.
  - [Verify users](/agentkit/user-verification/): Confirm the person who connects is the user your app intended.


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
