ProAuth Installation
Helm Chart Deployment
ProAuth is designed to run in a Kubernetes cluster and therefore the main deployment method is a Helm release. Releasing by Helm charts has several advantages.
- The configuration values are defined on a logical level in the values.yaml. The technical details on how those values are consumed during runtime is hidden.
- The Helm releases also take care of initialization actions like database schema deployments. The helm release makes sure that the service only gets deployed after a successful and compatible database schema upgrade.
- Easy release management and rollback features provided by helm.
ProAuth is delivered as two helm charts, one for the backend (core) and one for the admin UI. If you do not host ProAuth in Kubernetes, then you need to configure the containers directly and make sure the appropriate initialization logic (database, UI configuration) has been executed at the right point in time of the startup. Please refer to the chapter @sec:containerruntimeenvironment for detailed information.
ProAuth Helm Chart Values
Application setting values
This section contains most important settings.
- License data
- Please provide a valid license string in order to use ProAuth.
- ProAuthRoot
- ProAuth provides a root client application with an initial random client secret if the
ClientAppSecretis not set explicitly during deployment. - To enable and use SCIM in ProAuth in general, the SCIM token security key
ScimTokenSecurityKeymust be set. The SCIM token security key must have a minimum length of128 bit(16 chars). This security key is needed to create individual SCIM tokens for the IDP instances where SCIM will be enabled and to verify the security token of every incoming SCIM request. - ProAuth needs a default certificate to sign and encrypt tokens within the OIDC flow. The default certificate needs to be provided through application settings, at least at the initial startup of ProAuth. More certificates can then either be managed by API or UI.
- ProAuth provides a root client application with an initial random client secret if the
- Encryption keys are used to encrypt critical information in ProAuth data stores. A valid X.509 certificate is needed. If a key rotation is necessary, the old certificates can be listed under keyrotationdecryptioncertificates. This enables the system to decrypt old values while already using the new key pair for all current encryption / decryption actions.
- The data section contains the database provider, connection string, and command timeout for the ProAuth database.
- The base service settings contain general settings for the service to run.
licensedata: content of the license data fileclientappsecret: ProAuth Root client secret; when empty a random value will be generatedscimtokensecuritykey: necessary when SCIM is used; security key to create the SCIM endpoint tokens- The encryption algorithm requires a key size of at least
128 bits(16 chars)
- The encryption algorithm requires a key size of at least
requirehttpsmetadata: default set totruesessionidletimeout: session timeout in minutes; default set to20jobqueueinterval: job queue interval execution in hours; default set to4emailsenderaddress,mailserverconfig: when provided, it is used as default option value on all supported types- mail server config is a JSON definition, quotes needs to be escaped (JSON Samples are provided in the corresponding chapters)
- Tenant (@sec:tenant-configure)
- UserStore IDP (@sec:userstore-configure)
- E-Mail MFA (@sec:mfa-email-configure)
- mail server config is a JSON definition, quotes needs to be escaped (JSON Samples are provided in the corresponding chapters)
knownproxies: comma separated list of IP addresses of proxies used for x-forwarded-for headerknownnetworks: comma separated list CIDR ranges of networks used for x-forwarded-for headerforwardlimit: maximum number of forwarded header entries processed from each header; default set to1crossoriginembedderpolicy(optional): controls theCross-Origin-Embedder-Policyheader; defaultRequireCorp. Set toUnsafeNonewhen using hCaptcha or Friendly Captcha (see CAPTCHA Protection)- Redis/state-store token backend (only effective when Dapr is enabled and a state store component is configured):
tokenstatestorettlafterrevocationinseconds(optional): how long revoked tokens remain in Redis before automatic removal; default120seconds. Set to0for immediate hard-deletion. See Token Lifecycle & Performance Tuning.usertokensmaxconcurrencyretries(optional): max optimistic-concurrency retries for per-user token index updates in multi-instance deployments; default8. See Token Lifecycle & Performance Tuning.
- Database token backend (only effective when Dapr is disabled):
tokenstorepruneintervalinminutes(optional): minutes between background token-prune job runs; default60. See Token Lifecycle & Performance Tuning.
- The enhanced logging configuration enables detailed logs for error analysis and is normally only used by a 4tecture representative.
appsettings:
license:
licensedata: VALUE_TO_OVERRIDE
proauthroot:
clientappsecret:
scimtokensecuritykey:
# defaultcertvalue: VALUE_TO_OVERRIDE
# defaultcertpassword: VALUE_TO_OVERRIDE
encryptionkeys:
mode: "" ## empty to disable, currently supported X509
certificate: ""
certificatepassword: ""
keyrotationdecryptioncertificates: []
#- certificate: ""
# certificatepassword: ""
#- certificate: ""
# certificatepassword: ""
data:
defaultconnection:
provider: SqlServer
connectionstring: VALUE_TO_OVERRIDE
commandtimeoutinseconds: VALUE_TO_OVERRIDE
baseservicesettings:
hosturl: VALUE_TO_OVERRIDE
#requirehttpsmetadata: VALUE_TO_OVERRIDE
#sessionidletimeout: VALUE_TO_OVERRIDE
#jobqueueinterval: VALUE_TO_OVERRIDE
emailsenderaddress:
mailserverconfig:
forwardlimit: 1
#knownproxies: ""
#knownnetworks: ""
# Redis/state-store token backend (Dapr enabled):
#tokenstatestorettlafterrevocationinseconds: 120
#usertokensmaxconcurrencyretries: 8
# Database token backend (Dapr disabled):
#tokenstorepruneintervalinminutes: 60
enhancedlogging:
enabled: false
logsensitivedata: falseFor Kubernetes Secret based certificate provisioning, prefer mounted certificate files:
certificateSecrets:
defaultCertificate:
enabled: true
secretName: proauth-default-certificate
type: pem
certificateKey: tls.crt
privateKeyKey: tls.key
dataProtectionCertificate:
enabled: true
secretName: proauth-dataprotection-certificate
type: pem
certificateKey: tls.crt
privateKeyKey: tls.key
dataProtectionDecryptionCertificates:
- secretName: proauth-dataprotection-old
type: pem
certificateKey: tls.crt
privateKeyKey: tls.keyThe chart mounts these Secrets into both the database deployment job and the ProAuth runtime and sets the corresponding ProAuthRoot:DefaultCertificate and EncryptionKeys:CertificateInput file-path settings. Legacy defaultcertvalue / defaultcertpassword and encryptionkeys.certificate / certificatepassword values remain supported.
For inline Helm values or external Secret values, the ProAuth CLI can generate password-protected PKCS#12 certificates:
proauthcli crypto token-signing-cert generate --kid proauth-default-token-signing --format helm
proauthcli crypto data-protection-cert generate --format helmToken-signing certificates support RSA and EC keys:
proauthcli crypto token-signing-cert generate --algorithm ec --curve P-384 --kid proauth-default-token-signing --format helmData-protection key encryption certificates must use RSA.
appsettings.data.defaultconnection.provider selects the database provider for the whole ProAuth installation. Supported values are SqlServer and PostgreSql. The matching environment variable name is Data__DefaultConnection__Provider. The provider is global: the ProAuth database and all UserStore databases must use the same provider. UserStore connection strings can still use aliases, but they do not define their own provider.
ProAuth creates its own database objects in the proauth schema. UserStore database objects are created in the userstore schema. This also allows ProAuth and UserStore objects to be hosted in the same physical database when both connection strings point to that database.
Dapr settings
If ProAuth is hosted in a cluster with multiple instances, we rely on Dapr for the communication between services, event handling and shared state data.
If dapr.enabled is set to true, a valid dapr configuration needs to be provided. You can either let the helm chart generate a valid dapr configuration for using Redis. If a custom dapr configuration is desired, set the flag deployDefaultComponents to false.
When deployDefaultComponents is true, the chart will create Dapr components for you using the names specified below. The generated components include
scopesto restrict each component to the appropriate Dapr app ID.When deployDefaultComponents is false, the chart will NOT create any Dapr components and will reference pre-existing components ONLY by name. You must pre-create components that match the configured names. When providing your own components, you should add appropriate
scopesto each component to ensure they are only loaded by the intended application sidecars.redisHost: sample valueredis-ha-haproxy.redis:6379
dapr:
enabled: false
id: proauth
nameStateStore: "proauthstatestore"
namePubSub: "proauthglobalevents"
nameDbDeploymentWorkerPubSub: "proauth-db-deployment-worker-pubsub"
deployDefaultComponents: true
defaultComponents:
redisHost: VALUE_TO_OVERRIDE
redisPassword: VALUE_TO_OVERRIDE
redisDB: 0
maxLenApprox: 100Dapr component requirements and delivery patterns
When you bring your own Dapr components (deployDefaultComponents=false), create them with the exact names configured above and ensure they satisfy the following requirements for ProAuth (backend):
- StateStore: any supported Dapr state store (no special metadata required)
- PubSub (global events): PubSub component with metadata consumerID set to {uuid}. This ensures cache invalidation and pipeline reload events are fanned out to every ProAuth instance. For Redis Streams, set metadata:
- consumerID:
- PubSub for DB Deployment Worker: PubSub component that points to the same backend service as the global PubSub. Here we require the competing consumer pattern so only one worker instance processes a given event. For Redis Streams, use a shared consumer/group (do not set consumerID to a unique value per instance).
Scoping: Each component should include a scopes section restricting it to the correct Dapr app ID. The ProAuth chart uses the following app IDs:
proauth— for the main ProAuth backend (StateStore and PubSub)<fullname>-db-deployment-worker— for the DB Deployment Worker (Worker PubSub), for exampleproauth-db-deployment-worker
Example:
spec:
# ... component spec ...
scopes:
- "proauth"Sample Dapr components (ProAuth)
The following example shows a typical set of components when using Redis. Adjust names and secret references to match your environment.
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauthstatestore"
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha-haproxy.redis:6379"
- name: redisPassword
secretKeyRef:
name: proauth-dapr-secrets
key: redis-password
- name: ttlInSeconds
value: 1800
- name: redisDB
value: "0"
scopes:
- "proauth"
---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauthglobalevents"
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha-haproxy.redis:6379"
- name: redisPassword
secretKeyRef:
name: proauth-dapr-secrets
key: redis-password
- name: consumerID
value: "{uuid}"
- name: redisDB
value: "0"
- name: maxLenApprox
value: "100"
scopes:
- "proauth"
---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauth-db-deployment-worker-pubsub"
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha-haproxy.redis:6379"
- name: redisDB
value: "0"
- name: redisPassword
secretKeyRef:
name: proauth-dapr-secrets
key: redis-password
- name: maxLenApprox
value: "100"
- name: processingTimeout
value: "300s"
scopes:
- "proauth-db-deployment-worker"Azure Identity
If ProAuth is hosted in Azure, the Pods can be run with a dedicated Azure Managed Identity. This enables a password-less configuration for the access to other resources in Azure (i.e. Azure SQL, ...). Since the database deployment needs higher access rights, there is a dedicated identity configuration for the database deployment. Please provide the appropriate data.
azureidentity:
enabled: false
name: VALUE_TO_OVERRIDE
resourceID: VALUE_TO_OVERRIDE
clientID: VALUE_TO_OVERRIDE
dbdeployazureidentity:
enabled: false
name: VALUE_TO_OVERRIDE
resourceID: VALUE_TO_OVERRIDE
clientID: VALUE_TO_OVERRIDEUserStore DB Deployment Worker
ProAuth provides a worker container which is able to automatically create and configure databases for newly created UserStore IDPs. To enable the deployment of this DB deployment worker container, enable it in the configuration.
dbdeployment: the group where all the DB Deployment Worker settings are configured
dbdeploymentworker:
enabled: trueThe database worker needs permissions to create databases and users in the target database server. Those settings depend on the target database server and overall security setup. Currently, the following target environments are supported: AzureSql, SqlServer, and PostgreSql.

The different configuration options are due to provider-specific database creation and user creation requirements. During a deployment, there is a dedicated job running to update the schemas of all existing databases. This job either runs with a database user or with a managed identity. The same concept applies for the database worker.
- For Azure SQL, database creation is usually performed through the Azure API. Therefore, a user or identity with permissions to create databases through the Azure API is required. This can be either of the following:
- The pod identity (if configured, the db deployment identity is used)
- A dedicated service principal which is only used for creating the database. This is the preferred approach, since the pod identity for schema deployment does usually not have database creation permissions.
- If the access to the database is authenticated by managed identities, the DB creation and user creation must be performed by either the pod identity or a dedicated service principal. A managed identity based user can only be created by a user which has
Directory Readerpermissions on the AAD tenant. This is not the case for SQL users. - If the access to SQL Server or PostgreSQL is authenticated by database users, there is no need for a pod identity. The configured database administrative connection is used to create databases and users or roles. The schema deployment is always performed by the schema deployment user.
If the databases are hosted on Azure SQL, the database worker needs the required authentication settings for accessing the Azure API.
dbdeploymentworker.azuresqltenantid,clientid,clientsecret: AAD service principal (or client app) with proper permissions. If managed identities will be configured, this user needs directory read permissions.subscriptionid: The Azure Subscription ID in which the Azure SQL resources are hostedresourcegroupname: The resource group name which contains the Azure SQL instancesqlservername: The Azure SQL server nameelasticpoolname: if provided, the new UserStore databases are created in this elastic pool- Managed Identity authentication:
- if Managed Identity is enabled for ProAuth (
azureidentity.enabled,dbdeployazureidentity.enabled), the security (users and roles) of the newly created databases will be targeting those managed identities
- if Managed Identity is enabled for ProAuth (
- SQL Server user login:
dbuser,dbpassword: database user which is created and assigned for Read/Write accessdeploymentuser,deploymentpassword: database user which is created and assigned for schema deployment when deploy ProAuth updates
- Managed Identity users have priority over SQL Server users, if both are configured
dbdeploymentworker:
azuresql:
tenantid: VALUE_TO_OVERRIDE
clientid: VALUE_TO_OVERRIDE
clientsecret: VALUE_TO_OVERRIDE
subscriptionid: VALUE_TO_OVERRIDE
resourcegroupname: VALUE_TO_OVERRIDE
sqlservername: VALUE_TO_OVERRIDE
elasticpoolname: null
#dbuser: null
#dbpassword: null
#deploymentuser: null
#deploymentpassword: nullIf the databases are hosted on a MS SQL Server, the database worker needs the required DB server permissions (roles) to create and configure the databases.
dbdeploymentworker.sqlserverconnectionstring: The connection string to the SQL Serverdbuser,dbpassword: SQL Server login which is created and assigned for Read/Write accessdeploymentuser,deploymentpassword: SQL Server login which is created and assigned for schema deployment when deploy ProAuth updates- The created database users use
userstoreas their default schema for UserStore databases.
dbdeploymentworker:
sqlserver:
connectionstring: VALUE_TO_OVERRIDE
dbuser: null
dbpassword: null
deploymentuser: null
deploymentpassword: nullIf the databases are hosted on PostgreSQL, the database worker needs a PostgreSQL administrative connection string which can create databases and roles.
dbdeploymentworker.postgresqlconnectionstring: The administrative PostgreSQL connection stringadmindatabase: The PostgreSQL database used for administrative operations such as creating databases and roles. Defaults topostgres. Override this when the PostgreSQL provider uses a different maintenance database.dbuser,dbpassword: PostgreSQL role which is created and assigned for Read/Write accessdeploymentuser,deploymentpassword: PostgreSQL role which is created and assigned for schema deployment when deploying ProAuth updates- The created database users are granted access to the
userstoreschema for UserStore databases.
dbdeploymentworker:
targetenvironment: PostgreSql
postgresql:
connectionstring: VALUE_TO_OVERRIDE
admindatabase: postgres
dbuser: null
dbpassword: null
deploymentuser: null
deploymentpassword: nullIf the database needs to be deleted when the UserStore IPD is removed or the UserStore ConnectionString is deleted, this can be enabled by setting the flag enabledeletionofuserstoredatabases.
dbdeploymentworker:
enabledeletionofuserstoredatabases: falseINFO
The database will only be deleted when there is no other usage of the same database in another UserStore IDP connection string.
External Secrets Configuration
ProAuth Helm charts support using pre-created Kubernetes Secrets instead of creating them automatically during deployment. In ProAuth 3.x, Secret keys are direct .NET configuration environment variable names, for example Data__DefaultConnection__ConnectionString.
Use Secrets only for confidential values. Non-secret settings that must be prepared before deployment should be provided through externalConfig as appsettings.overrides.json; non-secret values supplied through Helm are rendered as plain environment variables by the chart.
How External Secrets Work
When external Secrets are enabled, the chart will:
- Attempt to discover existing Secrets using Kubernetes API lookup.
- Fall back to configured
keyswhen lookup is unavailable, for example duringhelm template, CI/CD, or parent-chart rendering. - Reference your external Secrets instead of creating new ones.
ProAuth Core Chart External Secrets
By default, the ProAuth chart creates v3 Secrets automatically based on the values provided in values.yaml. You can configure the chart to reference external, pre-created Secrets for each responsibility.
| Secret group | Default generated name | Responsibility |
|---|---|---|
runtime | <fullname>-runtime | Runtime confidential values used by ProAuth and the schema deployment job |
crypto | <fullname>-crypto | ProAuthRoot secrets, default signing certificate, and data-protection/encryption certificates |
dbSchemaDeployment | <fullname>-db-schema-deployment | Optional schema deployment override user/password |
dbWorkerSqlserver | <fullname>-db-worker-sqlserver | SQL Server database worker credentials |
dbWorkerAzuresql | <fullname>-db-worker-azuresql | Azure SQL database worker credentials |
dbWorkerPostgresql | <fullname>-db-worker-postgresql | PostgreSQL database worker credentials |
ProAuth Core Chart Resource Names And Labels
The chart labels rendered resources with the standard Helm and Kubernetes application labels: helm.sh/chart, app.kubernetes.io/name, app.kubernetes.io/instance, app.kubernetes.io/version, app.kubernetes.io/managed-by, app.kubernetes.io/part-of, and app.kubernetes.io/component.
Common selectors:
- Runtime pods:
app.kubernetes.io/name=<chart-name>,app.kubernetes.io/component=identity-server - Database deployment worker pods:
app.kubernetes.io/name=<chart-name>,app.kubernetes.io/component=db-deployment-worker
Default generated support resource names:
| Resource | Default generated name |
|---|---|
| Main service account | <fullname> |
| Deployment job service account | <fullname>-deploy |
| Database management service account | <fullname>-db-management |
| Wait-for RBAC role and binding | <fullname>-wait-for |
| Initializer job | <fullname>-initializer-<version-or-revision> |
| Database deployment worker StatefulSet | <fullname>-db-deployment-worker |
| Azure identity binding | <fullname>-azure-identity-binding |
| Initializer Azure identity binding | <fullname>-initializer-azure-identity-binding |
ProAuth Core Pod Topology Spread Constraints
The ProAuth Core chart supports Kubernetes topologySpreadConstraints for the runtime Deployment. Use this when you want ProAuth replicas to be distributed across nodes, availability zones, or another topology label.
By default, topologySpreadConstraints is empty and the chart does not add explicit scheduling constraints. When a constraint omits labelSelector, the chart automatically adds the runtime pod selector: app.kubernetes.io/name=<chart-name>, app.kubernetes.io/instance=<release-name>, and app.kubernetes.io/component=identity-server.
Example that prefers spreading replicas across zones while keeping pods schedulable:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnywayExample that enforces spreading replicas across nodes:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotScheduleUse DoNotSchedule carefully. If the cluster has too few eligible nodes or is missing the selected topology labels, new pods can remain pending.
externalSecrets:
runtime:
enabled: false
secretName: ""
keys: []
crypto:
enabled: false
secretName: ""
keys: []
dbSchemaDeployment:
enabled: false
secretName: ""
keys: []
dbWorkerSqlserver:
enabled: false
secretName: ""
keys: []
dbWorkerAzuresql:
enabled: false
secretName: ""
keys: []
dbWorkerPostgresql:
enabled: false
secretName: ""
keys: []Required and Optional Keys
Only include keys that exist in your Secret.
Runtime (runtime):
Data__DefaultConnection__ConnectionString
Data__UserStoreConnections__ConnectionStringAliases__<alias>
License__LicenseData
BaseServiceSettings__MailServerConfigBaseServiceSettings__MailServerConfig commonly contains SMTP credentials and therefore remains in the runtime Secret. Other base service settings should be supplied as non-secret settings.
Crypto (crypto):
ProAuthRoot__ClientAppSecret
ProAuthRoot__ScimTokenSecurityKey
ProAuthRoot__DefaultCertValue
ProAuthRoot__DefaultCertPassword
ProAuthRoot__DefaultCertificate__Base64Pkcs12
ProAuthRoot__DefaultCertificate__Password
EncryptionKeys__Certificate
EncryptionKeys__CertificatePassword
EncryptionKeys__CertificateInput__Base64Pkcs12
EncryptionKeys__CertificateInput__Password
EncryptionKeys__KeyRotationDecryptionCertificates__<index>__Certificate
EncryptionKeys__KeyRotationDecryptionCertificates__<index>__CertificatePasswordPEM and file-path certificate input keys use the same direct naming pattern, for example EncryptionKeys__CertificateInput__PemCombined or EncryptionKeys__CertificateInput__PemCombinedFilePath.
Schema deployment (dbSchemaDeployment):
ProAuthDbSchemaDeployment__User
ProAuthDbSchemaDeployment__PasswordSQL Server worker (dbWorkerSqlserver):
SqlServer__ConnectionString
SqlServer__DbUser
SqlServer__DbPassword
SqlServer__DbUserSecondary
SqlServer__DbPasswordSecondary
SqlServer__DeploymentUser
SqlServer__DeploymentPassword
SqlServer__DeploymentUserSecondary
SqlServer__DeploymentPasswordSecondaryAzure SQL worker (dbWorkerAzuresql):
AzureSql__ClientSecret
AzureSql__SqlAdminUser
AzureSql__SqlAdminPassword
AzureSql__DbUser
AzureSql__DbPassword
AzureSql__DbUserSecondary
AzureSql__DbPasswordSecondary
AzureSql__DeploymentUser
AzureSql__DeploymentPassword
AzureSql__DeploymentUserSecondary
AzureSql__DeploymentPasswordSecondaryPostgreSQL worker (dbWorkerPostgresql):
PostgreSql__ConnectionString
PostgreSql__DbUser
PostgreSql__DbPassword
PostgreSql__DeploymentUser
PostgreSql__DeploymentPasswordConfiguration Best Practices
1. Always Specify keys
To ensure reliable deployment across all scenarios, always specify the keys field with the direct environment variable keys that exist in your external Secret:
externalSecrets:
runtime:
enabled: true
secretName: "proauth-runtime"
keys:
- Data__DefaultConnection__ConnectionString
- Data__UserStoreConnections__ConnectionStringAliases__DefaultUserStoreConnection
- License__LicenseData2. Use Consistent Secret Naming
Adopt a consistent naming pattern for your external Secrets:
externalSecrets:
runtime:
secretName: "proauth-runtime"
crypto:
secretName: "proauth-crypto"
dbSchemaDeployment:
secretName: "proauth-db-schema-deployment"3. Keep Non-Secret Settings Out Of Secrets
Use Helm values or externalConfig for non-secret settings such as the provider, command timeout, host URL, email sender address, forwarded headers, known proxies, and deployment environment.
Examples
Example 1: Runtime and crypto Secrets
Create your Secrets manually:
kubectl create secret generic proauth-runtime \
--from-literal=Data__DefaultConnection__ConnectionString="Server=myserver;Database=proauth;User Id=user;Password=pass;" \
--from-literal=Data__UserStoreConnections__ConnectionStringAliases__DefaultUserStoreConnection="Server=myserver;Database=userstore;User Id=user;Password=pass;" \
--from-literal=License__LicenseData="<license-data>"
kubectl create secret generic proauth-crypto \
--from-literal=ProAuthRoot__ClientAppSecret="<client-secret>" \
--from-literal=ProAuthRoot__ScimTokenSecurityKey="<scim-token-key>" \
--from-literal=ProAuthRoot__DefaultCertValue="<base64-pfx>" \
--from-literal=ProAuthRoot__DefaultCertPassword="<password>" \
--from-literal=EncryptionKeys__Certificate="<base64-pfx>" \
--from-literal=EncryptionKeys__CertificatePassword="<password>"Configure your values.yaml:
externalSecrets:
runtime:
enabled: true
secretName: "proauth-runtime"
keys:
- Data__DefaultConnection__ConnectionString
- Data__UserStoreConnections__ConnectionStringAliases__DefaultUserStoreConnection
- License__LicenseData
crypto:
enabled: true
secretName: "proauth-crypto"
keys:
- ProAuthRoot__ClientAppSecret
- ProAuthRoot__ScimTokenSecurityKey
- ProAuthRoot__DefaultCertValue
- ProAuthRoot__DefaultCertPassword
- EncryptionKeys__Certificate
- EncryptionKeys__CertificatePassword
appsettings:
data:
defaultconnection:
provider: SqlServer
commandtimeoutinseconds: 30
baseservicesettings:
hosturl: "https://idp.example.com"
emailsenderaddress: "no-reply@example.com"Example 2: Pre-created non-secret settings
kubectl create configmap proauth-overrides \
--from-file=appsettings.overrides.json=./appsettings.overrides.jsonexternalConfig:
enabled: true
existingConfigMap: proauth-overrides
key: appsettings.overrides.json
mountPath: /appExample 3: Complete External Secrets Configuration
externalSecrets:
runtime:
enabled: true
secretName: "proauth-runtime"
keys:
- Data__DefaultConnection__ConnectionString
- Data__UserStoreConnections__ConnectionStringAliases__DefaultUserStoreConnection
- License__LicenseData
- BaseServiceSettings__MailServerConfig
crypto:
enabled: true
secretName: "proauth-crypto"
keys:
- ProAuthRoot__ClientAppSecret
- ProAuthRoot__ScimTokenSecurityKey
- ProAuthRoot__DefaultCertValue
- ProAuthRoot__DefaultCertPassword
- EncryptionKeys__Certificate
- EncryptionKeys__CertificatePassword
dbSchemaDeployment:
enabled: true
secretName: "proauth-db-schema-deployment"
keys:
- ProAuthDbSchemaDeployment__User
- ProAuthDbSchemaDeployment__Password
dbWorkerSqlserver:
enabled: true
secretName: "proauth-db-worker-sqlserver"
keys:
- SqlServer__ConnectionString
- SqlServer__DbUser
- SqlServer__DbPassword
- SqlServer__DeploymentUser
- SqlServer__DeploymentPasswordUsing ProAuth as a Subchart
When using ProAuth as a subchart in a larger Helm deployment, external secrets are particularly useful. Ensure that:
- Create secrets before ProAuth deployment: Use Helm hooks or dependency ordering to ensure your secrets exist before ProAuth is deployed
- Always specify the keys configuration: This is crucial for subchart scenarios where secret lookup may not work during template rendering
- Use proper namespace: Ensure secrets are created in the same namespace where ProAuth will be deployed
Example parent chart structure:
# In parent chart values.yaml
proauth:
externalSecrets:
runtime:
enabled: true
secretName: "shared-proauth-runtime"
keys:
- Data__DefaultConnection__ConnectionString
- License__LicenseData
# In parent chart templates/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: shared-proauth-runtime
namespace: {{ .Release.Namespace }}
type: Opaque
data:
Data__DefaultConnection__ConnectionString: {{ .Values.database.connectionString | b64enc | quote }}
License__LicenseData: {{ .Values.proauthLicense | b64enc | quote }}Troubleshooting External Secrets
If you encounter issues with external secrets:
Verify secret existence: Ensure your external secret exists in the correct namespace
bashkubectl get secret your-secret-name -n your-namespaceCheck secret keys: Verify the secret contains the expected keys
bashkubectl get secret your-secret-name -n your-namespace -o jsonpath='{.data}' | jq 'keys'Validate configuration: Ensure your
keysconfiguration matches the actual keys in your secretTest template rendering: Use
helm templateto verify the configuration works correctlybashhelm template test-release ./proauth -f your-values.yaml
Migration from Internal to External Secrets
To migrate from chart-created Secrets to external Secrets:
- Create your external Secrets with the v3 direct environment variable keys.
- Enable external Secrets in your values.yaml with proper
keysconfiguration. - Move non-secret settings to Helm values or
externalConfig. - Test the deployment in a non-production environment first
This approach gives you full control over secret management while maintaining the flexibility and ease of use of the ProAuth Helm chart.
External Service Accounts Configuration
Both ProAuth Helm charts now support using pre-created Kubernetes service accounts instead of creating them automatically during deployment. This is useful for organizations that want to manage service accounts and their RBAC permissions separately from the Helm deployment process.
ProAuth Core Chart External Service Accounts
By default, the ProAuth chart creates all necessary service accounts automatically. However, you can configure the chart to reference external, pre-created service accounts for specific workloads.
The external service accounts configuration is controlled through the externalServiceAccounts section:
externalServiceAccounts:
# Main service account configuration (used by the main ProAuth deployment)
# This service account needs permissions for basic Kubernetes API access and k8s-wait-for functionality
# Required RBAC: Role with access to services, pods (get, watch, list) and jobs (get, watch, list)
main:
enabled: false # Set to true to use an external service account
name: "" # Name of the external service account to use
# Deploy service account configuration (used by database deployment jobs)
# This service account needs permissions for job management and k8s-wait-for functionality
# Required RBAC: Role with access to services, pods (get, watch, list) and jobs (get, watch, list)
deploy:
enabled: false # Set to true to use an external service account
name: "" # Name of the external service account to use
# Database management service account configuration (used by database deployment worker stateful set)
# This service account is used for database management operations
# Required RBAC: Depends on your specific database management requirements
dbManagement:
enabled: false # Set to true to use an external service account
name: "" # Name of the external service account to useImportant Notes:
- When using external service accounts, you are responsible for creating the necessary RBAC roles and role bindings
- The chart will only create RBAC resources if at least one service account is managed by the chart
- You can mix and match internal and external service accounts as needed
Example: Using External Service Account for Main Deployment
- Create your service account and RBAC manually:
# Create the service account
kubectl create serviceaccount my-proauth-main-sa
# Create the required role (if not exists)
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: proauth-k8s-wait-for
rules:
- apiGroups: [""]
resources: ["services", "pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "watch", "list"]
EOF
# Create the role binding
kubectl create rolebinding my-proauth-main-binding \
--role=proauth-k8s-wait-for \
--serviceaccount=default:my-proauth-main-sa- Configure your
values.yaml:
externalServiceAccounts:
main:
enabled: true
name: "my-proauth-main-sa"
# deploy and dbManagement remain internal (chart-managed)
deploy:
enabled: false
dbManagement:
enabled: falseExample: Using All External Service Accounts
- Create all service accounts and RBAC manually:
# Create service accounts
kubectl create serviceaccount my-proauth-main-sa
kubectl create serviceaccount my-proauth-deploy-sa
kubectl create serviceaccount my-proauth-db-sa
# Create and bind roles (you are responsible for all RBAC when using all external service accounts)
# ... (create appropriate roles and bindings for your requirements)- Configure your
values.yaml:
externalServiceAccounts:
main:
enabled: true
name: "my-proauth-main-sa"
deploy:
enabled: true
name: "my-proauth-deploy-sa"
dbManagement:
enabled: true
name: "my-proauth-db-sa"Deployment Job Resources Configuration
Both ProAuth Helm charts now support configuring resource requests and limits for their respective initializer jobs. This is critical in environments with resource quotas or policies that require all pods to have resource limits.
ProAuth Core Chart - Database Deployment Job
The main ProAuth chart includes a database deployment job that can be configured with resource limits and requests:
# Database deployment job resource configuration
deploymentJobResources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "100m"
memory: "128Mi"Example Usage:
deploymentJobResources:
limits:
cpu: "1000m" # 1 CPU core
memory: "1Gi" # 1 GB memory
requests:
cpu: "200m" # 0.2 CPU cores
memory: "256Mi" # 256 MB memoryINFO
By default, deploymentJobResources is set to {} (empty), which means no resource limits or requests are applied to the jobs. This maintains backward compatibility with existing deployments.
INFO
Reasons for setting resource limits on all containers:
- Many Kubernetes environments have resource quotas that require resource requests and limits
- Some organizations use admission controllers that require all pods to have resource limits defined
- Defining resource limits helps with capacity planning and prevents jobs from consuming excessive resources
External Connectivity Configuration
ProAuth supports multiple options for exposing the service externally in Kubernetes environments. You can choose between traditional Kubernetes Ingress, the newer Gateway API (HTTPRoute), or disable both to implement your own external connectivity solution.
Ingress Configuration
By default, ProAuth creates a Kubernetes Ingress resource for external access. The Ingress configuration allows you to specify hosts, TLS settings, and controller-specific annotations.
ingress:
enabled: true
ingressClass: nginx # Optional: Ingress class name
annotations: {} # Controller-specific annotations
# cert-manager.io/issuer: letsencrypt
# nginx.ingress.kubernetes.io/proxy-read-timeout: '120'
path: /
pathType: Prefix
hosts:
- auth.example.com
tls:
- secretName: proauth-tls
hosts:
- auth.example.comConfiguration Options:
| Option | Description | Default |
|---|---|---|
enabled | Enable or disable Ingress resource creation | true |
ingressClass | Ingress class name (e.g., nginx, traefik) | Not set |
annotations | Controller-specific annotations | {} |
path | URL path to match | / |
pathType | Path matching type (Prefix, Exact, ImplementationSpecific) | Prefix |
hosts | List of hostnames | [] |
tls | TLS configuration with secret names and hosts | [] |
Gateway API Configuration (HTTPRoute)
ProAuth also supports Kubernetes Gateway API as an alternative to traditional Ingress. Gateway API is a more expressive, extensible, and role-oriented approach to managing external traffic.
INFO
Prerequisites for Gateway API:
- Gateway API CRDs must be installed in your cluster:bash
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml - A Gateway controller must be deployed (e.g., Envoy Gateway, Istio, Traefik, Kong, NGINX Gateway Fabric)
- A Gateway resource must be created and managed by the cluster administrator
The ProAuth Helm chart only creates the HTTPRoute resource. The Gateway resource must be deployed and managed separately by the cluster administrator, giving full control over TLS termination, listener configuration, and gateway infrastructure.
gatewayApi:
enabled: false # Set to true to create HTTPRoute
labels: {} # Additional labels for HTTPRoute
annotations: {} # Implementation-specific annotations
# Simple Gateway reference
gatewayName: "" # Name of the Gateway to attach to
gatewayNamespace: "" # Gateway namespace (optional)
sectionName: "" # Specific listener name (optional)
# Advanced: Multiple Gateway references
parentRefs: [] # Use for complex multi-gateway setups
# Hostname matching
hostnames: [] # Hostnames to match
# Path configuration
path: / # Path to match
pathMatchType: PathPrefix # Match type: PathPrefix, Exact, RegularExpression
# Advanced options
backendWeight: 1 # Weight for traffic distribution
filters: [] # HTTP filters
timeouts: {} # Request timeouts
rules: [] # Custom routing rules (full override)Configuration Options:
| Option | Description | Default |
|---|---|---|
enabled | Enable or disable HTTPRoute creation | false |
labels | Additional labels for the HTTPRoute | {} |
annotations | Implementation-specific annotations | {} |
gatewayName | Name of the Gateway resource to reference | Required if parentRefs not set |
gatewayNamespace | Namespace where the Gateway is deployed | Same namespace as HTTPRoute |
sectionName | Specific listener on the Gateway to attach to | Not set (all listeners) |
parentRefs | Advanced: Multiple gateway references | [] |
hostnames | List of hostnames to match | [] (matches all) |
path | Path prefix to match | / |
pathMatchType | Path matching type | PathPrefix |
backendWeight | Weight for traffic distribution | 1 |
filters | HTTP filters (headers, rewrites) | [] |
timeouts | Request and backend timeouts | {} |
rules | Custom routing rules (overrides default) | [] |
Basic HTTPRoute Example
Attach to a Gateway in the same namespace:
gatewayApi:
enabled: true
gatewayName: main-gateway
hostnames:
- auth.example.comHTTPRoute with Gateway in Different Namespace
Common in production environments where Gateways are centrally managed:
gatewayApi:
enabled: true
gatewayName: main-gateway
gatewayNamespace: gateway-system
sectionName: https-listener # Attach to specific listener
hostnames:
- auth.example.com
- login.example.comMultiple Gateway References (Advanced)
For complex setups with internal and external access:
gatewayApi:
enabled: true
parentRefs:
- name: external-gateway
namespace: gateway-system
sectionName: https
- name: internal-gateway
namespace: gateway-system
sectionName: http
hostnames:
- auth.example.com
- auth.internal.example.comHTTPRoute with HTTP Filters
Add request/response modifications:
gatewayApi:
enabled: true
gatewayName: main-gateway
hostnames:
- auth.example.com
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-Proto
value: https
set:
- name: Host
value: auth.example.comHTTPRoute with Timeouts
Configure request timeouts:
gatewayApi:
enabled: true
gatewayName: main-gateway
hostnames:
- auth.example.com
timeouts:
request: 60s
backendRequest: 30sHTTPRoute with Custom Rules (Advanced)
Full control over routing for OIDC endpoints:
gatewayApi:
enabled: true
gatewayName: main-gateway
hostnames:
- auth.example.com
rules:
# OIDC well-known endpoints
- matches:
- path:
type: PathPrefix
value: /.well-known/
backendRefs:
- name: proauth
port: 80
# Token endpoint with specific timeout
- matches:
- path:
type: Exact
value: /connect/token
method: POST
backendRefs:
- name: proauth
port: 80
timeouts:
request: 30s
# All other paths
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: proauth
port: 80Gateway Implementation-Specific Annotations
Different Gateway implementations support custom annotations:
gatewayApi:
enabled: true
gatewayName: main-gateway
hostnames:
- auth.example.com
labels:
app.kubernetes.io/component: authentication
annotations:
# Kong-specific
konghq.com/strip-path: "false"
konghq.com/preserve-host: "true"
# Envoy Gateway
gateway.envoyproxy.io/rate-limit: "enabled"Disabling External Connectivity
You can disable both Ingress and Gateway API to implement your own external connectivity solution:
ingress:
enabled: false
gatewayApi:
enabled: falseThis is useful when:
- Using a service mesh (e.g., Istio, Linkerd) with its own ingress handling
- Implementing custom traffic management through operators
- Using cloud-provider specific load balancers directly
Migration from Ingress to Gateway API
To migrate from Ingress to Gateway API:
- Ensure prerequisites are met: Install Gateway API CRDs and deploy a Gateway controller
- Create a Gateway resource: Define your Gateway with appropriate listeners and TLS configuration
- Update your values.yaml:
ingress:
enabled: false
gatewayApi:
enabled: true
gatewayName: main-gateway
gatewayNamespace: gateway-system
hostnames:
- auth.example.com- Test the deployment in a non-production environment first
- Update DNS once verified
ProAuth Admin App Helm Chart Values
Application setting values
This section contains most important settings.
- Authentication information to authenticate against the backend API
- Encryption keys are used to encrypt critical information in ProAuth data stores. A valid X.509 certificate is needed. If a key rotation is necessary, the old certificates can be listed under keyrotationdecryptioncertificates. This enables the system to decrypt old values while already using the new key pair for all current encryption / decryption actions.
- The base service settings contain general settings for the service to run.
- The initializer settings will be used to initialize the Admin UI configuration (View Definitions, Labels, etc.) by the initializer container. Please provide the appropriate settings to connect to the backend API via a client credential grant.
appsettings:
authentication:
authority: VALUE_TO_OVERRIDE
clientid: VALUE_TO_OVERRIDE
clientsecret: VALUE_TO_OVERRIDE
tenantid: VALUE_TO_OVERRIDE
senderconstrainedtokenmode: Dpop
dpop__enabled: "true"
dpop__jsonwebkey: '<private-rsa-jwk>'
dpop__signingalgorithm: RS256
dpop__generateephemeralkeywhenmissing: "false"
dpop__retrywithnonce: "true"
dpop__prooflifetimeinseconds: "300"
pushedauthorizationbehavior: Require
requestobject__enabled: "true"
requestobject__signingalgorithm: RS256
requestobject__certificate: "<base64-pfx>"
requestobject__certificatepassword: "<password>"
requestobject__keyid: proauth-adminapp-jar
encryptionkeys:
mode: "" ## empty to disable, currently supported X509
certificate: ""
certificatepassword: ""
keyrotationdecryptioncertificates: []
#- certificate: ""
# certificatepassword: ""
#- certificate: ""
# certificatepassword: ""
baseservicesettings:
serviceurl: VALUE_TO_OVERRIDE
sessiontimeoutinminutes: 720
forwardlimit: 1
#knownproxies: ""
#knownnetworks: ""
initializersettings:
authority: VALUE_TO_OVERRIDE
serviceurl: VALUE_TO_OVERRIDE
resourceclientid: VALUE_TO_OVERRIDE
resourceclientsecret: VALUE_TO_OVERRIDE
resourcetenantid: VALUE_TO_OVERRIDEThe Admin App defaults to the FAPI-oriented profile with PAR, JAR, and DPoP. For production and for every deployment with more than one Admin App replica, configure a stable private DPoP JWK with appsettings.authentication.dpop__jsonwebkey and keep appsettings.authentication.dpop__generateephemeralkeywhenmissing set to "false". Every Admin App pod in the same deployment must use the same DPoP private key; otherwise an authorization code can be bound to one pod's DPoP key and redeemed by another pod with a different proof key, which ProAuth rejects with invalid_dpop_proof.
The DPoP JWK is runtime client proof material. It is different from the request-object signing certificate configured with requestobject__certificate and from the public client-app key set registered in ProAuth for JAR validation. When you provide the JWK through Helm values instead of an external Secret, wrap the JSON value in YAML single quotes so the JSON double quotes do not need escaping:
appsettings:
authentication:
dpop__jsonwebkey: '{"kty":"RSA","n":"...","e":"AQAB","d":"...","p":"...","q":"...","dp":"...","dq":"...","qi":"...","use":"sig","alg":"RS256","kid":"proauth-adminapp-dpop"}'
dpop__generateephemeralkeywhenmissing: "false"You can generate the DPoP JWK and related Admin App certificates with the ProAuth CLI:
proauthcli crypto dpop-jwk generate --kid proauth-adminapp-dpop --format helm
proauthcli crypto request-object-cert generate --kid proauth-adminapp-jar --format helm
proauthcli crypto client-assertion-cert generate --kid proauth-client-assertion --format helmExternal Secrets Configuration
The ProAuth Admin App chart supports the same v3 external Secret model. Secret keys are direct .NET configuration environment variable names, and non-secret settings should be supplied through Helm values or externalConfig.
| Secret group | Default generated name | Responsibility |
|---|---|---|
runtime | <fullname>-runtime | AdminApp OIDC client confidential values |
resourceDeployment | <fullname>-resource-deployment | Resource deployment job client secret |
crypto | <fullname>-crypto | Data-protection/encryption certificates |
ProAuth Admin App Chart Resource Names And Labels
The chart labels rendered resources with the standard Helm and Kubernetes application labels: helm.sh/chart, app.kubernetes.io/name, app.kubernetes.io/instance, app.kubernetes.io/version, app.kubernetes.io/managed-by, app.kubernetes.io/part-of, and app.kubernetes.io/component.
Common selector:
- AdminApp pods:
app.kubernetes.io/name=<chart-name>,app.kubernetes.io/component=admin-app
ProAuth Admin App Pod Topology Spread Constraints
The ProAuth Admin App chart also supports topologySpreadConstraints for its Deployment. The default is empty. When a constraint omits labelSelector, the chart automatically adds the AdminApp pod selector: app.kubernetes.io/name=<chart-name>, app.kubernetes.io/instance=<release-name>, and app.kubernetes.io/component=admin-app.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnywayDefault generated support resource names:
| Resource | Default generated name |
|---|---|
| Main service account | <fullname> |
| Resource deployment service account | <fullname>-resource-deployment |
| Wait-for RBAC role and binding | <fullname>-wait-for |
| Resource deployment job | <fullname>-resource-deployment-<version-or-revision> |
externalSecrets:
runtime:
enabled: false # Set to true to use an external secret
secretName: "" # Name of the external secret to use
keys: [] # List of direct env-var keys in the external secret
resourceDeployment:
enabled: false
secretName: ""
keys: []
crypto:
enabled: false
secretName: ""
keys: []Common keys:
# runtime
AuthenticationSettings__ClientSecret
AuthenticationSettings__Dpop__JsonWebKey
AuthenticationSettings__ClientAssertion__Certificate
AuthenticationSettings__ClientAssertion__CertificatePassword
AuthenticationSettings__MutualTls__Certificate
AuthenticationSettings__MutualTls__CertificatePassword
AuthenticationSettings__RequestObject__Certificate
AuthenticationSettings__RequestObject__CertificatePassword
# resourceDeployment
InitializerSettings__ResourceClientSecret
# crypto
EncryptionKeys__Certificate
EncryptionKeys__CertificatePassword
EncryptionKeys__KeyRotationDecryptionCertificates__<index>__Certificate
EncryptionKeys__KeyRotationDecryptionCertificates__<index>__CertificatePasswordExample: Using external Secrets for AdminApp credentials
Create the Secrets manually:
kubectl create secret generic proauthadminapp-runtime \
--from-literal=AuthenticationSettings__ClientSecret="<admin-client-secret>" \
--from-literal=AuthenticationSettings__Dpop__JsonWebKey='{"kty":"RSA","n":"...","e":"AQAB","d":"...","p":"...","q":"...","dp":"...","dq":"...","qi":"...","use":"sig","alg":"RS256","kid":"proauth-adminapp-dpop"}' \
--from-literal=AuthenticationSettings__RequestObject__Certificate="<base64-pfx>" \
--from-literal=AuthenticationSettings__RequestObject__CertificatePassword="<password>"
kubectl create secret generic proauthadminapp-resource-deployment \
--from-literal=InitializerSettings__ResourceClientSecret="<resource-client-secret>"
kubectl create secret generic proauthadminapp-crypto \
--from-literal=EncryptionKeys__Certificate="<base64-pfx>" \
--from-literal=EncryptionKeys__CertificatePassword="<password>"Configure your values.yaml:
externalSecrets:
runtime:
enabled: true
secretName: "proauthadminapp-runtime"
keys:
- AuthenticationSettings__ClientSecret
- AuthenticationSettings__Dpop__JsonWebKey
- AuthenticationSettings__RequestObject__Certificate
- AuthenticationSettings__RequestObject__CertificatePassword
resourceDeployment:
enabled: true
secretName: "proauthadminapp-resource-deployment"
keys:
- InitializerSettings__ResourceClientSecret
crypto:
enabled: true
secretName: "proauthadminapp-crypto"
keys:
- EncryptionKeys__Certificate
- EncryptionKeys__CertificatePassword
appsettings:
authentication:
authority: "https://idp.example.com"
clientid: "admin-app"
tenantid: "default"
initializersettings:
serviceurl: "https://idp.example.com"
resourceclientid: "admin-resource-deployment"ProAuth Admin App Chart External Service Accounts
By default, the ProAuth Admin App chart creates all necessary service accounts automatically. However, you can configure the chart to reference external, pre-created service accounts for specific workloads.
The external service accounts configuration is controlled through the externalServiceAccounts section:
externalServiceAccounts:
# Main service account configuration (used by the main ProAuthAdminApp deployment)
# This service account needs permissions for basic Kubernetes API access and k8s-wait-for functionality
# Required RBAC: Role with access to services, pods (get, watch, list) and jobs (get, watch, list)
main:
enabled: false # Set to true to use an external service account
name: "" # Name of the external service account to use
# Deploy service account configuration (used by resource deployment jobs)
# This service account needs permissions for job management and k8s-wait-for functionality
# Required RBAC: Role with access to services, pods (get, watch, list) and jobs (get, watch, list)
deploy:
enabled: false # Set to true to use an external service account
name: "" # Name of the external service account to useExample: Using External Service Account for Admin App Main Deployment
- Create your service account and RBAC manually:
# Create the service account
kubectl create serviceaccount my-adminapp-main-sa
# Create the required role (if not exists)
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: adminapp-k8s-wait-for
rules:
- apiGroups: [""]
resources: ["services", "pods"]
verbs: ["get", "watch", "list"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "watch", "list"]
EOF
# Create the role binding
kubectl create rolebinding my-adminapp-main-binding \
--role=adminapp-k8s-wait-for \
--serviceaccount=default:my-adminapp-main-sa- Configure your
values.yaml:
externalServiceAccounts:
main:
enabled: true
name: "my-adminapp-main-sa"
# deploy remains internal (chart-managed)
deploy:
enabled: falseDeployment Job Resources Configuration
The Admin App chart includes a resource deployment job that can be configured with resource limits and requests:
# Resource deployment job resource configuration
deploymentJobResources:
limits:
cpu: "300m"
memory: "256Mi"
requests:
cpu: "50m"
memory: "64Mi"Example Usage:
deploymentJobResources:
limits:
cpu: "500m" # 0.5 CPU cores
memory: "512Mi" # 512 MB memory
requests:
cpu: "100m" # 0.1 CPU cores
memory: "128Mi" # 128 MB memoryDapr settings
If ProAuth is hosted in a cluster with multiple instances, we rely on Dapr for the communication between services, event handling and shared state data.
If dapr.enabled is set to true, a valid dapr configuration needs to be provided. You can either let the helm chart generate a valid dapr configuration for using Redis. If a custom dapr configuration is desired, set the flag deployDefaultComponents to false.
When deployDefaultComponents is true, the chart will create Dapr StateStore and LockStore components using the configured names. The generated components include
scopesto restrict each component to the Admin App's Dapr app ID.When deployDefaultComponents is false, the chart will NOT create any Dapr components and will reference pre-existing components ONLY by name. You must pre-create the components with the configured names. When providing your own components, you should add appropriate
scopesto ensure they are only loaded by the Admin App sidecar.redisHost: Redis endpoint used by the state store (e.g.,redis-ha-haproxy.redis:6379)sentinelHost: Sentinel endpoint used by the lock store in HA mode (e.g.,redis-ha.redis:26379)
dapr:
enabled: false
id: proauthadminapp
nameStateStore: "proauthadminappstatestore"
nameLockStore: "proauthadminapplockstore"
deployDefaultComponents: true
defaultComponents:
redisHost: VALUE_TO_OVERRIDE
redisPassword: VALUE_TO_OVERRIDE
redisDB: 0
maxLenApprox: 100
failover: false
sentinelHost: ""
sentinelMasterName: ""Redis High Availability (Sentinel) Configuration (Admin App)
When running Redis in HA mode with Sentinel, the lock store component requires additional configuration to connect through the Sentinel endpoint.
In a typical Redis HA setup, there are two different endpoints:
- HAProxy endpoint (e.g.,
redis-ha-haproxy.redis:6379): Used by the state store for general Redis operations - Sentinel endpoint (e.g.,
redis-ha.redis:26379): Used by the lock store for distributed locking with failover support
Set failover to true, provide the sentinelHost pointing to the Sentinel endpoint, and specify the sentinelMasterName.
dapr:
enabled: true
deployDefaultComponents: true
defaultComponents:
redisHost: "redis-ha-haproxy.redis:6379" # HAProxy endpoint for state store
redisPassword: "your-redis-password"
redisDB: 0
failover: true
sentinelHost: "redis-ha.redis:26379" # Sentinel endpoint for lock store
sentinelMasterName: "mymaster" # Sentinel master group nameWARNING
The failover, sentinelHost, and sentinelMasterName settings only affect the lock store component. The state store component always uses redisHost.
Dapr component requirements (Admin App)
When you bring your own Dapr components (deployDefaultComponents=false), create the StateStore and LockStore with the exact names configured above. Requirements:
- ProAuthAdminApp
- StateStore: any supported Dapr state store (no special metadata required). Uses the HAProxy endpoint in Redis HA setups.
- LockStore: a Dapr lock component. When using Redis in HA mode, the lock store must be configured with
failover: "true",sentinelMasterName, andredisHostpointing to the Sentinel endpoint (not the HAProxy endpoint).
Scoping: Each component should include a scopes section restricting it to the Admin App's Dapr app ID (configured via dapr.id).
Sample Dapr components (Admin App)
The following example shows a typical StateStore and LockStore when using Redis. Adjust names and secret references to match your environment.
Standalone Redis:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauthadminappstatestore"
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha-haproxy.redis:6379"
- name: redisPassword
secretKeyRef:
name: proauthadminapp-dapr-secrets
key: redis-password
- name: ttlInSeconds
value: 1800
- name: redisDB
value: "0"
scopes:
- "proauthadminapp"
---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauthadminapplockstore"
spec:
type: lock.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha-haproxy.redis:6379"
- name: redisPassword
secretKeyRef:
name: proauthadminapp-dapr-secrets
key: redis-password
- name: redisDB
value: "0"
scopes:
- "proauthadminapp"Redis HA with Sentinel:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauthadminappstatestore"
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha-haproxy.redis:6379"
- name: redisPassword
secretKeyRef:
name: proauthadminapp-dapr-secrets
key: redis-password
- name: ttlInSeconds
value: 1800
- name: redisDB
value: "0"
scopes:
- "proauthadminapp"
---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: "proauthadminapplockstore"
spec:
type: lock.redis
version: v1
metadata:
- name: redisHost
value: "redis-ha.redis:26379"
- name: failover
value: "true"
- name: sentinelMasterName
value: "mymaster"
- name: redisPassword
secretKeyRef:
name: proauthadminapp-dapr-secrets
key: redis-password
- name: redisDB
value: "0"
scopes:
- "proauthadminapp"External Connectivity Configuration (Admin App)
The ProAuth Admin App supports the same external connectivity options as the ProAuth Core chart. You can choose between traditional Kubernetes Ingress or Gateway API (HTTPRoute).
Ingress Configuration (Admin App)
ingress:
enabled: true
ingressClass: nginx
annotations: {}
path: /
pathType: Prefix
hosts:
- admin.example.com
tls:
- secretName: adminapp-tls
hosts:
- admin.example.comGateway API Configuration (Admin App)
The Gateway API configuration follows the same structure as the ProAuth Core chart. See the External Connectivity Configuration section for detailed documentation.
gatewayApi:
enabled: true
gatewayName: main-gateway
gatewayNamespace: gateway-system
hostnames:
- admin.example.comAdmin App HTTPRoute with Custom Rules
For Blazor applications, you may want to configure specific rules:
gatewayApi:
enabled: true
gatewayName: main-gateway
hostnames:
- admin.example.com
rules:
# API endpoints
- matches:
- path:
type: PathPrefix
value: /api/
backendRefs:
- name: proauthadminapp
port: 80
timeouts:
request: 30s
# Static assets
- matches:
- path:
type: PathPrefix
value: /_content/
backendRefs:
- name: proauthadminapp
port: 80
# All other paths (Blazor app)
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: proauthadminapp
port: 80Container Runtime Environment
ProAuth is delivered as container images and those images can be run in any OCI compliant container environment. The advantages of the helm chart do not apply here and the deployment automation needs a little bit more logic. From a runtime perspective, there is no change.
The easiest way to configure the containers is by using an appropriate .env file to specify the environment variables to overwrite the appsettings.json values.
ProAuth appsettings.json
The following settings should be configured to run ProAuth:
{
"Data": {
"DefaultConnection": {
"Provider": "SqlServer",
"ConnectionString": "VALUE_TO_OVERRIDE",
"CommandTimeoutInSeconds": 30
},
"Events": {
"Type": "InMemory", // or Dapr
"InstanceName": "proauthglobalevents"
},
"StateStore": {
"Type": "InMemory", // or Dapr
"InstanceName": "proauthstatestore"
}
},
"BaseServiceSettings": {
"HostUrl": "VALUE_TO_OVERRIDE",
"EmailSenderAddress": null, // or proper value
"MailServerConfig": null // or proper value
},
"ProAuthRoot": {
"ClientAppSecret": null, // or own secret
"ScimTokenSecurityKey": null // needs to be set when using SCIM
},
"License": {
"LicenseFile": "",
"LicenseData": "VALUE_TO_OVERRIDE"
}
"EncryptionKeys": {
"Mode": "X509", // empty to disable
"Certificate": "VALUE_TO_OVERRIDE",
"CertificatePassword": "VALUE_TO_OVERRIDE",
"KeyRotationDecryptionCertificates": [
//{
// "Certificate": "VALUE_TO_OVERRIDE",
// "CertificatePassword": "VALUE_TO_OVERRIDE"
//}
]
}
}Data:DefaultConnection:Provider selects the database provider for the full ProAuth installation. Supported values are SqlServer and PostgreSql. When using environment variables, set Data__DefaultConnection__Provider. The same provider is used for the ProAuth database and all UserStore databases.
Please refer to the chapter @sec:helmchartdeployment for detailed information about the different settings.
ProAuth Admin UI appsettings.json
The following settings should be configured to run ProAuth:
{
"BaseServiceSettings": {
"ServiceUrl": "VALUE_TO_OVERRIDE",
"SessionTimeoutInMinutes": 720
},
"AuthenticationSettings": {
"Authority": "VALUE_TO_OVERRIDE",
"ClientId": "VALUE_TO_OVERRIDE",
"ClientSecret": "VALUE_TO_OVERRIDE",
"TenantId": "VALUE_TO_OVERRIDE"
},
"Data": {
"StateStore": {
"Type": "InMemory",
"InstanceName": "proauthadminappserverstatestore"
}
},
"EncryptionKeys": {
"Mode": "X509", // empty to disable
"Certificate": "VALUE_TO_OVERRIDE",
"CertificatePassword": "VALUE_TO_OVERRIDE",
"KeyRotationDecryptionCertificates": [
//{
// "Certificate": "VALUE_TO_OVERRIDE",
// "CertificatePassword": "VALUE_TO_OVERRIDE"
//}
]
}
}Please refer to the chapter @sec:helmchartdeployment for detailed information about the different settings.
Root Configuration
To run ProAuth, access to a supported database server is required. ProAuth supports SQL Server and PostgreSQL. The provider is selected globally with Data:DefaultConnection:Provider (Data__DefaultConnection__Provider as an environment variable) and supports SqlServer or PostgreSql. It applies to the ProAuth database and all UserStore databases.
If ProAuth is deployed to the cluster by the Helm package, an initializer job is executed before the ProAuth deployment starts. The initializer uses EF Core migrations for the configured provider. It creates or updates the ProAuth database schema and then scans for existing UserStore instances by looking for UserStore connection strings in the options. If UserStore instances are found, their schemas are also migrated.
ProAuth stores its own objects in the proauth schema. UserStore objects are stored in the userstore schema. The default deployment still uses separate databases for ProAuth and UserStores, but both schemas can also exist in the same physical database when the configured connection strings point to the same database.
After the schema deployment job has completed successfully, the ProAuth deployment starts. During the deployment of ProAuth by the Helm package, a connection string is required which has access to the ProAuth database.
If ProAuth starts for the first time on an empty database, the Root DataInitializer is executed in ProAuth. The Root DataInitializer sets up a minimal ProAuth configuration, which finally contains a Root ClientApp, with which ProAuth can be set up automated customer specific.
Root DataInitializer
The goal of the ProAuth Root DataInitializer is to setup an initial Root ClientApp with SysAdmin privileges. With this ClientApp, it's possible to configure ProAuth automated through the API.
The ProAuth Root DataInitializer sets up following configuration:
- Default Certificate (provided by settings)
- Root Customer
- Root ClientApp
- Invitation ClientApp
- Root Subscription
- Root Tenant
- Forward ClaimRule
- ServerCookie IDP