Skip to content

2.1.2 Credential Management

This page lists all credentials required for the RCIIS deployment and describes how to generate, encrypt, and store them securely using SOPS before provisioning begins.

Credential Inventory

Infrastructure Credentials

These are established during the Prepare and Build phases:

Credential Used By Storage
AWS IAM access keys Terraform provisioning AWS CLI profile (~/.aws/credentials) — never committed to Git
Proxmox API token Terraform Proxmox provider .tfvars file — SOPS-encrypted if stored in Git
Bare Metal IPMI/BMC passwords Server management Password manager or SOPS-encrypted inventory file
SSH keys (Bare Metal / Proxmox) Initial server access, Terraform provisioning SSH agent — private key never committed to Git

Security Tool Credentials

These are needed before deploying the security tools in Phase 5 (Install Platform Services):

Credential Used By Format How to Generate
Keycloak admin credentials Keycloak Operator bootstrapAdmin secret (username + password) Kubernetes Secret (keycloak-admin-secret) openssl rand -base64 24
Keycloak DB password CloudNativePG bootstrap (used by Keycloak Operator via spec.db) Kubernetes Secret (keycloak-db-credentials, type kubernetes.io/basic-auth) openssl rand -base64 24
Keycloak OIDC client secrets Weave GitOps, APISIX Dashboard client authentication Kubernetes Secret (keycloak-client-secrets) openssl rand -base64 32 per client
Harbor pull credentials Trivy Operator (private registry scanning) docker-registry Secret Existing Harbor service account
Falcosidekick webhook URL Falco alert forwarding to Slack Kubernetes Secret From Slack app configuration
Falcosidekick PagerDuty key Falco alert escalation Kubernetes Secret From PagerDuty service integration
LDAP bind credentials Keycloak user federation (per partner state) Kubernetes Secret From partner state AD/LDAP admin
cosign private signing key Image signature verification (Sigstore) CI secret + SOPS-encrypted backup cosign generate-key-pair
cosign public key Kyverno image verification policy ConfigMap or inline in ClusterPolicy Generated alongside private key (safe to commit unencrypted)

HSM Credentials

Credential Purpose How to Generate
CloudHSM Crypto Officer (CO) password HSM administration, key management Set during cluster initialisation
CloudHSM Crypto User (CU) password Application-level key operations Created by CO after initialisation
Custom Key Store password KMS-to-CloudHSM bridge authentication Set during custom key store creation

Store these in a secure password manager. The CU password must also be available as a SOPS-encrypted Kubernetes Secret for pods that access the HSM (cert-manager, Keycloak).

Credential Purpose How to Generate
HSM Security Officer (SO) PIN HSM initialisation and policy management Set during key ceremony
HSM Partition password Application partition access Set during key ceremony
PKCS#11 PIN Runtime key operations by applications Set when creating the partition

These are generated during the formal key ceremony (see Provision the HSM). The SO PIN should be split using M-of-N secret sharing across multiple custodians. The PKCS#11 PIN must be available as a SOPS-encrypted Kubernetes Secret.

Credential Purpose How to Generate
HSM Security Officer (SO) PIN HSM initialisation and policy management Set during key ceremony
HSM Partition password Application partition access Set during key ceremony
PKCS#11 PIN Runtime key operations by applications Set when creating the partition

These are generated during the formal key ceremony (see Provision the HSM). The SO PIN should be split using M-of-N secret sharing across multiple custodians. The PKCS#11 PIN must be available as a SOPS-encrypted Kubernetes Secret.

SOPS Encryption Workflow

All credentials stored in Git must be encrypted with SOPS using Age keys. This follows the same workflow established in Machine Configuration.

Encrypt a Secret

# Create the plaintext secret manifest
cat > keycloak-admin-secret.yaml << 'EOF'
apiVersion: v1
kind: Secret
metadata:
  name: keycloak-admin-secret
  namespace: keycloak
type: Opaque
stringData:
  username: admin
  password: "your-generated-password-here"
EOF

# Encrypt with SOPS
sops -e -i keycloak-admin-secret.yaml

Decrypt for Inspection

sops --decrypt keycloak-admin-secret.yaml

KSOPS Integration

For GitOps deployment, use KSOPS secret generators to decrypt secrets during kustomize build:

secret-generator.yaml
apiVersion: viaduct.ai/v1
kind: ksops
metadata:
  name: keycloak-secret-generator
  annotations:
    config.kubernetes.io/function: |
      exec:
        path: ksops
files:
  - ./keycloak-admin-secret.enc.yaml
  - ./keycloak-db-credentials.enc.yaml
  - ./harbor-pull-secret.enc.yaml

Credential Rotation Schedule

Credential Rotation Frequency Procedure
Keycloak admin password Every 90 days Update SOPS secret, restart Keycloak pods
Keycloak DB password Every 90 days Update both PostgreSQL and Keycloak SOPS secrets
Harbor pull credentials Every 180 days Regenerate in Harbor, update SOPS secret
Falcosidekick tokens On compromise only Regenerate in Slack/PagerDuty, update SOPS secret
HSM PINs Every 90 days (or per compliance policy) Follow HSM vendor rotation procedure
LDAP bind credentials Per partner state policy Coordinate with partner state AD/LDAP admin

Security Practices

  • Never commit plaintext credentials to Git — always encrypt with SOPS first
  • Never store credentials in environment variables in CI/CD pipelines — use sealed secrets or SOPS
  • Always use openssl rand -base64 24 (or stronger) for generated passwords — never use human-chosen passwords for service accounts
  • Always restrict Secret access via Kubernetes RBAC — only the namespace's service account should read its secrets
  • Verify encryption before committing: sops --decrypt <file> should require the Age key to succeed