Guia de Operações 1Password — middag-io
Gerenciamento de vaults no dia-a-dia, criação de secrets, setup de Service Account e operações Connect. Decisões de arquitetura: veja ADR-005.
Sumário
- 1. Estrutura de Vaults
- 2. Adicionando um Secret a um Projeto Existente
- 3. Configurando um Novo Projeto
- 4. Gerenciamento de Service Account
- 5. Operações do Connect Server
- 6. Convenções de Nomenclatura
- 7. Troubleshooting
1. Estrutura de Vaults
Vaults atuais e seus propósitos:
| Vault | Propósito | Acessado por |
|---|---|---|
CI-SHARED | GHCR, Cloudflare global, SES SMTP | Todos repos (SA org) + Connect |
CI-AWS | ECR, RDS, Lambda, S3 | Todos repos (SA org) + Connect |
CI-MYPROJECT | Deploy keys my-project, APIs, env vars | SA myproject + Connect |
CI-SATIS | Token GitHub, R2, env vars | SA satis |
PRIVATE | Chaves JWT, certificado A1 | SA myproject + Connect |
CLOUD | Cloudflare legado (migrando para CI-*) | Apenas Connect |
Árvore de Decisão: Qual Vault?
É compartilhado entre projetos?
├── Sim → É AWS?
│ ├── Sim → CI-AWS
│ └── Não → CI-SHARED
└── Não → É chave privada ou certificado?
├── Sim → PRIVATE
└── Não → CI-{PROJECT}2. Adicionando um Secret a um Projeto Existente
Passo 1: Criar o item no 1Password
- Abrir 1Password web → selecionar o vault apropriado
- Criar item seguindo convenção de nomenclatura:
{SERVICE}-{context} - Adicionar campos nas seções apropriadas
Passo 2: Referenciar no código
Em workflow do GitHub Actions:
yaml
- uses: 1password/load-secrets-action@v2
with:
export-env: true
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SA_MYPROJECT }}
MY_SECRET: op://CI-MYPROJECT/item-name/section/fieldEm template .env (servidor):
MY_SECRET="op://CI-MYPROJECT/item-name/section/field"Em auth.json.tpl (Composer):
json
{
"http-basic": {
"privatesatis.middag.com.br": {
"username": "op://CI-MYPROJECT/ENV-myproject/PRIVATE-SATIS/SATIS_USER",
"password": "op://CI-MYPROJECT/ENV-myproject/PRIVATE-SATIS/SATIS_PASSWORD"
}
}
}Passo 3: Verificar acesso
- CI: Executar workflow na branch develop para verificar se o secret carrega
- Servidor:
op inject -f -i .env.production.tpl -o /dev/stdout | grep MY_SECRET
3. Configurando um Novo Projeto
Procedimento completo para adicionar integração 1Password a um novo repo.
3.1 Criar o vault
Nome do vault: CI-{PROJECT} (maiúsculas)
Exemplo: CI-HELICO, CI-TMS3.2 Criar Service Account
- 1Password web → Developer Tools → Service Accounts
- Nome:
sa-github-ci-{project}(minúsculas) - Conceder acesso aos vaults:
CI-{PROJECT}(específico do projeto)CI-SHARED(se precisa de GHCR, Cloudflare, SES)CI-AWS(se precisa de ECR, RDS, S3)PRIVATE(se precisa de chaves JWT, certificados)
3.3 Adicionar secret no GitHub
bash
gh secret set OP_SA_{PROJECT} --repo middag-io/{repo-name}
# Cole o token do SA quando solicitado3.4 Criar itens iniciais
Siga a convenção de nomenclatura da seção 6. Itens mínimos para um projeto WP típico:
| Item | Vault | Propósito |
|---|---|---|
ENV-{project} | CI-{PROJECT} | Vars de ambiente do app (seções por integração) |
SSH-{repo}-deploy-key | CI-{PROJECT} | Chave SSH para deploy no servidor |
AWS-EC2-{repo} | CI-{PROJECT} | Alvo do deploy (host, user, pasta) |
3.5 Conectar no workflow
Use 1password/load-secrets-action@v2 nos workflows GitHub Actions do repo.
4. Gerenciamento de Service Account
Service Accounts Atuais
| Nome do SA | Secret GitHub | Vaults | Escopo |
|---|---|---|---|
sa-github-ci-shared | OP_SERVICE_ACCOUNT_TOKEN (org) | CI-SHARED, CI-AWS | Todos repos |
sa-github-ci-myproject | OP_SA_MYPROJECT (repo) | CI-MYPROJECT, PRIVATE | Repos my-project |
sa-github-ci-satis | OP_SA_SATIS (repo) | CI-SATIS | my-satis-repo |
Quando criar um novo SA
- Novo projeto com seu próprio vault CI-
- Nunca compartilhe tokens SA entre projetos não relacionados
Rotação de token SA
- 1Password web → Developer Tools → Service Accounts → selecionar SA
- Revogar token antigo, gerar novo
- Atualizar secret no GitHub:
gh secret set OP_SA_{PROJECT} --repo middag-io/{repo} - Re-executar CI para verificar
5. Operações do Connect Server
Arquitetura
Host EC2
├── op-connect-api (porta 8080, apenas localhost)
├── op-connect-sync
└── Containers de aplicação
└── op inject -f -i .env.production.tpl -o .envAdicionando um vault ao Connect
- 1Password web → Integrations → Connect servers → selecionar servidor
- Adicionar vault → selecionar CI-
- Nenhum redeploy necessário — Connect captura mudanças de vault automaticamente
Reiniciando o Connect
bash
docker compose -f docker-compose.connect.yml restartHealth check
bash
curl -s http://localhost:8080/health | jq .
# Esperado: {"state":"ACTIVE"}6. Convenções de Nomenclatura
Vaults
| Padrão | Exemplo | Uso |
|---|---|---|
CI-SHARED | -- | Creds compartilhados cross-projeto |
CI-AWS | -- | Creds de serviços AWS |
CI-{PROJECT} | CI-MYPROJECT | Específico do projeto |
PRIVATE | -- | Chaves privadas, certificados |
Itens: {SERVICE}-{context}
| Padrão | Exemplo | Propósito |
|---|---|---|
GITHUB-{org}-{purpose} | GITHUB-middag-io-GHCR | Tokens GitHub |
CLOUDFLARE-{project} | CLOUDFLARE-myproject | CF API/R2/SSL |
AWS-EC2-{repo} | AWS-EC2-docker-wp-myproject | Alvos de deploy |
SSH-{repo}-{purpose} | SSH-docker-wp-myproject-dev-key | Chaves SSH |
ENV-{project} | ENV-myproject | Vars de ambiente |
{SERVICE} | HUBSPOT, STRIPE | APIs externas |
Seções (dentro de itens)
Agrupe campos por assunto. Em inglês, curto:
Credentials— username, password, tokenEC2— host, user, folderS3-Credentials— access key, secret, bucketORIGIN-SSL— certificate, private_keyBASE64— chaves/certs codificados em base64
Campos
snake_casepara novos campos- Nomes existentes em português/com espaços: atualizar na próxima vez que o item for tocado
Ambientes 1Password
Para op run --env em servidores:
{project}-{environment}
Exemplo: myproject-production, myproject-staging7. Troubleshooting
CI (GitHub Actions)
| Problema | Causa | Solução |
|---|---|---|
could not find item | Vault/nome de item errado no op:// | Verificar no 1Password web |
unauthorized | SA não tem acesso ao vault | Verificar permissões do SA |
permission denied | Usando SA da org para vault do projeto | Usar SA específico do projeto |
Connect (Servidor)
| Problema | Causa | Solução |
|---|---|---|
connect: connection refused | Connect não está rodando | docker compose up -d op-connect-api op-connect-sync |
item not found | Vault não adicionado ao Connect | 1Password web → Integrations → adicionar vault |
op inject trava | OP_CONNECT_HOST não definido | Exportar OP_CONNECT_HOST=http://op-connect-api:8080 |