Secrets Management SOP
Overview
All secrets in Engram are managed through Azure Key Vault and GitHub Secrets. No secrets are hardcoded in the codebase or committed to version control.
Secret Sources
1. Azure Key Vault (Primary)
All production secrets are stored in Azure Key Vault and referenced by Container Apps using Managed Identity.
Key Vault Location:
- Resource Group:
engram-rg - Key Vault Name:
{envName}-kv(e.g.,staging-env-kv)
Required Secrets:
| Secret Name | Description | Used By |
|---|---|---|
zep-api-key | Zep Memory Service API key | Backend, Worker |
azure-ai-key | Azure AI Services API key (APIM subscription key) | Backend, Worker, Zep |
postgres-password | PostgreSQL admin password | Backend, Worker, Zep, Temporal |
voicelive-api-key | Azure VoiceLive API key (optional) | Backend |
anthropic-api-key | Anthropic Claude API key (optional, for Sage) | Backend |
gemini-api-key | Google Gemini API key (optional, for Sage) | Backend |
2. GitHub Secrets (CI/CD)
GitHub Secrets are used during deployment to pass values to Bicep templates.
Required GitHub Secrets:
| Secret Name | Description | Used In |
|---|---|---|
ZEP_API_KEY | Zep API key (stored in Key Vault during deployment) | .github/workflows/deploy.yml |
AZURE_AI_ENDPOINT | Azure AI endpoint URL | .github/workflows/deploy.yml |
AZURE_OPENAI_KEY | Azure OpenAI API key (alternative to APIM key) | .github/workflows/deploy.yml |
POSTGRES_PASSWORD | PostgreSQL password (stored in Key Vault) | .github/workflows/deploy.yml |
CR_PAT | GitHub Container Registry Personal Access Token | .github/workflows/deploy.yml |
Secret Flow
Deployment Flow
GitHub Secrets → Bicep Parameters → Key Vault → Container App Secrets → Environment Variables
- GitHub Actions reads secrets from GitHub Secrets
- Bicep templates receive secrets as parameters
- Key Vault stores secrets (via
modules/keyvault-secrets.bicep) - Container Apps reference Key Vault secrets using Managed Identity
- Backend/Worker read secrets from environment variables
Runtime Flow
Container App → Managed Identity → Key Vault → Environment Variable → Application Code
- Container App uses Managed Identity to access Key Vault
- Key Vault returns secret value
- Environment Variable is set in container
- Application Code reads from environment variable (via
backend/core/config.py)
Configuration Files
Backend Configuration (backend/core/config.py)
All secrets are read from environment variables:
class Settings(BaseSettings):
zep_api_key: Optional[str] = Field(None, alias="ZEP_API_KEY")
azure_ai_key: Optional[str] = Field(None, alias="AZURE_AI_KEY")
postgres_password: str = Field("password", alias="POSTGRES_PASSWORD")
# ... other settings
Bicep Templates
Secrets are referenced from Key Vault:
// infra/modules/backend-aca.bicep
secrets: [
{
name: 'zep-api-key'
keyVaultUrl: '${keyVaultUri}secrets/zep-api-key'
identity: identityResourceId
}
// ...
]
env: [
{
name: 'ZEP_API_KEY'
secretRef: 'zep-api-key'
}
// ...
]
Security Best Practices
✅ DO
- ✅ Store all secrets in Azure Key Vault
- ✅ Use Managed Identity for Key Vault access
- ✅ Reference secrets using
secretRefin Container Apps - ✅ Read secrets from environment variables in code
- ✅ Use GitHub Secrets for CI/CD deployment parameters
- ✅ Rotate secrets regularly
- ✅ Use separate secrets for different environments
❌ DON’T
- ❌ Hardcode secrets in code
- ❌ Commit secrets to version control
- ❌ Store secrets in
.envfiles (local dev only) - ❌ Log secret values
- ❌ Pass secrets as command-line arguments
- ❌ Use the same secrets across environments
Verifying Secret Configuration
Check Key Vault Secrets
# List all secrets
az keyvault secret list --vault-name {key-vault-name} --query "[].name" --output table
# Check specific secret exists
az keyvault secret show --vault-name {key-vault-name} --name zep-api-key --query "name" --output tsv
Check Container App Environment Variables
# List environment variables (secretRef values are masked)
az containerapp show \
--name {app-name} \
--resource-group engram-rg \
--query "properties.template.containers[0].env" \
--output table
Check GitHub Secrets
GitHub Secrets can only be viewed in the GitHub repository settings:
- Go to:
Settings→Secrets and variables→Actions - Verify required secrets are present
Troubleshooting
Secret Not Found
Error: SecretNotFound or 401 Unauthorized
Solution:
- Verify secret exists in Key Vault
- Check Managed Identity has
Key Vault Secrets Userrole - Check Container App has correct Managed Identity assigned
Secret Not Accessible
Error: Application can’t read secret value
Solution:
- Verify
secretRefis correctly set in Container App - Check Managed Identity has access to Key Vault
- Verify secret name matches exactly (case-sensitive)
Secret Outdated
Error: Application using old secret value
Solution:
- Update secret in Key Vault
- Restart Container App to pick up new value
- Or update secret reference to force refresh