> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> 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 for SSO and SCIM

How Scalekit validates SAML responses, enforces PKCE, isolates organizations, stores identity data and gives you its SOC 2 report.
Use this page when your security team reviews Scalekit's modular SSO and SCIM, or when you fill in a vendor security questionnaire. It covers how Scalekit validates sign-in responses from your customers' identity providers (IdPs), how it protects the authorization code it returns to your app, how it keeps organizations apart, where it stores identity data, and how to get its compliance reports.

## SAML response validation

Scalekit validates every SAML response before it reads any user attributes from it. Your app receives a user's profile only after every check below passes.

| Check | What Scalekit requires |
| --- | --- |
| Signature | The response or the assertion is signed with a certificate configured on the connection. An unsigned response with an unsigned assertion is rejected. |
| Signature placement | The signature is a direct child of the element it signs, and its reference points to that element's ID. Scalekit reads assertions only from direct children of the response. These rules block XML signature-wrapping attacks. |
| Issuer | The response and assertion issuer match the IdP entity ID configured on the connection. |
| Audience | Any audience restriction in the assertion names the connection's SP entity ID. |
| Destination and recipient | The response destination and the subject confirmation recipient match the connection's assertion consumer service (ACS) URL. |
| Time conditions | `NotBefore` and `NotOnOrAfter` hold, with up to 180 seconds of clock skew. `IssueInstant` is within 90 seconds. |
| Status | The response status is `Success`. |

Scalekit also accepts encrypted assertions and decrypts them before validation.

### Replay protection

Scalekit rejects a SAML response it has already accepted:

- **SP-initiated sign-in:** the response's `InResponseTo` must match a SAML request that Scalekit issued for the same browser, and each request ID can be used only once.
- **IdP-initiated sign-in:** Scalekit stores the ID of each assertion it accepts and rejects an assertion with the same ID.

Scalekit doesn't send an authorization code to your app from an IdP-initiated response. It sends the user to your initiate-login URL, and your app starts a new SP-initiated sign-in. See [IdP-initiated SSO](/sso/guides/idp-init-sso/).

## PKCE on the authorization endpoint

Proof Key for Code Exchange (PKCE) stops a stolen authorization code from being redeemed by anyone else. Scalekit supports PKCE with the `S256` method on `/oauth/authorize`, the same endpoint your app uses to start SSO with `organization_id`, `connection_id`, `domain` or `login_hint`.

| Request | PKCE parameters |
| --- | --- |
| `GET /oauth/authorize` | `code_challenge`: the base64url-encoded SHA-256 hash of a random `code_verifier`. `code_challenge_method`: `S256`. |
| `POST /oauth/token` | `code_verifier`: the value you hashed for `code_challenge`. |

When the authorization request includes a `code_challenge`, the token request fails with `invalid_request` if `code_verifier` is missing, and with `invalid_grant` if it doesn't match.

### Require PKCE for an application

PKCE is required for single-page and native applications. To require it for a server-side app, register it as a web application:

1. In **Developers** > **Applications**, select **Create Application** and choose **Web Application**.
2. In the application's settings, select **Enforce PKCE**.

Scalekit then rejects authorization requests from that application that don't include a code challenge.

## Organizations that share an identity provider

Each SAML connection has its own SP entity ID, ACS URL and SP metadata URL, and each contains the connection's ID. Scalekit identifies the connection from the ACS URL a response is posted to, not from the IdP's entity ID.

Two organizations can each have a SAML connection to the same IdP entity ID. The second connection doesn't replace the first. In their IdP, the customer creates one SAML app per organization and enters that connection's SP values in each.

## Directory sync (SCIM)

- **One endpoint and token per directory.** Each directory has its own SCIM endpoint URL and bearer token. Scalekit shows the token once, when it's generated. Regenerate it to rotate it.
- **Signed webhooks.** Every webhook Scalekit sends to your app is signed with your endpoint's signing secret. Verify the signature and reject requests more than 5 minutes old. See [Verify webhook signatures](/guides/webhooks-best-practices/#verify-webhook-signatures).
- **Recovery after downtime.** See [Recover from missed events](/guides/webhooks-best-practices/#recover-from-missed-events).

## Export connection configuration

Read a connection's full configuration through the API with [Get a connection](/apis/#tag/connections). For a SAML connection, the response includes the IdP entity ID, SSO and logout URLs, metadata URL, bindings, signing options and the IdP certificates. Each certificate is the full base64-encoded certificate body, with its issue and expiry dates. Add `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` lines to use it as a PEM file.

For an OIDC connection, the response includes the issuer, endpoint URLs, scopes and client ID. The client secret is masked.

## Data residency

Choose the region when you create your workspace. US workspaces run in Google Cloud `us-west2`, and EU workspaces run in `europe-west3`. Each region is a separate deployment with its own databases, and data isn't replicated between them. SSO connection configuration, directory data, auth logs and backups for a workspace stay in its region. See [Choose a region](/dev-kit/guides/dashboard/environments/#choose-a-region-us-or-eu).

## Compliance reports

- **SOC 2 Type II.** Scalekit is audited annually against the SOC 2 Security criteria.
- **Penetration testing.** A third party tests Scalekit annually.
- **Getting the reports.** Request the SOC 2 Type II report and the latest penetration test report from the [Scalekit Trust Center](https://trustcenter.scalekit.com). One mutual NDA covers both.
- **HIPAA.** To sign a Business Associate Agreement (BAA), [contact us](/support/contact-us/).

## Dashboard access

Only people your Admins invite can open your workspace in the Scalekit dashboard, and each person's role controls what they can view or change. See [Team members and roles](/dev-kit/guides/dashboard/manage-team-members/).

> tip: SSO for the Scalekit dashboard
>
> To sign your team in to the dashboard through your own identity provider with SAML or OIDC, [contact us](/support/contact-us/).


---

## 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 |
