Pular para o conteúdo principal

CipherVault 1.5 — Self-rotation cloud, attach-secret e demo-app refatorado

· 4 min para ler
Time CipherVault
Notas oficiais de release

Release com rotação self-managed das credenciais que o CipherVault usa para acessar cloud integrations, demo-app transformado em validador multi-suite, enumeration hardening (UUID externo) e melhorias UX/segurança no fluxo Secrets/Fortress. ~20 commits desde 1.4.1.

✨ Novidades

Self-rotation de credenciais — cloud integrations

Padrão "create → test → delete": cria nova cred, valida que funciona, persiste, só então deleta a antiga. Se qualquer etapa antes do persist falhar, a cred atual continua intacta.

ProviderMecanismo
AWSIAM Access Keys via @aws-sdk/client-iam
GCPService Account Keys via IAM REST
IBMIAM API Keys via /v1/apikeys
  • Manual: POST /cloud-integrations/:id/rotate-credentials + botão "Rotacionar credenciais" no card
  • Auto: opt-in via toggle auto_rotate. Rotação imediata após primeiro sync (queima a cred copy-paste-able) + scheduler 24h com leader lock + retry 1h em failure
  • UI: badge no card mostra "auto-rotate · próxima DD/MM HH:mm", "rotação falhou" (com tooltip do reason), ou "pendente"
  • Schema: auto_rotate, last_credentials_rotated_at, next_rotation_at, rotation_failed_at, rotation_failure_reason em cloud_integrations + index parcial
  • Auditoria: integration_credentials_rotated (manual) e _rotated_auto / _rotation_failed (scheduler)

Não suportado (paradigmas diferentes): Azure, OCI, Huawei (lookups distintos / RSA keypairs); PAMs por design (são rotacionadores, não rotacionados).

Vault attach-secret (referência, não cópia)

POST /vaults/:id/attach-secret { secret_id, kind, promote? }

Atribui secret/fortress existente a outro cofre por referência (mesmo id em N cofres). Rotação reflete em todos. Idempotente.

  • Validações: requireVaultAccess('write') no destino + canAccessSecret na origem + env consistency (vault PRD exige promote=true pra absorver dev)
  • UI: dialog reutilizável "Adicionar a outro cofre" no card de Secret e Fortress
  • Decisão de design: rejeitar duplicação por valor evita rotation drift (dois secrets divergem após uma rotacionar e a outra não)

Custom rotation script (Secrets + Fortress)

Nova platform custom_script no RotationModal com selector de linguagem:

  • Shell / Python 3 / JavaScript (Node) / Java (JBang)

Textarea com placeholder contextual por linguagem; variáveis disponíveis: {{new_password}} no template + $NEW_SECRET no env. Sensor é responsável pela execução.

users.public_id UUID externo (anti-enumeration)

IDs sequenciais em URL vazam contagem de users. Solução:

  • Migration: users.public_id UUID NOT NULL DEFAULT gen_random_uuid() UNIQUE + backfill + extension pgcrypto
  • GET/PUT/DELETE /users/:id aceita ambos os formatos (helper userIdClause discrimina por regex v4)
  • Frontend (IAMSettings) prefere public_id em update/delete (fallback pro id int)

Aviso Fortress no SecretForm

Banner violeta no topo do form (modo criação) direciona credenciais críticas pra Fortress; reposiciona Secrets como "staging para sync com cloud/PAM". Internal continua disponível como destino válido.

🧪 Demo-app — refatorado completo

Era single-purpose mTLS demo (~220 linhas); agora é validador multi-tab de toda a superfície pública do CipherVault (~1500 linhas):

  • 7 suites de smoke test: AppConnection (mTLS+DPoP), Auth (PAT lifecycle), Secrets CRUD, Fortress, Vaults RBAC, Audit + License, OIDC Federation (com mock issuer in-memory)
  • OIDC mock issuer: keypair RSA-2048 in-memory, expõe .well-known/openid-configuration + jwks.json + endpoint utilitário /issue?sub=.... Auto-setup via PAT cria a cloud_integration oidc_custom
  • Trace HTTP por teste: cada teste captura todas as requests com método/URL/status/ms + headers (Authorization sanitizado) + bodies (truncados em 5KB), renderiza em <details> expansível
  • Run all: botão na home agrega pass/fail das 7 suites
  • Seed: cria 50–100 (configurável) de cada entidade — vaults, secrets, fortress, integrations, app_connections, paths, users
  • Cleanup: deleta tudo que o seed criou (match por prefixo seed-), ordem reversa de FKs
  • Perf test: spawn N workers concorrentes por D segundos, gera relatório com p50/p95/p99 + latências por quarto da janela + detecção automática de degradação (p95(Q4) > 1.5×p95(Q1) ou error rate > 1%)

🐛 Correções

  • risk_scores.secret_id FK sem ON DELETE: bloqueava qualquer DELETE de secret com score (UI inteira). Migrado pra ON DELETE SET NULL (alinhado com leak_findings)
  • Demo-app trace interceptor: callback retornava undefined, fazia testes 200/201 aparecerem como FAIL. Fix: success interceptor agora retorna res
  • OIDC PROVIDER_NOT_FOUND: setup manual era passo gargalo; agora o teste de Setup auto-cria a cloud_integration via API
  • Fortress rotate: test referenciava r.active_version mas endpoint retorna r.new_version — aceita ambos

🧪 Testes

186 cases passando em 17 suites.

Migrations

  • users.public_id UUID + index único + extension pgcrypto
  • cloud_integrations.auto_rotate / last_credentials_rotated_at / next_rotation_at / rotation_failed_at / rotation_failure_reason + partial index
  • risk_scores.secret_id_fkey recreate com ON DELETE SET NULL (DO block idempotente)

Breaking

Nada. Tudo opt-in: auto_rotate default OFF, attach-secret é endpoint novo, public_id complementa o id sem substituir.