Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ jobs:
ee/scim/lib/managed-membership.postgres.test.ts
lib/auth/sso/application/admit-sso-user.postgres.test.ts
lib/auth/sso/primary-provider.postgres.test.ts
lib/auth/sso-provider-secret-adapter.postgres.test.ts

- name: Verify billing and organization activity in PostgreSQL
working-directory: apps/sim
Expand Down
65 changes: 18 additions & 47 deletions apps/docs/content/docs/platform/enterprise/sso.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,24 @@ Click **Save**. To test, sign out and use the **Sign in with SSO** button on the

## Editing and advanced configuration

For a saved connection, open **Sign-in**, select the provider, and select **Edit**. The Provider ID remains fixed. **Delete** removes that sign-in path only: accounts and memberships it admitted stay. If you delete the primary provider and the domain has another verified provider, that one becomes primary; otherwise people at the domain sign in another way until a provider serves it again. A saved OIDC client secret appears as a mask with a suffix when available; **Replace** lets you enter a new secret, and **Keep saved** cancels that replacement. Select **Update** to save the provider, or **Discard** to abandon changes.
For a saved connection, open **Sign-in**, select the provider, and select **Edit**. The Provider ID remains fixed. **Delete** removes that sign-in path only: accounts and memberships it admitted stay. If you delete the primary provider and the domain has another verified provider, that one becomes primary; otherwise people at the domain sign in another way until a provider serves it again. A saved OIDC client secret appears as a mask with a suffix when available; **Replace** lets you enter a new secret, and **Keep saved** cancels that replacement. Provider secrets — the OIDC client secret, and SAML signing and decryption keys — are encrypted with `ENCRYPTION_KEY` before they are stored, so a copy of the database alone does not expose them. Select **Update** to save the provider, or **Discard** to abandon changes.

**Advanced options** contains OIDC scopes and optional authorization, token, and JWKS endpoint overrides. For SAML, it contains Audience, Callback URL override, signed-assertion requirements, NameID format, and optional IdP metadata XML. **Attribute mapping** lets either protocol override the email, name, and stable user-ID claim names. Leave a mapping blank to use the protocol default.
**Advanced options** contains OIDC scopes and optional authorization, token, and JWKS endpoint overrides. For SAML, it contains Audience, Callback URL override, signed-assertion requirements, encrypted assertions, NameID format, and optional IdP metadata XML. **Attribute mapping** lets either protocol override the email, name, and stable user-ID claim names. Leave a mapping blank to use the protocol default.

### Encrypted assertions

Turn on **Encrypt SAML assertions** when your identity provider encrypts the assertion, which some organizations require for assertions carrying personal data. It takes a key pair you generate:

- **Service provider certificate** — the public half. Sim publishes it in its service provider metadata, and you upload it to the identity provider as the encryption certificate.
- **Service provider private key** — the half Sim decrypts with. It is encrypted with `ENCRYPTION_KEY` before it is stored, and the form shows only a mask afterwards; **Replace** takes a new key.

Generate a pair with `openssl req -x509 -newkey rsa:2048 -keyout sp-key.pem -out sp-cert.pem -days 3650 -nodes`. Turning the setting off clears the stored key.

<Callout type="info">
Signing the authentication request Sim sends is not supported. Identity providers that
can require signed requests — Entra ID's **Require verification certificates**, for
example — must leave that off for Sim's application, which is their default.
</Callout>

SCIM settings save immediately in the **Provisioning** tab. Its **Disable just-in-time provisioning** rule overrides Automatic first-sign-in membership while the connection is active and entitled. Existing members can still sign in. See [directory provisioning](/platform/enterprise/scim#provisioning-and-sso-together).

Expand Down Expand Up @@ -417,48 +432,4 @@ SSO_TRUSTED_PROVIDER_IDS=custom-oidc,partner-saml
depend on your IdP asserting `email_verified`.
</Callout>

You can register providers through the **Settings UI** (same as cloud) or by running the registration script directly against your database.

### Script-based registration

Use this when you need to register an SSO provider without going through the UI — for example, during initial deployment or CI/CD automation.

```bash
# OIDC example (Okta)
SSO_ENABLED=true \
NEXT_PUBLIC_APP_URL=https://your-instance.com \
SSO_PROVIDER_TYPE=oidc \
SSO_PROVIDER_ID=okta \
SSO_ISSUER=https://dev-1234567.okta.com \
SSO_DOMAIN=company.com \
SSO_USER_EMAIL=admin@company.com \
SSO_OIDC_CLIENT_ID=your-client-id \
SSO_OIDC_CLIENT_SECRET=your-client-secret \
bun run packages/db/scripts/register-sso-provider.ts
```

```bash
# SAML example (ADFS)
SSO_ENABLED=true \
NEXT_PUBLIC_APP_URL=https://your-instance.com \
SSO_PROVIDER_TYPE=saml \
SSO_PROVIDER_ID=adfs \
SSO_ISSUER=https://adfs.company.com/adfs/services/trust \
SSO_SAML_AUDIENCE=https://your-instance.com \
SSO_DOMAIN=company.com \
SSO_USER_EMAIL=admin@company.com \
SSO_SAML_ENTRY_POINT=https://adfs.company.com/adfs/ls \
SSO_SAML_CERT="-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----" \
bun run packages/db/scripts/register-sso-provider.ts
```

The script outputs the callback URL to configure in your IdP once it completes.

To remove a provider:

```bash
SSO_USER_EMAIL=admin@company.com \
bun run packages/db/scripts/deregister-sso-provider.ts
```
Register providers through the **Settings UI**, the same flow as cloud. Verify the email domain first: a provider is only saved against a domain the organization has verified, which is what authorizes it to sign people in.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Three places once the deployment is configured for production. Everything else i
</Callout>

<Callout type="error">
`ENCRYPTION_KEY` is not recoverable and not derivable. It encrypts workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets at rest — a database restore paired with a *different* key yields a working app in which none of that can be decrypted. Back it up separately from the database, and never rotate it casually.
`ENCRYPTION_KEY` is not recoverable and not derivable. It encrypts workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, deployment/chat secrets, and SSO provider secrets at rest — a database restore paired with a *different* key yields a working app in which none of that can be decrypted. Back it up separately from the database, and never rotate it casually.
</Callout>

Redis is a cache and message bus. Losing it drops in-flight live updates; it does not lose committed data.
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/platform/self-hosting/docker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ EOF
</Callout>

<Callout type="error">
Save `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` somewhere outside this server. `ENCRYPTION_KEY` encrypts workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets; `API_ENCRYPTION_KEY` encrypts user-generated Sim API keys. Neither can be regenerated — a database restore paired with a different key leaves the data it protected permanently unreadable.
Save `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` somewhere outside this server. `ENCRYPTION_KEY` encrypts workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, deployment/chat secrets, and SSO provider secrets; `API_ENCRYPTION_KEY` encrypts user-generated Sim API keys. Neither can be regenerated — a database restore paired with a different key leaves the data it protected permanently unreadable.
</Callout>

The compose file refuses to start if `BETTER_AUTH_SECRET`, `ENCRYPTION_KEY`, `INTERNAL_API_SECRET`, or `POSTGRES_PASSWORD` is missing, rather than booting with empty or well-known values. Postgres applies `POSTGRES_PASSWORD` only when it first creates the database volume — see [Postgres on Compose](/platform/self-hosting/security#postgres-on-compose) before changing it on an existing install. `CRON_SECRET` is treated more gently: without it the `cron` service prints what to set and exits, leaving the rest of the stack running — so upgrading from a compose file that predates the scheduler still works.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Callout } from 'fumadocs-ui/components/callout'
`openssl rand -hex 32` prints 64 hex characters. `ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` must be exactly that — a value of any other shape throws the first time Sim encrypts or decrypts, not at startup. The rest are secrets of no fixed shape and only need 32 characters or more. The Sim app never checks — it runs its env schema with validation skipped — but the realtime service validates `BETTER_AUTH_SECRET` and `INTERNAL_API_SECRET` at boot and refuses to start if either is shorter.

<Callout type="error">
`ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` cannot be rotated or recovered. Losing either makes the data it protects permanently unreadable — workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, and deployment/chat secrets in the first case, user-generated Sim API keys in the second. Back them up separately from the database.
`ENCRYPTION_KEY` and `API_ENCRYPTION_KEY` cannot be rotated or recovered. Losing either makes the data it protects permanently unreadable — workspace and personal environment variables, stored provider API keys, MCP OAuth credentials, deployment/chat secrets, and SSO provider secrets in the first case, user-generated Sim API keys in the second. Back them up separately from the database.
</Callout>

## Strongly recommended
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/platform/self-hosting/kubernetes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ helm install sim oci://ghcr.io/simstudioai/charts/sim \
```

<Callout type="warn">
Save all six values somewhere durable before moving on. `ENCRYPTION_KEY` in particular cannot be regenerated — losing it makes workspace environment variables and stored provider keys permanently unreadable.
Save all six values somewhere durable before moving on. `ENCRYPTION_KEY` in particular cannot be regenerated — losing it makes workspace environment variables, stored provider keys, and SSO provider secrets permanently unreadable.

`API_ENCRYPTION_KEY` is optional, and the failure mode is silent: leave it unset and Sim stores user-generated API keys **in plain text**, logging one warning and nothing else. Set it at install time — it must be a 64-character hex string, which is exactly what `openssl rand -hex 32` produces — and back it up like `ENCRYPTION_KEY`.

Expand Down Expand Up @@ -102,7 +102,7 @@ Signing is Sigstore-only — there is no GPG `.prov` file, so `helm install --ve

## Cloud-Specific Values

These are cloud-tuned **alternatives** to the generic install above — pick one path, don't run both. The commands reuse the `$BETTER_AUTH_SECRET`, `$ENCRYPTION_KEY`, `$INTERNAL_API_SECRET`, `$API_ENCRYPTION_KEY`, `$CRON_SECRET`, and `$POSTGRES_PASSWORD` variables generated in [Installation](#installation) above, so run that block's `openssl` lines first in the same shell. They use `helm upgrade --install`, so they work whether or not a release exists yet. Two caveats when converting an existing generic install rather than starting fresh: (1) **reuse the original secret values** — recover them with `helm get values sim -n simstudio` if your shell no longer has them; supplying a newly generated `ENCRYPTION_KEY` makes every previously encrypted value (workspace environment variables, stored provider keys, MCP OAuth credentials) undecryptable. (2) The cloud values rename the bundled PostgreSQL database to `simstudio`, but Postgres only applies that setting on first initialization — add `--set postgresql.auth.database=sim` to keep your existing database. If you'd rather start clean, `helm uninstall sim -n simstudio`, delete its PVCs, and run the cloud command fresh.
These are cloud-tuned **alternatives** to the generic install above — pick one path, don't run both. The commands reuse the `$BETTER_AUTH_SECRET`, `$ENCRYPTION_KEY`, `$INTERNAL_API_SECRET`, `$API_ENCRYPTION_KEY`, `$CRON_SECRET`, and `$POSTGRES_PASSWORD` variables generated in [Installation](#installation) above, so run that block's `openssl` lines first in the same shell. They use `helm upgrade --install`, so they work whether or not a release exists yet. Two caveats when converting an existing generic install rather than starting fresh: (1) **reuse the original secret values** — recover them with `helm get values sim -n simstudio` if your shell no longer has them; supplying a newly generated `ENCRYPTION_KEY` makes every previously encrypted value (workspace environment variables, stored provider keys, MCP OAuth credentials, SSO provider secrets) undecryptable. (2) The cloud values rename the bundled PostgreSQL database to `simstudio`, but Postgres only applies that setting on first initialization — add `--set postgresql.auth.database=sim` to keep your existing database. If you'd rather start clean, `helm uninstall sim -n simstudio`, delete its PVCs, and run the cloud command fresh.

```bash
# The example values files are not part of the packaged chart, so fetch the one
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/platform/self-hosting/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Five secrets drive the security of a deployment. Generate each with `openssl ran
| Secret | Protects | Rotatable |
|---|---|---|
| `BETTER_AUTH_SECRET` | Session tokens | Yes — invalidates all sessions |
| `ENCRYPTION_KEY` | Workspace env vars, stored provider keys, MCP OAuth credentials, deployment/chat secrets | **No** — see below |
| `ENCRYPTION_KEY` | Workspace env vars, stored provider keys, MCP OAuth credentials, deployment/chat secrets, SSO provider secrets | **No** — see below |
| `API_ENCRYPTION_KEY` | Reversible stored copy of user-generated API keys | **No** — existing keys keep authenticating, but their stored copy can no longer be displayed |
| `INTERNAL_API_SECRET` | Service-to-service calls | Yes — roll app and realtime together |
| `CRON_SECRET` | Background job endpoints | Yes — roll app and cron together |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ A document that fails with `vector 0 has N unexpected dimensions` means `EMBEDDI

Integrations show as connected but fail, or provider keys error on decrypt. `ENCRYPTION_KEY` does not match the value in use when the backup was taken. There is no recovery — the original key must be restored.

SSO sign-in fails the same way, since provider secrets are encrypted with the same key. A provider whose secret cannot be decrypted refuses the sign-in rather than sending an unusable secret to the identity provider; re-enter the client secret in organization settings once the correct key is in place.

## Kubernetes: App Pods Never Become Ready

Check the migrations init container first — a failed migration deliberately blocks the rollout:
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/platform/self-hosting/upgrades.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ There is a short window where the app is unavailable while containers restart. C

### Verify

Run the [verification checklist](/platform/self-hosting/verify). At minimum: sign in, open a workflow, execute it, upload a file, and confirm the [background jobs](/platform/self-hosting/background-jobs) are still firing.
Run the [verification checklist](/platform/self-hosting/verify). At minimum: sign in, open a workflow, execute it, upload a file, and confirm the [background jobs](/platform/self-hosting/background-jobs) are still firing. If the deployment uses [SSO](/platform/enterprise/sso), complete one SSO sign-in too — provider secrets are encrypted with `ENCRYPTION_KEY`, so a key that does not match the one they were saved under surfaces here.

</Step>

Expand Down
Loading
Loading