CipherVault Guardian — K8s integration v2
A partir da v4.5, o CipherVault entrega uma integração Kubernetes consolidada chamada Guardian — um único Helm chart que substitui (e estende) os 3 caminhos K8s separados das versões anteriores:
| Antes (v4.4) | Agora (v4.5) |
|---|---|
| Mutating Admission Webhook (v1.7.5) | Guardian (Phase 1+2) |
| External Secrets Operator + ESO compat layer | Guardian (Phase 1) |
| Sensor de cluster | Guardian (Phase 1) |
Mais 3 capabilities novas:
- Discovery + Drift — descobre workloads e detecta drift de configuração
- Validating Admission Webhook com 4 rules built-in
- SPIFFE/SPIRE federation opcional para identidade de workload cross-cluster
Arquitetura
┌────────────────────────────────────────────────────┐
│ cluster │
│ │
│ ┌──────────────────┐ ┌─────────────────┐ │
│ │ cv-guardian │ ──────▶ │ CipherVault │ │
│ │ (Go agent) │ HTTPS │ /heartbeat │ │
│ │ │ │ /report │ │
│ │ • discovery │ └─────────────────┘ │
│ │ • classify │ │
│ │ • drift │ │
│ │ • SPIFFE auth │ │
│ └────┬─────────────┘ │
│ │ │
│ │ admission decisions │
│ ▼ │
│ ┌──────────────────┐ │
│ │ ValidatingWebhook│ ◀── kube-apiserver │
│ │ (4 rules) │ │
│ └──────────────────┘ │
└────────────────────────────────────────────────────┘
Phase 1+2: Foundation + Discovery + Drift
cv-guardian Go agent (8 packages)
config— env vars + flags + cluster identityclassify— heurísticas de criticidade (env=prd, labels, namespace)hash— content hash para detecção de driftdiscovery— list workloads no clusterreport— envia/reportperiódico ao CVspiffe— opcional, SVID-based authpolicy— local cache de policieswebhook— HTTP handler para admission webhook
Backend
Tabelas: kube_guardian_clusters, kube_guardian_discoveries.
Endpoints do agent (auth X-Cluster-Token):
POST /kube-guardian/heartbeat
POST /kube-guardian/report
Endpoints admin (JWT):
GET /kube-guardian/clusters
POST /kube-guardian/clusters/:id/policies
GET /kube-guardian/clusters/:id/discoveries
GET /kube-guardian/clusters/:id/drift
Auto-upgrade
Agent compara latest_agent_version retornado pelo heartbeat com a
versão local. Diferença → baixa nova imagem, reinicia o pod via
self-restart graceful (drain conexões → exit 0 → K8s recria).
Phase 3: Validating Admission Webhook
Quando habilitado, o webhook avalia cada CREATE/UPDATE de Deployment,
StatefulSet, Job, CronJob (configurável). 4 rules built-in:
| Rule | O que detecta |
|---|---|
hardcoded-secret-env | Env var literal com pattern de credencial (regex AWS, Stripe, GitHub, etc.) |
privileged-critical-secret | Pod com runAsRoot ou privileged: true consumindo Secret marcado critical |
cross-namespace-no-binding | Secret referenciado em namespace sem vault_member correspondente no CV |
stale-rotation | Secret cujo last_rotated_at no CV passou da política do tenant |
Modos:
audit(default) — apenas registra, não bloqueiablock— rejeita o admission request com 403
Promote de audit → block é gated por dual-control
(Approvals action
kube_guardian_policy_change).
Phase 4: SPIFFE/SPIRE + multi-cluster federation
Opcional. Requer SPIRE deployado no cluster.
internal/spiffeno agent viago-spiffe/v2- Agent autentica no CV via JWT-SVID em vez de token estático
- Tabela
kube_guardian_workload_relationsmapeia SPIFFE IDs para vault membership - Endpoints
/federatione/cross-cluster-pathspermitem Attack Path queries cross-cluster
Instalação via Helm
helm repo add ciphervault https://charts.ciphervault.com.br
helm repo update
# Modo namespace-only (default, RBAC mínimo)
helm install ciphervault-guardian ciphervault/guardian \
--namespace ciphervault-system \
--create-namespace \
--set cv.url=https://cv.acme.com.br \
--set cv.clusterId=cluster_01HXY... \
--set cv.clusterTokenSecretRef=cv-cluster-creds
# Modo cluster-wide (opt-in para Attack Path)
helm install ciphervault-guardian ciphervault/guardian \
--namespace ciphervault-system \
--set rbac.clusterScope=true
# Com Validating Webhook
helm install ciphervault-guardian ciphervault/guardian \
--set webhook.enabled=true \
--set webhook.failurePolicy=Ignore \
--set webhook.defaultMode=audit
Helm chart — 9 kinds renderizados
- Namespace
- ServiceAccount
- Role + ClusterRole (opt-in)
- RoleBinding + ClusterRoleBinding
- ConfigMap (config do agent)
- Secret (cluster credentials — referenciado via env)
- Deployment (agent + webhook server, sidecar)
- Service (admission webhook + metrics)
- ValidatingWebhookConfiguration (opt-in)
Imagem: distroless nonroot:nonroot (UID 65532), linux/amd64 + linux/arm64 em ghcr.io/martinez1991/ciphervault-guardian.
Migration do modelo antigo
Quem usava webhook + ESO + sensor separados:
# 1. Backup das configurações atuais
kubectl get mutatingwebhookconfigurations -o yaml > backup-webhook.yaml
helm get values external-secrets-operator > backup-eso.yaml
# 2. Desinstalar antigos (Helm hook do Guardian faz migration automática)
helm uninstall external-secrets-operator
kubectl delete mutatingwebhookconfigurations cv-injector
# 3. Instalar Guardian
helm install ciphervault-guardian ciphervault/guardian ...
O Helm chart do Guardian roda hooks pre-install que migram:
- ESO
SecretStore→ policies registradas no CV - Annotations dos pods → policies equivalentes
- ConfigMap do antigo Sensor → cluster identity no Guardian
Observabilidade
Métricas Prometheus (:9090/metrics):
cv_guardian_heartbeats_total{result}
cv_guardian_discoveries_total{kind}
cv_guardian_drift_detected_total{kind, severity}
cv_guardian_admission_decisions_total{rule, decision}
cv_guardian_spiffe_validations_total{result}
Boas práticas
- Comece em
auditmode — observe por 1-2 semanas, ajuste regras, então promove parablock - Cluster-wide RBAC apenas se Attack Path — namespace-only é suficiente para uso típico
- Helm chart versionado em GitOps — não use
helm install --setad-hoc em produção - SPIFFE opcional — adicione complexidade. Use apenas se já tem SPIRE deploya outras razões
- Audit cruzado — combine
kube_guardian_drift_detected_totalcom Risk Scoring no CV
Referências
charts/ciphervault-guardian/no repo do produtocv-guardian/README.md— agent architecture detalhada- K8s Operator — para casos de GitOps puro com CRDs (coexiste com Guardian)