ZitadelInstaller — Web
Key: Zitadel
Default Enabled: ✅
Package: SaveApis.Framework.Web
Purpose
Integrates Zitadel as the authentication provider via token introspection (not JWT validation). The installer uses a service account JWT profile to authenticate itself against the Zitadel introspection endpoint and caches token results for 5 minutes.
Note: If
Zitadel:JwtProfileis empty or missing, the installer silently skips registration — no error is thrown. This makes it safe to run without Zitadel in local development while keeping the installer enabled.
What It Does
Builder phase (only when JwtProfile is non-empty):
- Registers a distributed memory cache (for token caching)
- Adds Zitadel introspection as an authentication scheme via
.AddZitadelIntrospection() - Configures:
Authorityfrom configurationJwtProfileloaded from the JSON string- Token caching enabled for 5 minutes
Application phase: none — middleware is provided by AuthenticationInstaller.
Dependencies
| Dependency | Direction | Requirement | Description |
|---|---|---|---|
AuthenticationInstaller |
After | Required | Base auth services must be registered first |
AuthorizationInstaller |
After | Required | Authorization must be registered before Zitadel |
ControllerInstaller |
Before | Optional | |
OpenApiInstaller |
Before | Optional | Adds OAuth2 security scheme to the OpenAPI doc |
ScalarInstaller |
Before | Optional | Pre-selects Zitadel security scheme in Scalar |
Configuration
appsettings.json
{
"Zitadel": {
"Authority": "https://auth.example.com/",
"JwtProfile": "{\"type\":\"serviceaccount\",\"keyId\":\"...\",\"key\":\"-----BEGIN RSA PRIVATE KEY-----\\n...\\n-----END RSA PRIVATE KEY-----\\n\",\"appId\":\"...\",\"clientId\":\"...\"}",
"Scopes": {
"openid": "OpenID Connect",
"profile": "Profile",
"email": "Email",
"urn:zitadel:iam:user:resourceowner": "Organization Name"
}
}
}
Environment Variables
| Variable | Type | Required | Description |
|---|---|---|---|
Zitadel__Authority |
Uri |
Yes | Zitadel instance base URL (trailing slash required) |
Zitadel__JwtProfile |
string |
Yes | Full JSON content of the Zitadel service account key file |
Zitadel__Scopes__openid |
string |
No | Scope label shown in Scalar/OpenAPI |
Zitadel__Scopes__profile |
string |
No | Scope label |
Zitadel__Scopes__email |
string |
No | Scope label |
Zitadel__Scopes__urn:zitadel:iam:user:resourceowner |
string |
No | Scope label |
Example:
Zitadel__Authority=https://auth.example.com/
Zitadel__JwtProfile={"type":"serviceaccount","keyId":"123","key":"-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n","appId":"456","clientId":"789"}
Tip: In production, set
Zitadel__JwtProfilefrom a secret manager (e.g. Kubernetes secret, Azure Key Vault). Never commit the JWT profile JSON to source control.
Default Scopes
When Scopes is not configured, the following defaults are used (visible in the Scalar UI and OpenAPI document):
| Scope | Label |
|---|---|
openid |
OpenID Connect |
profile |
Profile |
email |
|
urn:zitadel:iam:user:resourceowner |
Organization Name |
InstallerContext Extension
installer.WithZitadel(bool enabled = true);
Example — disable in development:
installer.WithZitadel(false);
When Zitadel is disabled, OpenApiInstaller and ScalarInstaller automatically omit the Zitadel OAuth2 security scheme from their output. This is detected via context.Enabled(ZitadelInstaller.Key).
Related
- Web Framework Overview
- AuthenticationInstaller — prerequisite
- AuthorizationInstaller — prerequisite
- OpenApiInstaller — adds Zitadel OAuth2 security scheme to the API doc
- ScalarInstaller — pre-selects Zitadel in the UI