Skip to content

Secrets Management

SOPS + age

Used for encrypting Talos cluster secrets in the repository.

Public key:

age1h7dhxdsnclkeumquf8e3uzet2ppdeum2aykvp3fvqdwhlrnd4dfqwqm8fu

Key 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

bash
sops -e talsecret.yaml > talsecret.enc.yaml

Decrypt

bash
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt sops -d talsecret.enc.yaml

Ansible 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

bash
ansible-vault decrypt host_vars/bastion/vault.yml --vault-password-file ~/.vault_pass

Edit in-place

bash
ansible-vault edit host_vars/bastion/vault.yml --vault-password-file ~/.vault_pass

GitLab Deploy Tokens

ServiceTokenScope
Carzyinggitlab+deploy-token-13400455read_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.yaml

The 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:

bash
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

ServiceAccount
Directus adminadmin@carzying.es
ArgoCD adminStored in 1Password
Semaphore adminStored 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.

PropertyValue
K8s Secretcloudflare-api-token in external-dns namespace
ScopeZone:DNS:Edit for quinza.dev
GCore tokenPending -- 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.

PropertyValue
HostBastion
CA root fingerprint3c9abed6d6b0ea7da3b74d0372a3d66b4171641b4ae10c0fbac31138e84036da
Provisioner passwordStored 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.

Quinza Infrastructure