Segredos e gerenciamento de chaves

Nesta página

EmDash usa um pequeno conjunto de segredos para previews, comentários, autenticação, armazenamento e plugins. Esta página é o inventário completo: de onde cada segredo vem, onde é armazenado, como rotacioná-lo e o que quebra se for perdido.

Visão geral

SegredoFonteArmazenado emImpacto da perda
EMDASH_ENCRYPTION_KEYOperador (emdash secrets generate)Apenas ambiente / segredo WorkerSegredos de plugins criptografados ficam irrecuperáveis (quando a criptografia em repouso for lançada)
Segredo de previewAuto-gerado (override de env)Tabela options (emdash:preview_secret)Links de preview existentes param de funcionar; novos estão OK
Salt de IPAuto-gerado (override de env)Tabela options (emdash:ip_salt)A continuidade do rate-limit de comentários reseta
Tokens de sessão e APIGerados por sessão/tokenStore de sessões / BD (apenas hashes)Nada — texto plano nunca é armazenado
Credenciais de provedor OAuthVocê (console Google/GitHub)AmbienteLogin via esse provedor para até ser substituído
Segredo TurnstileVocê (painel Cloudflare)AmbienteVerificação CAPTCHA de comentários falha
Credenciais S3Você (provedor de armazenamento)Ambiente ou configuraçãoUpload/download de mídia falha até ser substituído
Segredos de pluginsVocê (UI de configurações do admin)Banco de dados (config / armazenamento de plugins)Re-inserir no admin
Credenciais CLIFluxos de dispositivo emdash login / emdash plugin publish~/.config/emdash/auth.json (modo 0600)Executar o fluxo de dispositivo novamente
Credenciais CLI do registroemdash-plugin atproto OAuth~/.emdash/oauth/, ~/.emdash/credentials.json (modo 0600)Fazer login novamente; identidade reside no seu PDS

A chave de criptografia

EMDASH_ENCRYPTION_KEY é a chave do site para criptografar segredos de plugins em repouso. É fornecida pelo operador e nunca armazenada no banco de dados — o banco de dados contém apenas texto cifrado, portanto um backup vazado não expõe a chave.

Gere uma e defina como variável de ambiente (ou segredo Worker):

npx emdash secrets generate
# emdash_enc_v1_<43 caracteres base64url>

# Cloudflare:
wrangler secret put EMDASH_ENCRYPTION_KEY

O formato é emdash_enc_v1_ seguido de 32 bytes aleatórios como base64url sem padding. A chave é validada na inicialização do runtime; um valor malformado registra um erro para o operador sem derrubar os caminhos de requisição.

Rotação

A variável aceita uma lista de chaves separadas por vírgula. A primeira entrada é a primária e usada para novas gravações; todas as entradas são tentadas para descriptografia. Cada valor criptografado é marcado com uma impressão digital de chave de 8 caracteres (o kid, imprimível via emdash secrets fingerprint <key>), então o runtime escolhe a chave correta automaticamente.

Para rotacionar: gere uma nova chave, coloque-a no início da lista (EMDASH_ENCRYPTION_KEY="nova,antiga"), reimplante e remova a antiga depois que os valores existentes tiverem sido re-criptografados.

Segredos do site gerados

Dois segredos são gerados automaticamente no primeiro uso e persistidos na tabela options, sendo estáveis entre requisições, implantações e isolados. A geração é atômica — cold starts concorrentes convergem em um único valor.

Segredo de preview

Assina URLs de preview (HMAC). Armazenado como emdash:preview_secret; 32 bytes aleatórios, base64url.

  • Override: defina EMDASH_PREVIEW_SECRET (alias legado: PREVIEW_SECRET) se precisar do mesmo segredo em múltiplos processos ou quiser fixá-lo por razões de auditoria. O ambiente sempre vence sobre o valor armazenado.
  • Rotação: delete a linha emdash:preview_secret (ou mude a variável de env) e reimplante. Impacto: links de preview emitidos anteriormente param de validar. Nada mais quebra — um segredo fresco é gerado (ou lido do env) na próxima requisição de preview.
  • Se perdido: nada é irrecuperável. Links de preview são efêmeros por design.

Consulte o guia de preview para como URLs de preview são construídas e verificadas.

Salt de IP

Aplica salt ao hash SHA-256 dos endereços IP dos comentaristas (ip_hash em comentários) usado para limitação de taxa de comentários. Armazenado como emdash:ip_salt. Específico do site, então hashes não são correlacionáveis entre instalações EmDash.

  • Override: defina EMDASH_IP_SALT. Para compatibilidade retroativa, EMDASH_AUTH_SECRET / AUTH_SECRET também são consultados — instalações que historicamente derivaram o salt destes mantêm hashes estáveis.
  • Rotação: mude a variável de env ou delete a linha emdash:ip_salt. Impacto: novos envios de comentários geram valores hash diferentes, então a contagem de rate-limit recomeça para todos. Comentários existentes e seus hashes armazenados não são tocados.
  • Se perdido: sem perda de dados. Apenas a continuidade do rate-limit reseta.

Tokens de sessão e API

  • Sessões usam o store de sessões do Astro (Workers KV no Cloudflare, sistema de arquivos no Node). O cookie carrega um ID de sessão opaco; não há segredo de assinatura para gerenciar. Faça logout para encerrar uma sessão, ou limpe o store de sessões (ex: o namespace KV) para forçar todos a fazer login novamente.
  • Tokens API (prefixos ec_pat_, ec_oat_, ec_ort_) são valores aleatórios opacos de 256 bits; apenas seu hash SHA-256 é armazenado. O texto plano é mostrado uma vez na criação. Rotacione revogando e recriando no admin.
  • Tokens de convite, magic-link e recuperação são de propósito único, armazenados como hashes SHA-256 em auth_tokens, e com tempo limitado (convites 7 dias, magic links 15 minutos).

Não há nada para backup ou rotação proativa: um vazamento de banco de dados expõe apenas hashes, e cada token pode ser revogado ou reemitido pelo admin.

Credenciais de serviço fornecidas pelo usuário

Credenciais para serviços externos são lidas do ambiente e nunca escritas no banco de dados. Rotacione-as no provedor, atualize a variável, reimplante.

ServiçoVariáveis
Login GoogleEMDASH_OAUTH_GOOGLE_CLIENT_ID, EMDASH_OAUTH_GOOGLE_CLIENT_SECRET (ou aliases sem prefixo)
Login GitHubEMDASH_OAUTH_GITHUB_CLIENT_ID, EMDASH_OAUTH_GITHUB_CLIENT_SECRET (ou aliases sem prefixo)
Publicação Marketplace (CI)EMDASH_MARKETPLACE_TOKEN
Turnstile (comentários)EMDASH_TURNSTILE_SECRET_KEY (ou TURNSTILE_SECRET_KEY)
Armazenamento compatível S3S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, S3_BUCKET, S3_REGION

No Cloudflare, defina com wrangler secret put; localmente, coloque em .env. R2 via binding não precisa de credenciais — o acesso é concedido pelo binding no wrangler.jsonc, que é a configuração recomendada no Workers. Veja opções de armazenamento.

Segredos de plugins

Configurações que um plugin declara com type: "secret" (chaves API para provedores de email, CAPTCHAs de formulários, etc.) são inseridas na UI do admin e armazenadas no banco de dados — na tabela options sob plugin:<id>:settings:<key>, ou no armazenamento chave-valor do plugin. Se um segredo armazenado é devolvido à UI do admin depende do plugin; plugins bem escritos retornam apenas um flag “valor definido” em vez do segredo em si (o plugin de formulários incluído faz isso).

  • Rotação: rotacione a chave no provedor e cole o novo valor na página de configurações do plugin. Tem efeito imediato.
  • Se perdido: re-insira o valor no admin. Nada mais depende dele.

Credenciais CLI

A CLI emdash mantém dois tipos de credenciais, ambos em ~/.config/emdash/auth.json (respeitando XDG_CONFIG_HOME), criados com permissões apenas do proprietário (0600):

  • Tokens do siteemdash login autentica contra sua instância EmDash via um fluxo de dispositivo OAuth e armazena o token resultante indexado por URL da instância. emdash logout o remove; por invocação, --token ou EMDASH_TOKEN substitui o token armazenado.
  • Tokens do Marketplaceemdash plugin publish autentica no EmDash Marketplace via um fluxo de dispositivo GitHub e armazena o JWT resultante indexado como marketplace:<origin>. Para publicação CI, defina EMDASH_MARKETPLACE_TOKEN — tem prioridade sobre a credencial armazenada.

Perder o arquivo é inofensivo: execute emdash login (ou emdash plugin publish, que re-executa o fluxo de dispositivo) novamente.

Credenciais CLI do registro de plugins

A CLI separada emdash-plugin (pacote @emdash-cms/plugin-cli) mira o registro experimental do AT Protocol. A publicação lá é vinculada à sua identidade AT Protocol (seu DID de publicador) — o site em si não mantém credenciais de publicação, e instalações verificam artefatos contra checksums de registros de release atribuídos a esse DID.

  • Autentica via atproto OAuth. Os blobs de sessão/estado OAuth residem em ~/.emdash/oauth/, e a identidade do publicador (DID, handle, PDS) é cacheada em ~/.emdash/credentials.json; ambos são escritos com permissões apenas do proprietário.
  • Em CI, forneça a identidade via EMDASH_PUBLISHER_DID, EMDASH_PUBLISHER_HANDLE e EMDASH_PUBLISHER_PDS; EMDASH_REGISTRY_URL substitui o host do registro. O publish automatizado do CI ainda precisa dos arquivos de sessão OAuth em ~/.emdash/oauth/ no runner — as variáveis de env sozinhas não carregam a sessão OAuth.
  • A rotação ou revogação do acesso de publicação acontece na sua conta AT Protocol (ex: senhas de aplicativo), não no EmDash. Veja Atmosphere auth.

Referência rápida de rotação

Eu quero…Fazer isso
Rotacionar a chave de criptografiaPrefixar nova chave: EMDASH_ENCRYPTION_KEY="nova,antiga", reimplantar, remover antiga depois
Invalidar todos os links de previewDeletar a linha de opção emdash:preview_secret (ou mudar o override de env)
Resetar o hashing de rate-limitMudar EMDASH_IP_SALT (ou deletar a linha de opção emdash:ip_salt)
Revogar um token API vazadoAdmin → Usuários → Tokens API → revogar, depois criar substituto
Encerrar todas as sessõesLimpar o store de sessões (namespace Workers KV / diretório de sessões)
Substituir uma credencial de provedorRotacionar no provedor, atualizar variável de env, reimplantar
Substituir uma chave API de pluginRotacionar no provedor, re-inserir nas configurações admin do plugin