Cofre de segredos
Cifrar por envelope, rotacionar a chave sem reescrever os dados, e recusar o dado adulterado.
Uma chave que nunca é trocada é uma chave que um dia vaza e continua valendo. O motivo de ninguém trocar é sempre o mesmo: trocá-la tornaria ilegível tudo que ela cifrou. O envelope resolve — os dados são cifrados por uma chave própria, e só essa chave pequena é cifrada pela mestra.
| Peça | O que ela exercita |
|---|---|
Ch.cofre | as chaves com propósito e prazo |
envelopar / desenvelopar | DEK por dado, KEK mestra |
rotacionar | a chave nova, mantendo as antigas |
recifrar | trocar a mestra sem tocar nos dados |
Estrutura#
text
cofre/
src/
cofre.df abrir, guardar, ler
rotacao.df o job mensal
tests/forge.toml
[project]
name = "cofre"
version = "0.1.0"
description = "Cofre de segredos"
entry = "src/main.df"
dataforge = ">=1.1"
[dependencies]
[scripts]
start = "run src/main.df"
test = "test tests/"
O núcleo#
Este bloco roda sozinho — copie para um arquivo e rode dataforge run. Ele termina com assert, e é assim que esta página é conferida a cada build.
src/cofre.df
adopt Arcane.Chaves as Ch
adopt Arcane.Bytes as Bytes
cofre := Ch.cofre()
cofre.gerar("mestra", proposito := "cifrar")
segredos := {}
action guardar(nome, valor):
segredos[nome] := cofre.envelopar(valor, "mestra")
// O envelope guarda BYTES: um segredo pode ser um certificado binario.
// Quem sabe que ali mora texto converte na saida.
action ler(nome):
yield Bytes.para_texto(cofre.desenvelopar(segredos[nome]))
guardar("banco", "postgres://app:s3nh4@db/loja")
guardar("stripe", "chave-de-teste-ficticia")
// A rotacao: a chave nova passa a cifrar, a antiga continua abrindo.
nova := cofre.rotacionar("mestra", "cifrar")
assert ler("banco") is "postgres://app:s3nh4@db/loja"
// E o job de rotacao recifra so as DEKs — os dados ficam onde estao.
cycle nome in segredos.keys():
segredos[nome] := cofre.recifrar(segredos[nome], "mestra")
assert segredos["banco"]["kid"] is nova.kid
out "rotacionado; o passado continua legivel"O teste#
No projeto, a regra mora em src/ e o teste a importa pelo caminho relativo — dataforge test tests/ descobre o arquivo sozinho.
tests/nucleo_test.df
adopt ../src/cofre as C
crucible "cofre":
trial "o que se guarda volta igual":
C.guardar("x", "valor")
expect C.ler("x") is "valor"As decisões#
| Decisão | Sem ela |
|---|---|
| envelope (DEK/KEK) | trocar a mestra é reescrever cada segredo |
o kid dentro do envelope | com cinco chaves, não se sabe qual abre o quê |
| a chave tem propósito | a chave que assina token também decifra backup |
| a integridade é barulhenta | o dado adulterado abre como void e o programa grava nada onde havia um valor |
Para ir além#
- O ciclo de vida inteiro: Criptografia e chaves.
- Onde a mestra mora em produção: fora do processo — KMS ou variável de ambiente.
- A referência: Arcane.Chaves.
Volte para todos os tipos de projeto.