Secrets Management
SOPS + age
Used for encrypting Talos cluster secrets in the repository.
Public key:
age1h7dhxdsnclkeumquf8e3uzet2ppdeum2aykvp3fvqdwhlrnd4dfqwqm8fuKey file location: ~/.config/sops/age/keys.txt
WARNING
The age private key is backed up in 1Password under "Talos Cluster - Age Key (SOPS)". Losing both copies means secrets are unrecoverable.
Encrypt
sops -e talsecret.yaml > talsecret.enc.yamlDecrypt
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops -d talsecret.enc.yamlAnsible Vault
Used for WireGuard private keys and other sensitive Ansible variables.
- Password file:
~/.vault_pass - Encrypted vars:
host_vars/*/vault.yml
Decrypt a vault file
ansible-vault decrypt host_vars/bastion/vault.yml --vault-password-file ~/.vault_passEdit in-place
ansible-vault edit host_vars/bastion/vault.yml --vault-password-file ~/.vault_passGitLab Deploy Tokens
| Service | Token | Scope |
|---|---|---|
| Carzying | gitlab+deploy-token-13400455 | read_registry |
ArgoCD Credentials
ArgoCD admin password is stored in 1Password.
Private Repository Access
ArgoCD uses a credential template to authenticate with all private GitLab repos under the https://gitlab.com/carzying prefix. The Secret is SOPS-encrypted at:
talos/manifests/argocd/repo-creds-gitlab.enc.yamlThe Secret uses the label argocd.argoproj.io/secret-type: repo-creds (note: repo-creds, not repository). This means any new repo under the matching URL prefix is automatically authenticated -- no per-repo Secret needed.
To apply:
sops decrypt talos/manifests/argocd/repo-creds-gitlab.enc.yaml | kubectl apply -f -KSOPS planned
KSOPS integration with ArgoCD is planned so encrypted Secrets can be synced automatically via GitOps, eliminating the manual sops decrypt | kubectl apply step.
Service Credentials
| Service | Account |
|---|---|
| Directus admin | admin@carzying.es |
| ArgoCD admin | Stored in 1Password |
| Semaphore admin | Stored in 1Password |
Semaphore API Token
The Semaphore webhook relay on the bastion (port 8011) uses an API token to trigger task templates. The token is stored in Ansible Vault (vault_semaphore_api_token).
Cloudflare API Token (ExternalDNS)
ExternalDNS uses a Cloudflare API token scoped to the quinza.dev zone for DNS record management. The token is stored as a K8s Secret in the external-dns namespace.
| Property | Value |
|---|---|
| K8s Secret | cloudflare-api-token in external-dns namespace |
| Scope | Zone:DNS:Edit for quinza.dev |
| GCore token | Pending -- needed for carzying.es via a second ExternalDNS instance |
step-ca (Internal CA)
step-ca is deployed on the bastion for internal TLS certificate issuance.
| Property | Value |
|---|---|
| Host | Bastion |
| CA root fingerprint | 3c9abed6d6b0ea7da3b74d0372a3d66b4171641b4ae10c0fbac31138e84036da |
| Provisioner password | Stored in Ansible Vault (vault_step_ca_password) |
Known issue
The step_cli Ansible role references a k3s_server group that no longer exists (migrated to Talos). This does not block anything but should be cleaned up.
Infisical (Rejected)
Infisical was evaluated as a centralized secrets manager but rejected -- it requires approximately 20GB of RAM for managing 15 secrets, which is far too heavy for a homelab.
The current stack (SOPS + age + Ansible Vault + 1Password) is sufficient. The recommended next step is adding KSOPS to ArgoCD for GitOps-managed encrypted secrets.