Docs/ Segurança/ Gerenciamento de Segredos

Gerenciamento de Segredos

Armazene e gerencie valores de configuração sensíveis com criptografia AES-256-GCM, acesso com escopo e rotação sem tempo de inatividade.

Como o sh0 Criptografa Segredos

Todos os segredos (variáveis de ambiente marcadas como sensíveis) são criptografados em repouso no banco de dados SQLite do sh0 usando criptografia autenticada AES-256-GCM, alimentada pela biblioteca de criptografia ring.

O fluxo de criptografia:

  1. Uma chave de criptografia única de 256 bits é gerada durante a instalação do sh0 e armazenada no diretório de configuração do servidor.
  2. Cada valor de segredo é criptografado com um nonce único (aleatório de 96 bits), garantindo que valores idênticos produzam textos cifrados diferentes.
  3. A tag de autenticação (GCM) garante que segredos não possam ser adulterados sem detecção.
  4. Segredos são descriptografados apenas em memória quando injetados nos contêineres na inicialização.
Note
Os valores são criptografados em repouso e nunca gravados nos logs. As listas os mostram mascarados; um membro com o papel Developer ou superior pode revelá-los no painel, ou pela API com ?reveal=true. Uma chave de API somente leitura também pode: dê chaves e papéis apenas a pessoas e ferramentas a quem você confiaria seus segredos.

Adicionando Segredos pelo Painel

A forma mais comum de gerenciar segredos é pelo painel de Variáveis de Ambiente do dashboard.

  1. Navegue até sua aplicação e abra Configurações → Variáveis de Ambiente.
  2. Clique em Adicionar Variável.
  3. Insira o nome da variável (ex.: DATABASE_URL).
  4. Insira o valor.
  5. Cada valor é criptografado antes de ser armazenado; não há nada para ativar.
  6. Clique em Salvar.
Painel de variáveis de ambiente com formulário de adição de variável

Via API:

Terminal
curl -X POST https://panel.example.com/api/v1/apps/APP_ID/env-vars \
  -H "Authorization: Bearer $SH0_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "DATABASE_URL",
    "value": "postgres://user:pass@db:5432/mydb"
  }'
Tip
As alterações nas variáveis de ambiente valem a partir da próxima implantação. Reimplante a app depois de salvá-las.

Importação em Massa de Arquivo .env

Se você tem um arquivo .env existente, pode importar todas as variáveis de uma vez.

  1. No painel de Variáveis de Ambiente, clique em Importação em Massa.
  2. Cole o conteúdo do seu arquivo .env ou faça upload diretamente.
  3. O sh0 analisa o arquivo e mostra um preview de todas as variáveis.
  4. Revise, marque valores sensíveis como segredos e clique em Importar.
Diálogo de importação em massa mostrando conteúdo do arquivo .env analisado

O analisador suporta sintaxe padrão .env:

.env
# Database
DATABASE_URL=postgres://user:pass@db:5432/mydb
REDIS_URL=redis://redis:6379

# API Keys
STRIPE_SECRET_KEY=sk_live_abc123
SENDGRID_API_KEY=SG.xyz789

# App Config
NODE_ENV=production
PORT=3000
Warning
A importação em massa sobrescreverá variáveis existentes com o mesmo nome. Variáveis não presentes no arquivo de importação permanecem inalteradas.

Escopo de Segredos

Segredos podem ser definidos em dois níveis, dando controle sobre quais contêineres têm acesso a quais valores.

Segredos em Nível de Stack

Segredos em nível de stack são compartilhados entre todos os serviços em uma stack. Isso é ideal para configuração compartilhada como credenciais de banco de dados que múltiplos serviços precisam.

Variáveis de ambiente em nível de stack compartilhadas entre todos os serviços

Defina um segredo em nível de stack em Configurações da Stack → Variáveis de Ambiente, ou via API:

Terminal
curl -X POST https://panel.example.com/api/v1/projects/PROJECT_ID/env-vars \
  -H "Authorization: Bearer $SH0_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "DATABASE_URL",
    "value": "postgres://user:pass@db:5432/mydb"
  }'

Segredos em Nível de Aplicação

Segredos em nível de aplicação são específicos a um único serviço. Eles têm precedência sobre segredos em nível de stack com o mesmo nome, permitindo sobrescrever valores compartilhados para serviços individuais.

Note
Ordem de precedência: Variáveis em nível de aplicação sobrescrevem as de nível de stack. Se ambas definem DATABASE_URL, o valor em nível de aplicação é usado para aquele serviço específico.

Rotação de Segredos

Rotacionar um segredo significa atualizar o valor e reimplantar a app que o usa:

  1. Atualize o valor no painel ou pela API.
  2. Reimplante a app: o novo contêiner inicia com o novo valor.
  3. O contêiner antigo continua atendendo o tráfego até o novo passar na verificação de saúde.
  4. Em seguida, o tráfego passa para o novo contêiner.
Terminal
curl -X PATCH https://panel.example.com/api/v1/apps/APP_ID/env-vars/ENV_ID \
  -H "Authorization: Bearer $SH0_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "value": "sk_live_new_key_456"
  }'

curl -X POST https://panel.example.com/api/v1/apps/APP_ID/deployments \
  -H "Authorization: Bearer $SH0_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'
Rotação de segredo com implantação blue-green em andamento
Tip
Para rotação de senha de banco de dados, atualize a senha no banco de dados primeiro, depois atualize o segredo no sh0 e reimplante. Essa ordem evita falhas de conexão durante a transição.

Acessando Segredos nos Contêineres

Segredos são injetados nos contêineres como variáveis de ambiente padrão. Sua aplicação os acessa da mesma forma que acessaria qualquer variável de ambiente:

Node.js
const dbUrl = process.env.DATABASE_URL;
const stripeKey = process.env.STRIPE_SECRET_KEY;
Python
import os
db_url = os.environ["DATABASE_URL"]
stripe_key = os.environ["STRIPE_SECRET_KEY"]
Rust
let db_url = std::env::var("DATABASE_URL")?;
let stripe_key = std::env::var("STRIPE_SECRET_KEY")?;

Segredos são definidos na inicialização do contêiner e permanecem disponíveis por toda a vida do contêiner. Eles não são gravados em disco dentro do contêiner.

Danger
Nunca registre variáveis de ambiente em logs ou as inclua em relatórios de erro. Embora o sh0 proteja segredos em repouso e em trânsito, o código da sua aplicação também deve tratá-los com responsabilidade.