Objetivo
Guardar credenciais GCP (Service Account JSON) de forma encriptada usando pass + YubiKey, eliminando arquivos JSON em disco.
Estratégia
Em vez de apontar GOOGLE_APPLICATION_CREDENTIALS para um arquivo em disco, o conteúdo do JSON é guardado encriptado no pass e um wrapper script cria um arquivo temporário on-demand — que é apagado ao fim da execução.
Passo a passo
1. Guardar o JSON no pass
# Copia o conteúdo do JSON como uma entrada no pass
cat ./sua-service-account.json | pass insert --multiline gcp/nome-do-projeto-saConfirma que ficou correto:
pass show gcp/nome-do-projeto-sa | head -52. Deletar o arquivo em disco
# Use gshred para apagar com segurança
gshred -u ./sua-service-account.json3. Wrapper script gcp-run.sh
#!/usr/bin/env bash
# gcp-run.sh — roda um comando com GOOGLE_APPLICATION_CREDENTIALS decriptado via pass
set -euo pipefail
PASS_KEY="${GCP_PASS_KEY:-gcp/nome-do-projeto-sa}"
# Cria arquivo temporário seguro (o mktemp substitui os Xs por caracteres aleatórios)
CREDS_FILE=$(mktemp /tmp/gcp-creds-XXXXXX.json)
# Garante limpeza ao sair (mesmo com erro)
trap 'rm -f "$CREDS_FILE"' EXIT
# Decripta e escreve no temp file
pass show "$PASS_KEY" > "$CREDS_FILE"
# Exporta e executa o comando passado
GOOGLE_APPLICATION_CREDENTIALS="$CREDS_FILE" exec "$@"chmod +x gcp-run.shA variável GCP_PASS_KEY pode ser sobrescrita por projeto:
GCP_PASS_KEY=gcp/outro-projeto ./gcp-run.sh python main.py4. Uso
Antes:
GOOGLE_APPLICATION_CREDENTIALS=./sa.json python main.pyDepois:
./gcp-run.sh python main.py
./gcp-run.sh uvicorn app.main:app --reload5. Variante com direnv (opcional)
# .envrc
export _GCP_CREDS_FILE=$(mktemp /tmp/gcp-creds-XXXXXX.json)
pass show gcp/nome-do-projeto-sa > "$_GCP_CREDS_FILE"
export GOOGLE_APPLICATION_CREDENTIALS="$_GCP_CREDS_FILE"⚠️ Com
direnvo cleanup é menos elegante — prefira o wrapper script para maior controle.
Segurança resultante
| Aspecto | Situação |
|---|---|
| JSON em disco | ❌ Removido com gshred |
| JSON em repouso | ✅ Encriptado no pass (GPG + YubiKey) |
| JSON em uso | ⚠️ Arquivo temporário em /tmp (curta duração, limpado via trap) |
| Acesso requer | Touch no YubiKey (via gpg-agent) |
| Compatibilidade | ✅ Funciona com qualquer app que leia GOOGLE_APPLICATION_CREDENTIALS |
O JSON existe em texto claro apenas durante a execução, como arquivo /tmp/gcp-creds-XXXXX.json deletado imediatamente pelo trap EXIT.