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¶
KSOPS Integration¶
For GitOps deployment, use KSOPS secret generators to decrypt secrets during kustomize build:
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