Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
8.0 KiB
Helm Secret Provider Configuration
This document explains how to configure the composite secret provider system in Kubernetes using Helm charts.
Overview
The Helm charts support the same composite secret provider system as Docker deployments, but with additional Kubernetes-specific features:
- Values-based configuration: Configure providers through Helm values files
- Environment-specific defaults: Different values files for different deployment environments
- Conditional vault configuration: Vault settings only applied when vault is used
- Setup job integration: Secret provider configuration for database initialization jobs
Configuration Structure
Values File Structure
secrets:
# Comma-separated list of providers for reading secrets
readChain: "env,filesystem,vault"
# Single provider for writing secrets
writeProvider: "filesystem"
# Optional environment variable prefix
envPrefix: ""
# Vault configuration (only used when vault is in readChain or writeProvider)
vault:
addr: "https://vault.example.com"
token: "hvs.xxxxx"
appSecretPath: "kv/data/app/secrets"
tenantSecretPathTemplate: "kv/data/tenants/{tenantId}/secrets"
Environment-Specific Configurations
Development (values.yaml)
secrets:
readChain: "env,filesystem"
writeProvider: "filesystem"
envPrefix: ""
vault:
addr: ""
token: ""
Use case: Local development and testing with simple env var overrides.
Production (prod.values.yaml)
secrets:
readChain: "env,filesystem,vault"
writeProvider: "filesystem"
envPrefix: ""
vault:
addr: "https://vault.company.com"
token: "" # Provided via environment or secret
Use case: Production environments with vault integration for enterprise secrets.
Host Environment (host.values.yaml)
secrets:
readChain: "env,filesystem,vault"
writeProvider: "filesystem"
envPrefix: ""
vault:
addr: "https://vault-internal.cluster.local"
token: "" # Mounted via kubernetes secret
Use case: On-premises or dedicated host deployments with internal vault.
Development Environment (values-dev-env.yaml)
secrets:
readChain: "env,filesystem"
writeProvider: "filesystem"
envPrefix: ""
Use case: Development branches and PR environments.
Deployment Methods
1. Override via Command Line
helm upgrade --install alga-psa ./helm \
--set secrets.readChain="env,vault" \
--set secrets.vault.addr="https://vault.example.com" \
--set secrets.vault.token="hvs.xxxxx"
2. Custom Values File
Create custom-values.yaml:
secrets:
readChain: "env,filesystem,vault"
writeProvider: "vault"
vault:
addr: "https://vault.company.com"
token: "hvs.xxxxx"
Deploy with:
helm upgrade --install alga-psa ./helm \
-f values.yaml \
-f custom-values.yaml
3. Environment Variables Override
Set environment variables in the pod:
apiVersion: v1
kind: ConfigMap
metadata:
name: secret-provider-override
data:
SECRET_READ_CHAIN: "env,vault"
SECRET_WRITE_PROVIDER: "vault"
VAULT_ADDR: "https://vault.example.com"
Reference in deployment:
spec:
containers:
- name: app
envFrom:
- configMapRef:
name: secret-provider-override
Vault Integration
Using Kubernetes Secrets for Vault Token
- Create a Kubernetes secret:
kubectl create secret generic vault-credentials \
--from-literal=token="hvs.xxxxx"
- Update values to reference the secret:
secrets:
vault:
addr: "https://vault.example.com"
# Token will be provided via mounted secret or environment
token: ""
- Mount the secret in deployment (modify
deployment.yaml):
env:
- name: VAULT_TOKEN
valueFrom:
secretKeyRef:
name: vault-credentials
key: token
Using Vault Agent Sidecar
For advanced vault integration, use Vault Agent as a sidecar:
spec:
containers:
- name: vault-agent
image: vault:latest
# Vault agent configuration for automatic token renewal
- name: app
# Main application container
env:
- name: VAULT_TOKEN
value: "/vault/secrets/token"
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
Generated Environment Variables
The Helm templates generate these environment variables in the application pods:
Always Present
SECRET_READ_CHAIN: Fromsecrets.readChainSECRET_WRITE_PROVIDER: Fromsecrets.writeProvider
Conditional
SECRET_ENV_PREFIX: Only ifsecrets.envPrefixis setVAULT_ADDR: Only if vault is used andsecrets.vault.addris setVAULT_TOKEN: Only if vault is used andsecrets.vault.tokenis setVAULT_APP_SECRET_PATH: Only if vault is used and path is specifiedVAULT_TENANT_SECRET_PATH_TEMPLATE: Only if vault is used and template is specified
Affected Components
The secret provider configuration is applied to:
-
Main Application Deployment (
templates/deployment.yaml)- Primary application container
- All secret provider environment variables
-
Setup Jobs (
templates/jobs.yaml)- Database initialization jobs
- Same secret provider configuration as main app
-
Hocuspocus Deployment (conditionally)
- If hocuspocus uses application secrets (currently uses separate DB secrets)
Validation and Troubleshooting
Check Configuration
View the actual environment variables in a running pod:
kubectl exec -it deployment/alga-psa -- env | grep SECRET
kubectl exec -it deployment/alga-psa -- env | grep VAULT
Validate Template Rendering
Test Helm template rendering locally:
helm template alga-psa ./helm -f values.yaml --debug
Common Issues
-
Vault connection errors
- Check
VAULT_ADDRis accessible from cluster - Verify
VAULT_TOKENhas correct permissions - Ensure vault paths exist
- Check
-
Missing environment variables
- Verify values file syntax
- Check Helm template conditions
- Confirm vault configuration is properly nested
-
Template syntax errors
- Use
helm template --debugto validate - Check for proper YAML indentation
- Verify Helm function syntax
- Use
Debugging Steps
-
Check rendered templates:
helm template alga-psa ./helm -f prod.values.yaml > rendered.yaml grep -A 20 -B 5 "SECRET_READ_CHAIN" rendered.yaml -
Validate in running pod:
kubectl exec deployment/alga-psa -- cat /proc/1/environ | tr '\0' '\n' | grep SECRET -
Check application logs:
kubectl logs deployment/alga-psa | grep "secret provider"
Expected log messages:
Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystemEnvSecretProvider initialized without prefixCompositeSecretProvider initialized with 2 read providers and 1 write provider
Migration from Legacy Configuration
Before (Legacy)
# Old way - single provider
config:
secretProvider:
type: "filesystem" # or "vault"
After (Composite)
# New way - composite providers
secrets:
readChain: "env,filesystem" # or "env,filesystem,vault"
writeProvider: "filesystem" # or "vault"
The application automatically detects and uses the new configuration while maintaining backward compatibility with legacy SECRET_PROVIDER_TYPE environment variables.
Security Best Practices
-
Never commit vault tokens to values files
- Use Kubernetes secrets or environment variables
- Consider vault agent for token management
-
Use least privilege vault policies
- Restrict vault token permissions to required paths
- Use renewable tokens when possible
-
Secure filesystem secrets
- Use Kubernetes secrets instead of plain files
- Set appropriate file permissions (600)
-
Environment variable precedence
- Leverage env provider for temporary overrides
- Use filesystem/vault for persistent secrets
-
Regular token rotation
- Implement vault token rotation procedures
- Monitor token expiration in logs