Zitadel Setup
This guide walks through setting up Zitadel as the identity provider for OIDC login and SCIM user provisioning in Open Saasframe.
Zitadel Cloud offers a free tier with up to 25,000 monthly active users.
1. Create a Zitadel Instance
- Go to https://zitadel.com and sign up for a free account
- Create a new instance (or use the default one)
- Note your instance domain:
https://<instance>.zitadel.cloud
2. Create Test Users
- In the Zitadel Console, go to Users -> + New
- Fill in:
- Username: e.g.,
testuser@yourdomain.com - First name / Last name
- Email: the user's email address
- Password: set an initial password
- Username: e.g.,
- Click Create
- Repeat for 2-3 test users
3. Register the OIDC Application
- In the Zitadel Console, go to Projects -> + New
- Name the project
Open Saasframeand click Continue - Click + New Application
- Configure:
| Field | Value |
|---|---|
| Name | Open Saasframe |
| Type | Web |
| Authentication Method | Code (PKCE) |
| Redirect URIs | http://localhost:3000/api/sso/callback/oidc |
| Post-Logout URIs | http://localhost:3000/login |
- Click Create
- On the application overview, note:
- Client ID
- Client Secret (generate one if using Code flow)
OIDC Credentials Summary
| Credential | Where to find it | Value |
|---|---|---|
| Issuer URL | Instance domain | https://<instance>.zitadel.cloud |
| Client ID | Application -> General | Copy from console |
| Client Secret | Application -> General -> Generate | Copy immediately |
| Redirect URI | You configured this | http://localhost:3000/api/sso/callback/oidc |
Configure Token Claims
Zitadel includes email, given_name, family_name, and email_verified in ID tokens by default when the openid, profile, and email scopes are requested. No additional configuration is needed.
Assign Users
By default, all users in the organization can access the application. To restrict access:
- Go to your Project -> Authorizations -> + New
- Select specific users or grant roles
- Enable "Require authorization" on the project settings if you want to restrict access
4. Create the SSO Config in Open Saasframe
- Log into Open Saasframe as admin
- Go to Settings -> Single Sign-On -> Create New
- Select OIDC as the protocol
- Enter:
- Name:
Zitadel - Issuer URL:
https://<instance>.zitadel.cloud - Client ID: (paste from Zitadel)
- Client Secret: (paste from Zitadel)
- Name:
- Add allowed email domains (e.g.,
yourdomain.com) - Test the connection (Verify Discovery)
- Activate the config
Verify OIDC Login
- Open a private/incognito browser window
- Go to the Open Saasframe login page
- Enter an email address belonging to one of your test users
- The HRD check should detect SSO and redirect to Zitadel login
- Authenticate at Zitadel
- You should be redirected back to Open Saasframe and logged in
5. Configure SCIM Provisioning
Generate a SCIM bearer token from Open Saasframe via the admin UI (SSO config -> Provisioning tab -> Generate Token).
Zitadel SCIM Support
Zitadel supports outbound SCIM provisioning through its Actions feature (custom workflows). Zitadel also offers a native SCIM provisioning option:
- Go to your Project -> Open Saasframe application
- Navigate to Provisioning or Actions
- Configure SCIM outbound provisioning:
| Field | Value |
|---|---|
| SCIM Base URL | http://localhost:3000/api/sso/scim/v2 (dev) or https://<your-domain>/api/sso/scim/v2 (prod) |
| Bearer Token | Paste the SCIM token from Open Saasframe |
- Test the connection
Alternative: Manual/API-Based Provisioning
If Zitadel's native SCIM outbound is not available in your version, use the Zitadel Management API to sync users:
- Create a Service User in Zitadel with Management API access
- Use the Zitadel Management API to list users
- Push user changes to Open Saasframe's SCIM endpoint
6. Test the Full Flow
Test OIDC Login
- Navigate to Open Saasframe login
- Enter a test user's email
- Expected: Redirect to Zitadel -> authenticate -> redirect back to Open Saasframe
- Verify the user appears in the Open Saasframe admin panel
Test JIT Provisioning
If SCIM is not configured and JIT is enabled:
- Log in as a new user via OIDC
- Expected: User is automatically created in Open Saasframe with
provisioningMethod: jit - Verify user profile (name, email) matches Zitadel
Test SCIM Provisioning (if configured)
- Create a new user in Zitadel
- Wait for provisioning cycle (or trigger manually)
- Expected: User appears in Open Saasframe with
provisioningMethod: scim - Update the user in Zitadel -> verify changes propagate
- Deactivate the user in Zitadel -> verify deactivation in Open Saasframe
Zitadel SCIM Quirks
| Quirk | Description | How to handle |
|---|---|---|
| Standard-compliant | Zitadel follows SCIM 2.0 spec closely | Standard parsing works |
email_verified claim | Always included in ID tokens | No special handling needed |
| Group claims | Available via project roles | Configure role mappings if needed |
| PKCE support | Natively supports S256 PKCE | Automatically used by Open Saasframe |
Troubleshooting
OIDC login redirects but fails
- Verify the Redirect URI matches exactly:
http://localhost:3000/api/sso/callback/oidc - Check that the Issuer URL matches your instance:
https://<instance>.zitadel.cloud - Verify Client ID and Client Secret
- Check the Zitadel Console -> Events for error details
"redirect_uri_mismatch" error
- Ensure the redirect URI registered in Zitadel matches exactly (including protocol and port)
- No trailing slash differences
- For production, use HTTPS
Users can't log in
- Check that users exist in the same Zitadel organization
- If "Require authorization" is enabled on the project, ensure users have project grants
- Check that the email domain matches the allowed domains in Open Saasframe SSO config
SCIM connection fails
- For local dev, Zitadel needs to reach your server over the internet
- Use ngrok:
ngrok http 3000 - Update the SCIM Base URL to the ngrok URL