PSA/docs/security/config/HELM_SECRET_PROVIDER_CONFIG.md
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

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

  1. Create a Kubernetes secret:
kubectl create secret generic vault-credentials \
  --from-literal=token="hvs.xxxxx"
  1. Update values to reference the secret:
secrets:
  vault:
    addr: "https://vault.example.com"
    # Token will be provided via mounted secret or environment
    token: ""
  1. 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: From secrets.readChain
  • SECRET_WRITE_PROVIDER: From secrets.writeProvider

Conditional

  • SECRET_ENV_PREFIX: Only if secrets.envPrefix is set
  • VAULT_ADDR: Only if vault is used and secrets.vault.addr is set
  • VAULT_TOKEN: Only if vault is used and secrets.vault.token is set
  • VAULT_APP_SECRET_PATH: Only if vault is used and path is specified
  • VAULT_TENANT_SECRET_PATH_TEMPLATE: Only if vault is used and template is specified

Affected Components

The secret provider configuration is applied to:

  1. Main Application Deployment (templates/deployment.yaml)

    • Primary application container
    • All secret provider environment variables
  2. Setup Jobs (templates/jobs.yaml)

    • Database initialization jobs
    • Same secret provider configuration as main app
  3. 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

  1. Vault connection errors

    • Check VAULT_ADDR is accessible from cluster
    • Verify VAULT_TOKEN has correct permissions
    • Ensure vault paths exist
  2. Missing environment variables

    • Verify values file syntax
    • Check Helm template conditions
    • Confirm vault configuration is properly nested
  3. Template syntax errors

    • Use helm template --debug to validate
    • Check for proper YAML indentation
    • Verify Helm function syntax

Debugging Steps

  1. Check rendered templates:

    helm template alga-psa ./helm -f prod.values.yaml > rendered.yaml
    grep -A 20 -B 5 "SECRET_READ_CHAIN" rendered.yaml
    
  2. Validate in running pod:

    kubectl exec deployment/alga-psa -- cat /proc/1/environ | tr '\0' '\n' | grep SECRET
    
  3. Check application logs:

    kubectl logs deployment/alga-psa | grep "secret provider"
    

Expected log messages:

  • Building composite secret provider. Read chain: [env, filesystem], Write provider: filesystem
  • EnvSecretProvider initialized without prefix
  • CompositeSecretProvider 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

  1. Never commit vault tokens to values files

    • Use Kubernetes secrets or environment variables
    • Consider vault agent for token management
  2. Use least privilege vault policies

    • Restrict vault token permissions to required paths
    • Use renewable tokens when possible
  3. Secure filesystem secrets

    • Use Kubernetes secrets instead of plain files
    • Set appropriate file permissions (600)
  4. Environment variable precedence

    • Leverage env provider for temporary overrides
    • Use filesystem/vault for persistent secrets
  5. Regular token rotation

    • Implement vault token rotation procedures
    • Monitor token expiration in logs