Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

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.

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.

CheckWhat Scalekit requires
SignatureThe response or the assertion is signed with a certificate configured on the connection. An unsigned response with an unsigned assertion is rejected.
Signature placementThe 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.
IssuerThe response and assertion issuer match the IdP entity ID configured on the connection.
AudienceAny audience restriction in the assertion names the connection’s SP entity ID.
Destination and recipientThe response destination and the subject confirmation recipient match the connection’s assertion consumer service (ACS) URL.
Time conditionsNotBefore and NotOnOrAfter hold, with up to 180 seconds of clock skew. IssueInstant is within 90 seconds.
StatusThe response status is Success.

Scalekit also accepts encrypted assertions and decrypts them before validation.

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.

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.

RequestPKCE parameters
GET /oauth/authorizecode_challenge: the base64url-encoded SHA-256 hash of a random code_verifier. code_challenge_method: S256.
POST /oauth/tokencode_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.

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

Section titled “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.

  • 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.
  • Recovery after downtime. See Recover from missed events.

Read a connection’s full configuration through the API with Get a connection. 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.

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.

  • 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. One mutual NDA covers both.
  • HIPAA. To sign a Business Associate Agreement (BAA), contact us.

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.