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-sa

Confirma que ficou correto:

pass show gcp/nome-do-projeto-sa | head -5

2. Deletar o arquivo em disco

# Use gshred para apagar com segurança
gshred -u ./sua-service-account.json

3. 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.sh

A variável GCP_PASS_KEY pode ser sobrescrita por projeto:

GCP_PASS_KEY=gcp/outro-projeto ./gcp-run.sh python main.py

4. Uso

Antes:

GOOGLE_APPLICATION_CREDENTIALS=./sa.json python main.py

Depois:

./gcp-run.sh python main.py
./gcp-run.sh uvicorn app.main:app --reload

5. 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 direnv o cleanup é menos elegante — prefira o wrapper script para maior controle.


Segurança resultante

AspectoSituaçã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 requerTouch 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.