# 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 ```json title="central.app.json" { "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 ```javascript title="backend/src/routes/omie.js" 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. > [!WARNING] > `use` **não é sandbox**: código consumidor pode copiar, logar ou exfiltrar strings. Nunca registre payload, headers, erros de SDK externo ou resposta remota sem sanitização. A criptografia protege valores em repouso; um processo backend comprometido pode acessá-los. ## Provisionamento e recadastro - Na publicação, o delivery cria o Secret imutável `oon-core-secrets` (e o marcador `oon-core-secrets-initialized`), montando só `OON_SECRETS_KEY` do 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**: ```bash title="backend/.env" 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. Fonte: https://sdk.oonapps.com/docs/capabilities/segredos