Security¶
Secret Management¶
Secrets are never stored in Git. They are synced from Vault (running on the NAS) into Kubernetes using the ExternalSecrets Operator:
graph LR
A[Vault\nNAS] --> B[ClusterSecretStore]
B --> C[ExternalSecret\nper app]
C --> D[Kubernetes Secret\nowned by ESO]
Two ClusterSecretStore resources connect to Vault:
| Store | Vault path | Used for |
|---|---|---|
vault |
apps/ |
Application secrets |
vault-infra |
infra/ |
Infrastructure secrets |
Note
ExternalSecrets refresh every hour. When an app is deleted and its ExternalSecret is pruned, the owned Kubernetes Secret is deleted automatically.
SSO¶
Authentik is the identity provider for the homelab, providing OIDC and LDAP authentication for all services. See Authentik for full configuration details.
TLS¶
All public-facing services use TLS certificates issued by Let's Encrypt via cert-manager. The DNS01 challenge is used with Cloudflare as the DNS provider, so certificates can be issued without exposing any ports publicly.
A single ClusterIssuer named letsencrypt is available cluster-wide. Apps opt in by adding the annotation:
Tip
TLS is terminated at Traefik for NAS-routed services, and at the shared Gateway for cluster apps. In both cases, certificates are managed automatically — no manual renewal needed.
DNS¶
ExternalDNS automatically creates Pi-hole DNS records for Kubernetes Ingress, Service, and HTTPRoute resources. When a new app is deployed with a hostname, its DNS record appears in Pi-hole without any manual configuration.
Note
ExternalDNS uses upsert-only policy — it creates and updates records but never deletes them, avoiding accidental removal.
Remote Access¶
Tailscale provides secure remote access to the cluster without exposing any ports to the internet. The Tailscale Operator runs in the cluster and allows devices tagged tag:k8s-admin in the Tailscale ACL to access the Kubernetes API server directly.