`runner ckeys`

Comandos para gerenciar content keys (ckeys) — passphrases usadas para encriptar .env + .secrets num blob .runner/secrets.enc por app, transportável entre servidores.

A ckey de cada app é guardada encriptada com a master key (mkey) em:

  • /opt/runner/state/{app}.yml — campo ckey: (apps com ckey legacy desde v2.12)
  • /opt/runner/.keys/ckeys/{id}.json — ckeys standalone (compartilháveis entre apps)

Subcomandos

Comando Função
runner ckeys list Lista todas as ckeys (por-app + shared)
runner ckeys add Cria uma ckey standalone para um projeto
runner ckeys export <id-or-app> Exporta o blob sealed (re-importável em servidor com a mesma mkey)
runner ckeys import-sealed Importa um blob sealed
runner ckeys reveal <id-or-app> Revela a ckey plaintext (gated por --insecure, v2.22.7+)
runner ckeys delete <id> Remove uma ckey standalone do vault (v2.23.0+)

`runner ckeys list`

Lista todas as ckeys do servidor.

runner ckeys list
runner ckeys list --json

Output (human):

Ckeys (2):
------------------------------------------------------------------------------------------
  ck_0177…6afd | middleware-241       | aes-256-gcm | app-state | secrets:8 | ck_0177…6afd
  ck_a3b2…7e91 | sweepapex-front      | aes-256-gcm | shared    | secrets:5 | ck_a3b2…7e91
      shared_with: sweepapex-backend, sweepapex-useradmin

Nota: o id ck_xxxx…xxxx contém o caractere unicode (U+2026). Para usar em outros comandos, copie-cole — não digite manualmente. Você também pode passar apenas o nome do app desde v2.22.7.


`runner ckeys add`

Cria uma ckey standalone para um projeto. Útil para compartilhar a mesma ckey entre múltiplos apps.

runner ckeys add meu-projeto
runner ckeys add meu-projeto --algorithm aes-256-gcm --json

A ckey criada fica em /opt/runner/.keys/ckeys/{id}.json, sealed com a mkey do servidor.


`runner ckeys export`

Exporta uma ckey como blob sealed (JSON encriptado com a mkey atual). Importável em outro servidor que tenha a mesma mkey.

# Por id
runner ckeys export ck_0177…6afd

# Por nome do app (v2.22.7+)
runner ckeys export middleware-241

# JSON com metadata
runner ckeys export middleware-241 --json

Output (raw): o JSON sealed (uma linha base64 ou bloco JSON).

Use case: migrar um app para outro servidor sem precisar regerar a ckey. Apenas se a mkey estiver sincronizada entre os servidores (via runner mkey export no original + runner mkey import no destino).


`runner ckeys import-sealed`

Importa um blob sealed (de ckeys export) num servidor que tenha a mesma mkey.

runner ckeys import-sealed --blob "$(cat ckey.sealed.json)"
runner ckeys import-sealed --blob /path/to/ckey.sealed.json --project meu-app

A flag --project permite renomear durante o import.


`runner ckeys reveal` (v2.22.7+)

Revela a ckey plaintext de um app ou ckey id. Gated por --insecure para evitar leak acidental — o plaintext vai pra stdout.

# Pelo nome do app (recomendado)
runner ckeys reveal middleware-241 --insecure

# Por id
runner ckeys reveal ck_0177…6afd --insecure

# JSON
runner ckeys reveal middleware-241 --insecure --json

Output (sem --json):

WARNING: plaintext ckey printed below. Store in password manager and clear terminal scrollback.
minha-chave-secreta-do-projeto

Output (--json):

{
  "ckey_id": "middleware-241",
  "plaintext": "minha-chave-secreta-do-projeto",
  "warning": "Store this value in a password manager. Anyone with this ckey can decrypt the app's secrets."
}

Quando usar

  • Recovery: você precisa re-registrar um app num servidor novo (runner add --ckey "...") mas só tem o servidor velho com a ckey encriptada
  • Backup manual: copiar a ckey pra password manager antes de descomissionar um servidor
  • Debug: verificar qual ckey está em uso

O que precisa estar disponível

  • A mkey do servidor (/opt/runner/.keys/master.key) — para decifrar a ckey sealed
  • A ckey sealed no state file (/opt/runner/state/{app}.yml::ckey) ou numa standalone (/opt/runner/.keys/ckeys/{id}.json)

Se a mkey foi perdida

Sem a mkey original, a ckey sealed é irrecuperável. Sua única opção é:

  1. Re-registrar a app gerando uma ckey nova (runner add --ckey)
  2. Recriar .env + .secrets do zero
  3. Re-encriptar e commitar novo .runner/secrets.enc

Por isso o runner mkey export deve sempre fazer parte do procedimento de backup do servidor.


Recuperação completa de uma app

Cenário: servidor antigo srv-old tem middleware-241 com ckey desconhecida. Você quer levar pro srv-new.

# 1. No srv-old: pega a ckey plaintext
ssh srv-old
runner ckeys reveal middleware-241 --insecure
# Copia o valor pro password manager

# 2. No srv-new: registra a app com a mesma ckey
ssh srv-new
runner add --repo seu/repo --branch main \
  --token ghp_xxx \
  --ckey "<valor-copiado-do-passo-1>"

# 3. Runner detecta .runner/secrets.enc no repo e restaura .env/.secrets automaticamente

Alternativa (se a mkey for compartilhada entre os servidores):

# 1. No srv-old: export sealed
ssh srv-old "runner ckeys export middleware-241" > ckey.sealed.json

# 2. No srv-new: import sealed
scp ckey.sealed.json srv-new:/tmp/
ssh srv-new "runner ckeys import-sealed --blob /tmp/ckey.sealed.json"

`runner ckeys delete` (v2.23.0+)

Remove uma ckey standalone do vault (/opt/runner/.keys/ckeys/). Útil quando uma ckey órfã foi criada por engano (ex: runner ckeys add <project> antes de runner add, gerando uma ckey que ficou desconectada de qualquer app).

runner ckeys delete ck_a3b2…7e91
runner ckeys delete ck_a3b27e91 --yes
runner ckeys delete ck_a3b2…7e91 --json
Flag Default Descrição
--force, -y, --yes false Skipa o prompt interativo de confirmação
--json false Output em JSON

Aceita tanto o storage id (ck_<8hex>) quanto o formatted id (ck_xxxx…xxxx). Não toca em per-app state ckeys — para essas, use runner unregister <app> (que remove a app inteira).

{
  "action": "ckeys_delete",
  "ckey_id": "ck_a3b2…7e91",
  "deleted": true,
  "deleted_at": "2026-05-16T..."
}

A partir de v2.23.0, runner add consulta o vault antes de criar uma ckey nova — se já existe uma shared ckey para o projeto, herda silenciosamente. Isso elimina a fonte mais comum de órfãs.


Veja também

By Borlot.com.br on 12/05/2026