Dynamic Secrets — JIT credentials
A partir da v1.7, o CipherVault emite credenciais just-in-time
com TTL ≤ 24h em 6 engines. A app recebe um lease com username/password/
token efêmeros, usa, e o CipherVault revoga automaticamente na expiração
ou release.
License gate: enterprise.
Engines suportadas (17 total)
| Engine | Paradigma | Revoke | Versão |
|---|---|---|---|
postgres | CREATE ROLE + GRANT + DROP ROLE | Imediato | 1.7.0 |
mysql | CREATE USER + GRANT + DROP USER | Imediato | 1.7.1 |
mongodb | createUser / dropUser admin DB | Imediato | 1.7.2 |
aws_sts | AssumeRole / GetFederationToken | No-op (token expira sozinho) | 1.7.1 |
gcp_iam (access_token) | IAMCredentials.GenerateAccessToken | No-op (cap 1h GCP) | 1.7.2 |
gcp_iam (sa_key) | Cria SA key com TTL ≤ 24h (CV cap) | No-op (key expira sozinho) | 3.0 |
azure_sp | Graph addPassword com endDateTime | removePassword | 1.7.2 |
cassandra | CREATE ROLE WITH LOGIN AND PASSWORD | DROP ROLE | 3.0 |
mssql | CREATE LOGIN + CREATE USER FOR LOGIN | DROP USER + DROP LOGIN | 3.0 |
redis (ACL) | ACL SETUSER ... ON >password (Redis 6+) | ACL DELUSER | 3.0 |
active_directory | ldap_modify user/password | Disable + remove | 4.5 |
ldap | OpenLDAP / 389DS / FreeIPA | Disable + remove | 4.5 |
consul | acl_token_create | acl_token_destroy | 4.5 |
nomad | acl_token_create | acl_token_destroy | 4.5 |
rabbitmq | PUT /api/users + permissions | DELETE /api/users | 4.5 |
alicloud_sts | AssumeRole Aliyun | No-op | 4.5 |
mongodb_atlas | Programmatic API key | Revoke key | 4.5 |
hcp_terraform | Workspace variables | Delete vars | 4.5 |
Plugins customizados via Plugin SDK podem adicionar engines proprietários sem fork do backend.
gcp_iam modes
A v3 adicionou template.mode em roles GCP IAM:
{
"engine": "gcp_iam",
"template": {
"mode": "sa_key", // ou "access_token" (default)
"service_account": "etl@project.iam.gserviceaccount.com"
}
}
access_token— token com cap 1h imposto pelo GCP. Adequado para chamadas APIsa_key— SA key JSON com TTL configurável (cap 24h pelo CV). Adequado para ferramentas que esperam credentials.json
mTLS nas engines (v3.0+)
postgres e mysql engines aceitam mTLS na conexão admin:
{
"engine": "postgres",
"connection": {
"host": "db-billing.internal.acme.com.br",
"port": 5432,
"ssl_ca": "<PEM CA>",
"ssl_cert": "<PEM client cert>",
"ssl_key_secret": "internal/db/postgres/cv-admin-key"
}
}
Conceitos
- Backend — conexão com o sistema externo (Postgres, AWS, etc.) que vai emitir creds
- Role — template de permissão e TTL no backend
- Lease — credencial efêmera emitida (
cv_*username + senha gerada)
admin: cria backend → cria role
app: solicita lease (role_id, ttl) → recebe { username, password, expires_at }
usa por TTL
(expira sozinho OU app chama release)
backend executa DROP USER / removePassword
Configuração — admin
1. Criar backend (Postgres)
curl -X POST https://cv.acme.com.br/dynamic-secrets/backends \
-H "Authorization: Bearer $CV_TOKEN" \
-d '{
"name": "billing-postgres-prd",
"engine": "postgres",
"connection": {
"host": "db-billing.internal.acme.com.br",
"port": 5432,
"database": "billing",
"admin_username": "cv_admin",
"admin_password_secret": "internal/db/postgres/cv-admin"
}
}'
A admin_password_secret aponta para um secret armazenado no próprio CV
(meta-protege a credencial admin que cria/destroi roles).
2. Criar role
curl -X POST https://cv.acme.com.br/dynamic-secrets/roles \
-H "Authorization: Bearer $CV_TOKEN" \
-d '{
"backend_id": 12,
"name": "billing-readonly",
"ttl_seconds": 600,
"max_ttl_seconds": 3600,
"creation_statements": [
"CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '\''{{password}}'\'' VALID UNTIL '\''{{expiration}}'\''",
"GRANT pg_read_all_data TO \"{{name}}\""
],
"revocation_statements": [
"REVOKE ALL ON DATABASE billing FROM \"{{name}}\"",
"DROP ROLE IF EXISTS \"{{name}}\""
]
}'
Templating seguro com whitelist anti-SQL injection: somente
{{name}}, {{password}}, {{expiration}}.
3. Modes
direct(default) — CipherVault conecta diretamente ao DB e roda statementssensor(Phase 4 — v1.7.2+) — task vai paradynamic_secret_tasks, sensor remoto puxa via poll 30s e executa em DB interno (sem expor DB para o CV)
Uso pela aplicação
Via SDK (Python)
from ciphervault.admin import AdminClient
cv = AdminClient(url="https://cv.acme.com.br", token=os.environ["CV_TOKEN"])
# Solicita lease
lease = cv.dynamic.request_lease(role_id=42, ttl_seconds=600, reason="ETL daily")
import psycopg2
conn = psycopg2.connect(
host="db-billing.internal.acme.com.br",
user=lease["username"], # cv_etl_<jti>
password=lease["password"],
dbname="billing",
)
# ... use ...
conn.close()
# Release (opcional — TTL expira sozinho)
cv.dynamic.release_lease(lease["id"])
Via CLI Go cv
LEASE=$(cv lease request 42 --ttl 600 --output json)
USER=$(echo "$LEASE" | jq -r .username)
PASS=$(echo "$LEASE" | jq -r .password)
PGPASSWORD="$PASS" psql -h db-billing.internal.acme.com.br -U "$USER" -d billing
Via Secretless Proxy (Postgres apenas, MVP)
secretless-proxy \
--listen :5432 \
--upstream db-billing.internal.acme.com.br:5432 \
--cv-url https://cv.acme.com.br \
--conn-id app_01HXY... \
--role-id 42
# App conecta em localhost:5432 com user/pass arbitrários — proxy injeta cred
psql -h localhost -U dummy -d billing
Operacional
- Cap absoluto 24h — independente de
max_ttl_secondsda role - Job de expiração 60s com leader-lock multi-replica
- Reconcile diário — detecta orphans no backend (usuários
cv_*sem lease ativo no CV) — alertadynamic_lease_orphan_in_backendseverity criticalauto_fix_orphans(v3.0+, opt-in viadynamic_backends.auto_fix_orphans=true) — drop automático de orphans com idade > 24h
- Lease pool / reuso (v3.0+) —
role.lease_reuse_max_usespermite mesma(role, app_connection)reaproveitar lease ativa viaSKIP LOCKED. Reduz RTT inicial do Secretless Proxy de 100ms → 5ms - Rate limiting — token-bucket in-memory, capacity 30, refill 0.5/s
- Prometheus metrics — 7 métricas custom + default process metrics.
/metricsgated porCV_METRICS_ENABLED=true
Tabelas
dynamic_backends -- conexões cadastradas
dynamic_roles -- templates por backend
dynamic_leases -- leases ativas + revogadas
dynamic_secret_tasks -- queue para sensor mode
Tutorial passo a passo
Veja Tutoriais → Rotação automática (alinhar sua rotação com leases dinâmicos para zero-downtime).
Boas práticas
- TTL curto — 5–15 min para ETL/jobs; 1h para sessões interativas. Cap final 24h.
- Modo
sensorem DBs internos — não exponha o DB de produção para o CipherVault SaaS. - Reconcile + alertas — orphan no backend significa drift; investigue imediatamente.
- Statements idempotentes —
IF EXISTSno DROP,OR REPLACEquando aplicável. - Não use admin do banco como
admin_username— crie rolecv_admincom permissões mínimas para criar/dropar roles.