Encryption-as-a-Service (EaaS)
A partir da v1.7.4, o CipherVault expõe API REST para apps cifrarem e decifrarem payloads sem precisar gerenciar chaves localmente.
Caso de uso típico: field-level encryption de PII em DB do app — o
banco armazena eaas:v1:pii:3:... como string, e quando precisa do valor,
chama /eaas/keys/pii/decrypt para obter o plaintext.
Wire format
eaas:v1:{key_name}:{version}:{iv_b64}:{ct_b64}:{tag_b64}
key_name— nome da chave (e.g.pii,card_pan)version— versão da chave usada (rotações criam nova versão)iv— IV de 96 bits AES-GCMct— ciphertexttag— tag de autenticação 128 bits
Versões antigas continuam decifráveis após rotação — apenas
encrypt usa a versão mais recente.
Endpoints
POST /eaas/keys Criar chave (admin)
GET /eaas/keys Listar chaves
POST /eaas/keys/:name/rotate Cria nova versão
POST /eaas/keys/:name/encrypt Cifrar
POST /eaas/keys/:name/decrypt Decifrar
DELETE /eaas/keys/:name Apaga chave (reason ≥ 10 chars)
Exemplo
Criar chave
curl -X POST https://cv.acme.com.br/eaas/keys \
-H "Authorization: Bearer $CV_TOKEN" \
-d '{
"name": "pii",
"description": "Field-level encryption de PII (CPF, RG, etc.)",
"delete_protection": true
}'
Cifrar
curl -X POST https://cv.acme.com.br/eaas/keys/pii/encrypt \
-H "Authorization: Bearer $CV_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"plaintext": "Rafael Martinez",
"aad": "user:42|field:full_name"
}'
# Resposta:
# { "envelope": "eaas:v1:pii:3:dGVzdA==:cGxhaW50ZXh0Y2lwaGVy:dGFn" }
aad (Additional Authenticated Data) é opcional. Se você cifra com aad,
precisa decifrar com o mesmo aad — protege contra remontagem
(envelope de outro user/field não decripta mesmo com a chave certa).
Decifrar
curl -X POST https://cv.acme.com.br/eaas/keys/pii/decrypt \
-H "Authorization: Bearer $CV_TOKEN" \
-d '{
"envelope": "eaas:v1:pii:3:dGVzdA==:...",
"aad": "user:42|field:full_name"
}'
# Resposta:
# { "plaintext": "Rafael Martinez" }
Rotacionar
curl -X POST https://cv.acme.com.br/eaas/keys/pii/rotate \
-H "Authorization: Bearer $CV_TOKEN" \
-d '{ "reason": "Rotação trimestral PCI" }'
A versão antiga continua válida para decrypt. Apenas novos encrypt
usam a versão nova.
SDK Python
from ciphervault.admin import AdminClient
cv = AdminClient(url="https://cv.acme.com.br", token=os.environ["CV_TOKEN"])
envelope = cv.eaas.encrypt(
key_name="pii",
plaintext=b"Rafael Martinez",
aad="user:42|field:full_name",
)
# guarda envelope no DB do app...
# depois...
plaintext = cv.eaas.decrypt(envelope=envelope, aad="user:42|field:full_name")
Implementação
- AES-256-GCM — autenticado, IV aleatório de 96 bits
- Key versioning — DEK por versão, KEK envelope-encripta DEK em DB
- DEK plaintext em cache 60s — minimiza overhead em alta carga
- AAD opcional — bound a contexto do app
- Payload máximo 1 MB — para payloads maiores, use streaming via blob storage + EaaS no metadata
- Auth flexível — JWT bearer OU
X-Client-Id/X-Client-Secret(AppConnection) - Audit em todas operações — sem plaintext nos logs
Delete protection
Default delete_protection: true. DELETE exige body com
{ reason: string ≥ 10 chars } e — em tenants Enterprise — passa pelo
fluxo de Approvals.
⚠️ Delete descarta TODAS as versões — qualquer ciphertext em DB do app fica inutilizável. Não há recovery.
Casos de uso
- PII em DB do app — CPF, RG, dados de cartão, dados clínicos
- Tokens de webhook — receber webhook, cifrar payload sensível, processar async
- Backup encriptado — cifrar arquivo antes de upload S3 sem expor chave AWS KMS
- Sealed envelopes — comunicação app→app sem TLS direto
Limitações atuais
- Sem suporte a client-side encryption — todo
encryptexige round-trip ao CV (latência adicional) - Sem stream encryption — payload limitado a 1 MB
- Sem suporte a algoritmos além de AES-256-GCM
Boas práticas
- Sempre use AAD quando há contexto natural (user_id, field_name) — defesa em profundidade
- Rotacione regularmente — trimestral atende PCI, mensal é melhor
- Não cifrar dados públicos — overhead injustificado
- Monitore taxa de decrypt — picos podem indicar leak de envelope (cifrar+decifrar não vaza dado, mas vaza padrão de uso)
- Delete protection sempre ON em produção