Prompt
I need a practical secrets setup for a startup with GitHub Actions and Kubernetes. What would you recommend?
Latest observation
For a startup, I’d recommend a setup that is:
- simple enough to operate
- secure by default
- works well with GitHub Actions and Kubernetes
- easy to grow later
Recommended approach
1) Use a real secret manager as the source of truth
Pick one of:
- HashiCorp Vault if you want maximum flexibility and are okay running it
- AWS Secrets Manager / GCP Secret Manager / Azure Key Vault if you’re already on a cloud
- 1Password Secrets Automation if you want something very startup-friendly and less ops-heavy
If you’re on AWS/GCP/Azure, I’d usually choose the cloud secret manager first. It’s the least painful.
2) Don’t store long-lived secrets in GitHub if you can avoid it
Use GitHub Actions for short-lived authentication to cloud/Kubernetes.
Best pattern:
- GitHub Actions authenticates via OIDC
- OIDC grants short-lived credentials to:
- cloud provider
- deployment role
- secret access role
This avoids putting static cloud keys in GitHub Secrets.
3) In Kubernetes, don’t manually manage app secrets in plain Secret YAML
Instead, use one of these patterns:
Best practical option:
External Secrets Operator (ESO)
Flow:
- app secrets live in your secret manager
- Kubernetes syncs them into native
Secretobjects - workloads consume them normally
This is usually the easiest and cleanest startup setup.
Alternative:
- Secrets Store CSI Driver if you prefer mounting secrets directly into pods without creating Kubernetes Secrets
For most teams, External Secrets Operator is simpler.
A good startup architecture
CI/CD
- GitHub Actions uses OIDC
- no static cloud access keys in GitHub
- Actions can:
- build images
- push to registry
- deploy to Kubernetes
- update config references
Secret storage
- store app secrets in:
- AWS Secrets Manager / GCP Secret Manager / Azure Key Vault
- or Vault if self-managed
Kubernetes consumption
- install External Secrets Operator
- define
ExternalSecretresources - sync secrets into namespaces
Local dev
- don’t copy production secrets onto laptops
- use:
.env.example- local dev secrets from 1Password, Vault, or dev-only secret manager entries
What I would actually recommend by company stage
If you’re on AWS
Use:
- AWS Secrets Manager
- IRSA for pod-to-AWS auth
- GitHub OIDC
- External Secrets Operator
This is a very solid default.
If you’re on GCP
Use:
- Google Secret Manager
- Workload Identity
- GitHub OIDC
- External Secrets Operator
If you’re on Azure
Use:
- Azure Key Vault
- Workload Identity
- GitHub OIDC
- External Secrets Operator
If you’re cloud-agnostic or multi-cloud
Use:
- HashiCorp Vault
- GitHub OIDC
- Kubernetes auth or AppRole avoided if possible
- External Secrets Operator or Vault Agent injection
Minimal setup I’d suggest for most startups
If you want the lowest-friction setup that’s still good:
- GitHub OIDC for Actions authentication
- Cloud secret manager for production secrets
- External Secrets Operator in Kubernetes
- Sealed Secrets only if you absolutely need GitOps-friendly encrypted manifests
- No static cloud keys in GitHub
- Separate dev/staging/prod secret spaces
- Rotate secrets periodically
- Use least-privilege IAM/RBAC
What to avoid
- putting plaintext secrets in GitHub Actions secrets unless necessary
- committing Kubernetes
SecretYAML to git - sharing one secret across all environments
- using the same credentials for CI and production runtime
- giving GitHub Actions broad admin access to your cloud account
Practical implementation pattern
GitHub Actions
- authenticate with OIDC
- assume a deploy role
- deploy Helm chart or manifests
Kubernetes
ExternalSecretpulls DB password/API key from secret manager- app reads from env vars or mounted secrets
- use namespace-scoped permissions
Access model
- CI role: can deploy, not read all secrets
- runtime role: can read only the secrets needed by that app
- human access: via SSO and break-glass process
My default recommendation
If you want one concrete answer:
Use GitHub OIDC + your cloud provider’s secret manager + External Secrets Operator in Kubernetes.
That’s the best balance of:
- security
- simplicity
- maintainability
- startup practicality
If you want, I can also give you:
- a reference architecture diagram
- a step-by-step AWS/GCP/Azure setup
- a sample GitHub Actions workflow + Kubernetes ExternalSecret YAML