Usando 1password-cli para evitar segredos no perfil de seu terminal
Leia em 3 minutos
Uma coisa que sempre me incomodou na configuração de terminal foi adicionar segredos como export GITHUB_TOKEN=<SECRET>
. É ainda mais chato quando você tem mais de um computador e precisa sincronizar segredos entre eles.
Eu finalmente decidi lidar com esse problema e para isso vou testar o 1password-cli, um utilitário de linha de comando que permite interagir com o 1Password.
No contexto deste artigo, vou pular a configuração do 1password-cli e vou assumir que o comando op
está disponível em seu terminal.
$ which op
/Users/fnando/local/bin/op
O primeiro passo é fazer login com o comando op signin
. Quando você terminar, pode listar os seus cofres com o comando op vault ls
.
$ op vault ls
ID NAME
zyxlrxyu53kax7qqrxz554fgbq Private
oblww37jzanxpl4wruzjz43i71 dev
No meu caso vou usar o cofre dev
para armazenar os segredos que uso em desenvolvimento. Você pode criar o item usando a linha de comando ou a interface do 1Password. Eu vou usar o tipo server
para isso:
$ op item create --title main --category server --vault dev
ID: kbfa7n6hcziy6ck7ys63pzta3a
Title: main
Vault: dev (oulww37jzinxpl4wruzjz43i44)
Created: now
Updated: now
Favorite: false
Version: 0
Category: SERVER
Fields:
Admin Console:
Hosting Provider:
Eu recomendo que você abra o 1Password e remova os itens que são adicionados por padrão; infelizmente, eu não achei uma maneira de remover esses itens usando a linha de comando. Aproveite para remover também os campos que foram adicionados por padrão, já que eles não serão usados (senha, usuário e url).
Agora você pode adicionar os segredos usando a o comando op item edit
. Se preferir, você também pode usar a interface do 1Password.
$ op item edit --vault dev main 'dev.SOME_API_KEY[password]=SOME_KEY' 'dev.ANOTHER_API_KEY[password]=SOME_OTHER_KEY'
ID: kbfa7n6hcziy6ck7ys63pzta3a
Title: main
Vault: dev (oulww37jzinxpl4wruzjz43i44)
Created: 40 seconds ago
Updated: now by Nando Vieira
Favorite: false
Version: 2
Category: SERVER
Fields:
dev:
SOME_API_KEY: SOME_KEY
ANOTHER_API_KEY: SOME_OTHER_KEY
Os segredos acima serão adicionados na seção chamada dev
. Aqui tem um screenshot mostrando os segredos no aplicativo do 1Password.
Depois que todos os segredos foram adicionados, podemos pegar esses itens em formato JSON usando o comando op item get
.
$ op item get --vault dev main --format json
{
"id": "kbfa7n6hcziy6ck7ys63pzta3a",
"title": "main",
"version": 3,
"vault": {
"id": "oulww37jzinxpl4wruzjz43i44",
"name": "dev"
},
"category": "SERVER",
"last_edited_by": "XCFD5SQIJNCZZOF2PBC7XED6QE",
"created_at": "2022-12-28T08:44:55Z",
"updated_at": "2022-12-28T00:45:35.033579-08:00",
"sections": [
{
"id": "Section_6r6xfx7vkbniby2fogqg7tvmee",
"label": "dev"
}
],
"fields": [
{
"id": "notesPlain",
"type": "STRING",
"purpose": "NOTES",
"label": "notesPlain",
"reference": "op://dev/main/notesPlain"
},
{
"id": "xzuhdgcumcnz5peyvjckq2z4gi",
"section": {
"id": "Section_6r6xfx7vkbniby2fogqg7tvmee",
"label": "dev"
},
"type": "CONCEALED",
"label": "SOME_API_KEY",
"value": "SOME_KEY",
"reference": "op://dev/main/dev/SOME_API_KEY"
},
{
"id": "4mg4ejw7q3pnsyworyiflofemq",
"section": {
"id": "Section_6r6xfx7vkbniby2fogqg7tvmee",
"label": "dev"
},
"type": "CONCEALED",
"label": "ANOTHER_API_KEY",
"value": "SOME_OTHER_KEY",
"reference": "op://dev/main/dev/ANOTHER_API_KEY"
}
]
}
Note que o 1Password sempre retornará o campo notesPlain
, já que ele é nativo e não pode sequer ser removido.
O próximo passo é usar essa lista e convertê-la em um formato que seu terminal entenda. Eu vou usar o jq para essa tarefa.
$ op item get main --vault dev --format json | jq -r '.fields | map(select(has("value"))) | map("export " + .label + "=\"" + .value + "\"") | join("\n")'
export SOME_API_KEY="SOME_KEY"
export ANOTHER_API_KEY="SOME_OTHER_KEY"
Você pode usar o eval
com a saída acima, ou pode mandar a saída para um arquivo que pode ser carregado pelo seu terminal. Eu vou usar a segunda opção, mas antes vamos fazer uma limpa e criar um script executável. Vou chamar esse script de op-env
.
#!/usr/bin/env bash
set -e
op item get main --vault dev --format json | jq -r '.fields | map(select(has("value"))) | map("export " + .label + "=\"" + .value + "\"") | join("\n")'
Torne esse script executável com o comando chmod +x op-env
. Você poderá ver os exports na tela se rodar o comando op-env
.
$ op-env
export SOME_API_KEY="SOME_KEY"
export ANOTHER_API_KEY="SOME_OTHER_KEY"
Agora basta adicionar as linhas seguintes ao seu perfil de terminal. Se você usa ZSH, pode usar o arquivo ~/.zshrc
. No Bash você pode usar o arquivo ~/.bashrc
.
if [ ! -f ~/.op-env ]; then
op run -- true
op-env > ~/.op-env
chmod 600 ~/.op-env
fi
source ~/.op-env
O código acima irá criar um arquivo chamado ~/.op-env
a menos que um já exista, permitindo que os segredos fiquem em cache até que este arquivo seja removido ou que você faça a atualização com o comando op-env > ~/.op-env
. Essa etapa é necessária porque o 1Password pede autorização primeira chamada do comando op
em uma seção de terminal, ou seja, se você abrir uma nova aba, terá que reautorizar o acesso do comando op
. Ao fazer cache dos resultados, você precisar fazer isso apenas de vez em quando.
Finalizando
É isso! O 1password-cli permite remover todos os segredos do seu perfil de terminal, sem falar que faz o compartilhamento de segredos uma tarefa muito mais fácil.
E por falar em 1password-cli, aproveite para dar uma olhada no suporte de arquivos .env
, que permite o compartilhamento de segredos entre as pessoas do seu time.
Como você lida com este problema? Você usa alguma outra técnica para isso? Compartilhe sua solução nos comentários abaixo.