Segredos (core.secrets)
Credenciais de integrações cifradas com AES-256-GCM, com chave por runtime e ambiente — put, status, use e remove a partir do contexto autorizado.
core.secrets V1 guarda credenciais (por exemplo appKey/appSecret de um ERP) cifradas no banco do App. É exclusivo para single_tenant dedicado, opt-in, e nenhum endpoint ou CRUD automático expõe a coleção técnica.
1. Declare
{
"capabilities": ["core.secrets"],
"capabilitySettings": { "core.secrets": { "enabled": true } }
}
Nunca coloque valores ou chave em manifesto, frontend, repositório ou imagem. O Publisher transmite somente a declaração; Core e executor precisam da release com V1.
2. Use no backend
const crypto = require("node:crypto");
const { capabilities, defineRoutes } = require("@oondemand/oon-core-back");
defineRoutes("/omie", (router) => {
router.private.put("/credenciais", { permission: "segredos.manage", sensitiveBody: true }, async (req, res) => {
const options = { name: "omie", context: req.accessContext, correlationId: crypto.randomUUID() };
const { appKey, appSecret } = req.body ?? {};
res.json(await capabilities.secrets.put({ ...options, value: { appKey, appSecret } }));
});
router.private.get("/credenciais", { permission: "segredos.manage" }, async (req, res) => {
res.json(await capabilities.secrets.status({ name: "omie", context: req.accessContext }));
});
router.private.post("/sincronizar", { permission: "omie.sync", sensitiveBody: true }, async (req, res) => {
await capabilities.secrets.use({ name: "omie", context: req.accessContext }, async (credential) => {
// Serviço do App controla URL, timeout, redirects e sanitização do retorno.
await omie.call(credential);
});
res.json({ ok: true });
});
router.private.delete("/credenciais", { permission: "segredos.manage", sensitiveBody: true }, async (req, res) => {
res.json(await capabilities.secrets.remove({ name: "omie", context: req.accessContext }));
});
});
context é o contexto autorizado do Core — nunca copie identidade do body/header. A V1 verifica App, tenant e usuário; a autorização da operação é da rota.
Contrato
| Operação | Comportamento |
|---|---|
put |
Substitui atomicamente o objeto inteiro; retorna { state: "available" }. Valor incompatível exige replace: true. |
status |
absent, available ou reentry_required (com reason/action). Erro de banco nunca vira "ausente". |
use(options, callback) |
Aguarda o callback e descarta seu retorno. Erros viram SECRETS_USE_FAILED, sem mensagem externa. |
remove |
Idempotente; não precisa decifrar. |
- Nome:
[a-z][a-z0-9._-]{0,63}, definido pelo backend. - Valor: objeto JSON não vazio, até 16 KiB. Sem merge parcial, histórico ou compare-and-swap.
- Correlação: 1–128 caracteres alfanuméricos,
:,_ou-, gerada no backend. - Auditoria técnica: registra operação, ator, escopo, nome, correlação e instante — nunca valor, envelope ou chave.
Criptografia
AES-256-GCM, chave aleatória de 32 bytes, IV novo de 12 bytes por gravação, envelope v1 autenticado com AAD que inclui App, identidade do runtime dedicado (appId + namespace), ambiente, tenant e nome. Uma chave por namespace/ambiente. As coleções oon_secrets e oon_secret_audit são técnicas, fora de CRUD/metadata/export.
Provisionamento e recadastro
- Na publicação, o delivery cria o Secret imutável
oon-core-secrets(e o marcadoroon-core-secrets-initialized), montando sóOON_SECRETS_KEYdo ambiente alvo. - Republicação, reinício e réplicas reutilizam Secret e coleção. Promoção provisiona chave independente no destino, sem copiar dados ou chave da origem.
- Valor incompatível com chave íntegra → usuário autorizado reenvia o objeto completo com
replace: true. - Chave ausente → operador restaura o Secret correspondente.
- Sem chave recuperável → procedimento operacional autorizado remove o Secret daquele ambiente, reprovisiona e solicita recadastro. Não há endpoint para trocar chave, nem rotação transparente nesta V1.
Desenvolvimento local
O exemplo (create-central-oon example) instala a página /segredos, menu, permissão segredos.manage e rotas. Configure no ambiente do backend:
OON_SECRETS_KEY=<32 bytes em base64>
OON_SECRETS_INSTANCE=local:sample
OON_SECRETS_TENANT=local:tenant
APP_ENVIRONMENT=desenvolvimento
Nunca use a chave local na Plataforma. Sem chave, as demais páginas continuam operacionais.