Skip to content

Instantly share code, notes, and snippets.

@colek42
Last active October 15, 2025 16:11
Show Gist options
  • Select an option

  • Save colek42/ece5df76c1d6e44fe264e7170e451ce2 to your computer and use it in GitHub Desktop.

Select an option

Save colek42/ece5df76c1d6e44fe264e7170e451ce2 to your computer and use it in GitHub Desktop.
Vault Secrets Reference for Anaconda Judge Platform - ESO Configuration Guide

Vault Secrets Reference - Judge Platform

Quick reference for configuring Vault secrets with External Secrets Operator.

Required Vault Secrets

Database Secrets (RDS)

Path: demo/kubernetes/rds/testifysec-judge

vault kv put demo/kubernetes/rds/testifysec-judge \
  archivista_dsn="postgresql://postgres:${ENCODED_PASSWORD}@HOST:5432/archivista" \
  judge_api_dsn="postgresql://postgres:${ENCODED_PASSWORD}@HOST:5432/judge_api" \
  kratos_dsn="postgresql://postgres:${ENCODED_PASSWORD}@HOST:5432/kratos"

Note: Passwords must be URL-encoded. Use python3 -c "import urllib.parse; print(urllib.parse.quote('${PASSWORD}', safe=''))" or jq -sRr @uri

Application Secrets (Kratos)

Path: demo/kubernetes/app/testifysec-judge

vault kv put demo/kubernetes/app/testifysec-judge \
  kratos_secrets_cookie="$(openssl rand -hex 16)" \
  kratos_secrets_cipher="$(openssl rand -hex 16)"

Vault Configuration

1. Enable Secrets Engine

vault secrets enable -path=demo/kubernetes kv-v2

2. Create Policies

# Archivista & Judge API policy
vault policy write archivista-secrets - <<EOF
path "demo/kubernetes/data/rds/testifysec-judge" {
  capabilities = ["read"]
}
EOF

vault policy write judge-api-secrets - <<EOF
path "demo/kubernetes/data/rds/testifysec-judge" {
  capabilities = ["read"]
}
EOF

# Kratos policy (needs both paths)
vault policy write kratos-secrets - <<EOF
path "demo/kubernetes/data/rds/testifysec-judge" {
  capabilities = ["read"]
}
path "demo/kubernetes/data/app/testifysec-judge" {
  capabilities = ["read"]
}
EOF

3. Create Kubernetes Auth Roles

vault write auth/kubernetes/role/archivista \
  bound_service_account_names=archivista \
  bound_service_account_namespaces=judge \
  policies=archivista-secrets \
  ttl=1h

vault write auth/kubernetes/role/judge-api \
  bound_service_account_names=judge-api \
  bound_service_account_namespaces=judge \
  policies=judge-api-secrets \
  ttl=1h

vault write auth/kubernetes/role/kratos \
  bound_service_account_names=kratos \
  bound_service_account_namespaces=judge \
  policies=kratos-secrets \
  ttl=1h

Transit Signing (GitHub Actions)

Enable Transit Engine

vault secrets enable transit
vault write -f transit/keys/anaconda-signing-key type=rsa-2048
vault write transit/keys/anaconda-signing-key/config \
  allow_plaintext_backup=false \
  exportable=false \
  auto_rotate_period="2160h" \
  min_encryption_version=0 \
  deletion_allowed=false

GitHub OIDC Auth

vault auth enable jwt
vault write auth/jwt/config \
  oidc_discovery_url="https://token.actions.githubusercontent.com" \
  bound_issuer="https://token.actions.githubusercontent.com"

vault write auth/jwt/role/anaconda-ci \
  role_type="jwt" \
  bound_claims='{"repository_owner":"anaconda"}' \
  bound_audiences="https://github.com/anaconda" \
  user_claim="actor" \
  token_ttl=1h \
  token_policies="transit-sign"

Transit Policy

vault policy write transit-sign - <<EOF
path "transit/sign/anaconda-signing-key" {
  capabilities = ["update"]
}
path "transit/verify/anaconda-signing-key" {
  capabilities = ["update"]
}
path "transit/keys/anaconda-signing-key" {
  capabilities = ["read"]
}
EOF

Verification

# Check secrets exist
vault kv get demo/kubernetes/rds/testifysec-judge
vault kv get demo/kubernetes/app/testifysec-judge

# Check auth roles
vault read auth/kubernetes/role/archivista
vault read auth/kubernetes/role/judge-api
vault read auth/kubernetes/role/kratos

# Check ExternalSecrets synced
kubectl get externalsecrets -n judge
kubectl get secrets -n judge | grep -E 'archivista|judge-api|kratos'

Troubleshooting

ExternalSecret not syncing?

kubectl describe externalsecret <name> -n judge

Common fixes:

  • Check Vault role exists: vault read auth/kubernetes/role/<role-name>
  • Check ServiceAccount matches bound_service_account_names
  • Check policy grants read on secret path
  • Check Vault is reachable: kubectl get svc -n vault

Pod can't read secret?

kubectl logs -n judge <pod-name>
kubectl get secret <secret-name> -n judge

References:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment