Tenants and access
Prepare tenants and accounts after installing Identity Service.
| Task | What to do |
|---|---|
| Platform clients | The provisioner and Identity Service configure Registry, frontend, and MCP automatically; see Automatic client registration |
| Tenants and people with Zitadel | Verify the chart's recurring import |
| Tenants and people with another provider | Create the tenant, then prepare the accounts |
| First platform administrator | Follow Creating Platform Administrators |
| Secure Connections, if used | Follow Secure Connection Service agent |
Automatic client registration
The provisioner and chart configure Registry, frontend, and MCP automatically.
For existing suffixed client IDs or additional redirect addresses, use the configuration reference:
Tenants
A tenant groups users and agents and controls their access. It has a unique, permanent slug, a changeable display name, and an optional identity-provider organization mapping. Tenant memberships persist when you change providers.
Tenants from the chart's Zitadel import
The import runs on each install and upgrade while Zitadel is selected. It reads organizations the management user belongs to and:
- creates a tenant for each organization, deriving its slug from the organization name (
Acme Corpbecomesacme-corp, with a numeric suffix if needed); - imports the organization's people;
- grants tenant administrator access to people with the Zitadel
customer_adminrole.
Later runs reconcile changes while preserving existing principal IDs. See Zitadel setup for management-key configuration. To skip the import, set identity.idpMigration.enabled: false and create tenants and accounts separately.
When using another provider, set identity.oidc.provider in values even if its credentials are supplied through a Secret, so the chart selects the correct operation.
Checking the import
Check the log and imported accounts after each run. Missing management configuration can skip the import successfully, and partial reads can warn without failing it. Malformed credentials and database failures can fail the Job.
The import skips role grants for machine users and people it has not imported. For a missing person, add the management user to that person's organization with ORG_OWNER_VIEWER, then upgrade again.
The chart deletes the import Job when it succeeds. Before you install or upgrade, set identity.idpMigration.autoCleanupSuccessfulJob: false. The chart then keeps the Job until the next run replaces it. Then read its log (for a release named istari):
kubectl logs job/istari-identity-idp-migrate
Review warning and skipped-grant counts, then list the tenants and verify their users and administrator roles.
For upgrades from chart 6.x, use --reset-then-reuse-values (Helm 3.14 or later) to apply the new defaults:
helm upgrade --reset-then-reuse-values -f istari-values.yaml istari istari-platform-7.1.0.tgz
Listing the tenants
Before a Platform Administrator is available, list tenants directly from the Identity Service database:
kubectl run list-tenants --rm -i --restart=Never \
--image=postgres:15-alpine \
--overrides='{
"spec":{
"containers":[{
"name":"list-tenants",
"image":"postgres:15-alpine",
"command":["psql"],
"args":["$(DATABASE_URL)","-c",
"SELECT t.slug, t.display_name, m.provider_name, m.provider_tenant_id FROM identity_router.tenants t LEFT JOIN identity_router.tenant_provider_mappings m ON m.tenant_id = t.id"],
"env":[{"name":"DATABASE_URL","valueFrom":{"secretKeyRef":{
"name":"istari-identity",
"key":"ISTARI_DIGITAL_IDENTITY_SERVICE_DATABASE_URL"}}}]
}]}
}'
Any image that includes psql works, for example a copy of postgres:15-alpine in your own registry. Change the image name in both --image and the --overrides JSON. If your registry needs credentials, also add imagePullSecrets to the pod spec in the --overrides JSON.
Each row shows the tenant and its organization mapping, if any. For missing organizations, check the import log and management user's memberships, correct the cause, and upgrade again. Create tenants manually when they should be independent of Zitadel.
Creating a tenant
Create tenants in the Identity Service:
- In the web app. A Platform Administrator clicks New tenant on the Platform Admin Console's Tenants page and enters a display name and slug; see Create a tenant.
- With
create-tenant, for when nobody can sign in to the console yet. Run it as a one-off pod (DATABASE_URLcomes from the identity secret; you never type it):
kubectl run create-tenant --rm -i --restart=Never \
--image=istaridigital.jfrog.io/customer-docker/identity-service:<tag> \
--overrides='{
"spec":{
"imagePullSecrets":[{"name":"docker-pull-secret"}],
"containers":[{
"name":"create-tenant",
"image":"istaridigital.jfrog.io/customer-docker/identity-service:<tag>",
"command":["/create-tenant"],
"args":["-database-url","$(DATABASE_URL)",
"-slug","<tenant_slug>",
"-display-name","<Human-Readable Name>"],
"env":[{"name":"DATABASE_URL","valueFrom":{"secretKeyRef":{
"name":"istari-identity",
"key":"ISTARI_DIGITAL_IDENTITY_SERVICE_DATABASE_URL"}}}]
}]}
}'
Re-running with the same slug is safe. Manually created tenants have no provider organization mapping.
Add people using the account import procedure below.
For Zitadel and Keycloak, Add user requires a provider-to-tenant mapping; without one it returns tenant_not_mapped. Okta, PingFederate, and eligible Google Workspace accounts can claim email pre-registrations without an organization mapping. Entra, Lastwall, and personal Google accounts need subject imports instead.
Preparing people for a provider
Import new users into their tenant with the import-humans Job, setting -provider as below. Run with -dry-run, fix rejected rows, then rerun without it. For existing users changing providers, use subject mappings to preserve their accounts.
| Provider | Account preparation |
|---|---|
zitadel | Recurring organization import or prepared verified-email account; retain organization mappings required by the selected enrollment policy |
keycloak | Prepared verified email or authoritative subject; preserve the existing realm/tenant setup |
entra | upstream_subject is the immutable Object ID (oid) |
google | Prefer immutable sub; personal accounts require it. Pending Workspace email claiming also requires email_verified=true and nonempty hd |
lastwall | Immutable sub required; email-only enrollment is never supported |
okta, pingfederate | Immutable sub, or a pending registration with a trusted verified-email assertion |
For subject-based new accounts, the shared CSV is:
email,upstream_subject,tenant_slug
person@example.com,<immutable-provider-subject>,acme
For eligible email-based registrations, omit upstream_subject. Provider-specific requirements still apply under open enrollment. For Zitadel with pre-registered-only, map the tenant to the person's organization using create-tenant -provider-name zitadel -provider-tenant-id <organization id>. For Keycloak's grouping configuration, see Keycloak account preparation.
Grant platform administrator access separately.
If You Use the Secure Connection Service
The provisioner does not generate this optional agent's credentials. Complete Secure Connection Service agent when your installation uses Secure Connections.
Verify a Registration
Check registration through the platform:
- Sign in at
https://<customer_istari_fqdn>. - Generate a key from Developer Settings — Keys or create an agent from the admin Agents page.
To test a key with the Istari CLI:
stari client init "https://api.<customer_istari_fqdn>" --identity-service \
--credentials-file <path_to_key_file> --yes
Run a CLI command to confirm authentication and access.
Supplying the Credentials Yourself
For installations without the provisioner, see Manual setup.
See credential generation, chart installation, installation without the chart, or key rotation.