scripts/zitadel-setup.sh once. This page connects your provider, grants the first roles, and explains the settings that keep sign-in safe.
What the setup script configures
The script writes every setting the application reads into your application configuration secret, so you never edit Zitadel settings into
values/jedify-be.yaml. See Settings the application reads.
Connect your identity provider
1
Register Jedify with your identity provider
Decision, in your identity provider’s console. Register a web application that uses the OIDC authorization code flow:When you’re done, note the issuer URL and the client ID, and keep the client secret for the next step.
- Okta
- Microsoft Entra ID
- Google
Create an OIDC web application with the Authorization Code grant type, set its sign-in redirect URI to the value above, and assign the people or groups who should use Jedify. The issuer is your Okta domain, for example
https://example.okta.com.2
Store the client secret in Secret Manager
The script reads the client secret from Secret Manager, so the secret is never typed on a command line or printed. Paste it at the prompt:To verify, list the secret’s versions. Expected: one version,
enabled.3
Add your provider as the sign-in button
Run the setup script again, from the release bundle’s directory, with the same
--org-name as before:--oidc-name is the button’s label (default Okta). The script finds the provider by this name on later runs, so keep it the same. The three --oidc-* connection options go together.Expected: the script prints sign-in button '<name>' - its redirect URI: https://<your Zitadel host>/idps/callback and ends with ==> done. That redirect URI must match the one you registered in step 1.To verify, open https://<your application host> in a browser. Zitadel’s sign-in page shows your provider’s button.4
Grant the first roles
A person signing in for the first time is created with no role, so Jedify shows them nothing. After their first sign-in, grant them a role:The role is one of
Tenant Admin, Data expert or User, spelled exactly like that. Role-Based Access Control describes what each one can do.Expected: alice@example.com now holds 'Tenant Admin' on the jedify project. Roles travel in the sign-in token, so ask the person to sign out and sign in again.The command fails with they must sign in once first until the person has signed in. To grant a role before anyone signs in, create the user in Zitadel’s console, in your organization, with a verified email address; their first sign-in through your provider then links to that user by email.Settings that matter
Self-registration off
Zitadel’s sign-in page offers self-registration by default, so anyone who can reach it can create an account. The setup script turns it off on the instance’s login policy, together with two neighbouring settings: unknown usernames aren’t confirmed (otherwise the page tells a visitor whether an address exists), and nobody signs in by phone. A self-registered account holds no role and sees no data, so this is about unauthenticated account creation, not data access. Hiding a sign-up link in the web app wouldn’t help: the registration form belongs to Zitadel’s sign-in page, so it has to be policy. An organization can override the instance’s login policy. Your organization inherits the instance policy until someone customizes the organization’s login settings in Zitadel’s console; if you do, keep registration off there too.One organization
Your organization holds every person who uses Jedify, and the web app names it:frontend.zitadel.orgId in values/jedify-infra.yaml, which the install set. It adds a scope to every sign-in request that makes Zitadel refuse users from any other organization. Leave it empty only if you deliberately run several organizations on one Zitadel instance.
Pinning your organization doesn’t cost you administrator access. Instance administration lives in Zitadel’s own ZITADEL organization, through Zitadel’s console, which the pin doesn’t touch. The instance administrator can’t sign in to Jedify itself, by design: if someone needs to use the product for support, give them a user in your organization, and keep the administrator identity for administration only.
To sign in to Zitadel’s console as the instance administrator, open https://<your Zitadel host>/ui/console and sign in as admin@zitadel.<your Zitadel host>. The installation generated the password once, into a Kubernetes Secret:
Roles in the token
The script turns on role assertion on thejedify project (projectRoleAssertion). Without it, tokens carry no roles claim, and turning on role assertion only on the application isn’t enough.
The failure is quiet. The API resolves roles through Zitadel’s management API, so it still treats a user as, say, a Tenant Admin. The web app reads roles from the token, so it shows the same user with no roles at all, and nothing reports an error. If you manage the project in Zitadel’s console, keep project-level role assertion on.
HTTPS everywhere
Zitadel builds its own callback URLs fromzitadel.zitadel.configmapConfig.ExternalSecure, which is true in the bundle’s values. Keep it true: with false, Zitadel hands your provider an http:// callback, which Google refuses and Microsoft Entra ID fails with AADSTS500117. TLS ends at the Gateway, so Zitadel’s pods speak plain HTTP inside the cluster while every URL they publish is https.
zitadel.zitadel.configmapConfig.ExternalDomain must equal your Zitadel host exactly. It’s part of the issuer of every token Zitadel mints, and a mismatch answers Instance not found, which looks like a broken client rather than a configuration error.
Settings the application reads
The setup script writes these keys into your application configuration secret. Don’t also set them invalues/jedify-be.yaml: a plain environment variable there overrides the secret’s value.
The application also needs
ZITADEL_PAT, a token for Zitadel’s management API. You don’t set it: Zitadel’s setup job mints it into a Kubernetes Secret, and the platform chart reads it live into the application’s configuration, so a re-minted token propagates on its own. Without it, sign-in works and the first authenticated request fails with a 500.
MCP server sign-in
AI agents and other MCP clients reach Jedify through the MCP server athttps://<your application host>/mcp. The MCP server runs an OAuth authorization server of its own in front of Zitadel, so it needs its own Zitadel application, jedify-mcp, next to the web app’s:
The setup script creates it and records its settings. Three things to keep in mind:
MCP_SERVER_URLis the server root,https://<your application host>, not the/mcppath.- Generate the signing key once. The MCP server signs the tokens it issues with
ZITADEL_MCP_JWT_SIGNING_KEY, so a new key signs every MCP client out. The script keeps the existing key on every run. - The OAuth server answers on nine paths, not one:
/mcp,/authorize,/token,/register,/revoke,/consent,/auth/callback,/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource. The bundle’s values route all nine to the MCP server throughgateway.mcpPathPrefixes. If you override that list, keep all nine: a list in your values replaces the chart’s, and a missing path falls through to the API, which answers404in the middle of an authorization with nothing logged. Both discovery documents must come from the MCP server, or a strict client sees two spellings of the issuer and refuses to connect.
https://<your application host>/mcp as the server URL. The client discovers the MCP server’s authorization endpoints, and your users sign in through Zitadel and your identity provider. MCP Overview describes the tools your users get.