Files
home-network-k3s-impl/bootstrap/sops/secret-templates
jakman85andClaude Opus 4.8 1a98429434 feat(phase3): author shared VPN egress gateway (Gluetun/PIA/WireGuard) — author-first
Per ADR-0013: platform/vpn-egress/ = a single shared Gluetun gateway (PIA over WireGuard,
built-in kill-switch FIREWALL=on, native port forwarding), namespace (non-app, NET_ADMIN +
/dev/net/tun), control-API Service, and a pre-wired (commented) pia-credentials SOPS line.
Defined the PIA secret location (platform/vpn-egress, keys username/password → OPENVPN_USER/
OPENVPN_PASSWORD) and updated the SOPS template accordingly.

NOT wired into platform/kustomization.yaml (Phase 3, author-first) — deploy needs PIA creds +
validation of the egress-steering mechanism (Cilium Egress Gateway → the Gluetun node's wg0;
documented in README with options + a fail-closed rationale, deliberately NOT committed as an
untested CiliumEgressGatewayPolicy). WireGuard chosen (UDP, protocol != TCP); PIA supports it on
all regions and the secret stays username/password.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-21 22:19:22 -05:00
..

SOPS Secret Templates

This directory holds reference templates for the SOPS-encrypted secrets that platform components consume. They are not applied and not encrypted.

Why .yaml.example?

Every file here uses a .yaml.example extension so that:

  • kustomize never loads them (they are not .yaml / not listed in any kustomization.yaml), and
  • SOPS never auto-encrypts them (the repo's .sops.yaml creation rules match *.sops.yaml, not *.yaml.example).

They exist purely so the operator can see the exact Kubernetes Secret shape (name, namespace, keys) each component expects. They contain only placeholder values (REPLACE-ME, <fill me>) — never real secrets.

Operator flow (per secret)

For each <name>.yaml.example:

  1. Copy it to the target path shown in the file's top comment, renaming to <name>.sops.yaml. Example:

    cp bootstrap/sops/secret-templates/grafana-admin-credentials.yaml.example \
       platform/monitoring/grafana-admin-credentials.sops.yaml
    
  2. Fill in the real values (replace every REPLACE-ME / <fill me>).

  3. Encrypt in place with SOPS + age:

    sops -e -i platform/monitoring/grafana-admin-credentials.sops.yaml
    
  4. Wire it into the component by adding the resource line (shown in the file's top comment) under resources: in that component's kustomization.yaml:

    resources:
      - grafana-admin-credentials.sops.yaml
    
  5. Commit the encrypted .sops.yaml (ciphertext is safe to commit) and the kustomization.yaml change. Flux decrypts it at reconcile via the cluster age key.

Files in this directory

Template Secret / namespace Phase
cloudflare-api-token.cert-manager.yaml.example cloudflare-api-token / cert-manager 2
cloudflare-api-token.external-dns.yaml.example cloudflare-api-token / external-dns (same token) 2
grafana-admin-credentials.yaml.example grafana-admin-credentials / monitoring 4
alertmanager-smtp.yaml.example alertmanager-smtp / monitoring 4
keycloak-admin-credentials.yaml.example keycloak-admin-credentials / keycloak 6
oauth2-proxy-credentials.yaml.example oauth2-proxy-credentials / oauth2-proxy 6
pia-credentials.yaml.example pia-credentials / TBD (Phase-3 VPN) 3

Master checklist

See bootstrap/sops/CREDENTIALS.md for the full, end-to-end credential provisioning flow and checklist.