Firstlume Docs firstlume.io PTEN EN Fale com a gente

Segredos do Vault

O Firstlume não guarda os segredos: quem lê o Vault é o executor, dentro do pod do run, e os valores não passam pelo servidor nem pelo banco. Para isso, o Firstlume emite para cada fase um JWT (ES256, válido por 15 minutos) que diz qual stack está rodando, e o executor o troca por um token do Vault. O token é revogado ao fim da fase.

1. No Firstlume

Defina a conexão da organização com PUT /api/v1/orgs/{org}/vault:

{"address": "https://vault.example.com:8200"}

Os campos opcionais são ca_cert, namespace, auth_path (padrão jwt) e audience (padrão vault).

Defina o papel, herdado como as outras configurações, numa pasta ou no stack:

{"vault_role": "infra-dev"}

FIRSTLUME_PUBLIC_URL (no Helm, controlPlane.publicURL; o padrão é o host do ingress) é o iss dos JWTs.

2. No Vault

Ligue o método jwt confiando no Firstlume, com a descoberta ou com a chave pública:

vault auth enable jwt
vault write auth/jwt/config bound_issuer=https://firstlume.example.com \
  oidc_discovery_url=https://firstlume.example.com      # ou [email protected]
vault policy write infra-dev - <<'EOF'
path "secret/data/infra/dev/*" { capabilities = ["read"] }
EOF
vault write auth/jwt/role/infra-dev role_type=jwt user_claim=sub bound_audiences=vault \
  bound_claims_type=glob bound_claims='{"stack_path": "infra/dev/*"}' \
  token_policies=infra-dev token_ttl=15m

A chave pública fica em GET /api/v1/orgs/{org}/vault/public-key (PEM) e em /.well-known/jwks.json.

3. No repositório

Use {vault: secret/infra/dev/${name}, field: ip} em qualquer valor da declaração. O caminho é o mesmo do vault kv get (KV v1 e v2 são detectados), e outros engines também funcionam.

Claims do JWT

Claim Valor
sub stack:<id>
org a organização
stack_id, stack_name o stack
stack_path pastas e nome, como infra/dev/machines
folder_ids os ids das pastas
run_id, run_type o run
phase plan, apply ou drift

Com bound_claims, um stack de dev não lê segredos de prod, e um papel com phase = apply não serve para o plan. Prefira folder_ids a stack_path se renomear pastas puder mudar o acesso.

Como os valores são tratados

  • Tudo o que vem do Vault é sensível: mascarado no log, e os arquivos saem com 0600.
  • Plan e apply: o apply relê o Vault e confere com o plan (por um hash com chave, sem guardar valores). Se um segredo mudou entre os dois, o apply falha com the secret in <caminho>#<campo> changed since the plan: plan again.
  • Erros dizem o item da declaração, o caminho e o campo, nunca o valor: sem conexão, sem papel, login recusado, permissão negada, segredo ou campo ausente, Vault fora do ar.

Testar sem rodar nada

POST /api/v1/orgs/{org}/stacks/{id}/vault/check faz o login como o stack e diz, por caminho, se o papel pode ler, sem ler nenhum valor:

{"paths": ["secret/infra/dev/n01"]}