Credenciais git

v2.137.0+ (#164). Cada app tem a sua credencial do GitHub, guardada cifrada com a mkey no state. O runner a usa para clonar, buscar versões e publicar o bundle de secrets na branch de deploy. Ele só precisa ler e escrever conteúdo no repo da app. Três tipos são aceitos:

Tipo Validade Escopo Como cadastrar
GitHub App (recomendado) token de 1 h gerado a cada uso só o repo da app, contents: write + metadata: read runner tokens set <app> --github-app <ID>
PAT fine-grained a que você escolher (até 1 ano) repos e permissões escolhidos printf %s "$TOKEN" | runner tokens set <app>
Token clássico longa a conta inteira idem, com --allow-broad-token se tiver escopo sensível

Ver o que cada app usa

runner tokens list      # agrupado por token, com o tipo (offline)
runner tokens audit     # tipo, escopo além da medida, validade (consulta o GitHub)
runner tokens test <app>

O audit marca broad quando um token clássico tem escopo que o runner não usa (delete_repo, admin:org, workflow, write:org…), expiring quando um fine-grained vence em 14 dias ou menos, e invalid quando o GitHub recusa.

Token clássico: aceito, sob protesto

Continua funcionando. Com escopo sensível, o cadastro (add, adopt, edit, tokens set) recusa com broad_token: e só segue com --allow-broad-token. Nesse caso imprime o alerta com os escopos que sobram e grava o uso em /opt/runner/logs/insecure-events.jsonl. tokens test repete o alerta a cada teste.

PAT fine-grained

No GitHub: Settings → Developer settings → Fine-grained tokens. Selecione só os repos das apps; permissões Contents: Read and write (Metadata: Read vem junto). Defina uma validade. O runner lê a validade e avisa antes de vencer.

GitHub App

O GitHub não deixa criar App pela API: é pela interface (Settings → Developer settings → GitHub Apps → New).

  1. Crie o App com permissão de repositório Contents: Read and write. Webhook desligado. Gere e baixe a private key (.pem).
  2. Instale o App nos repos das apps (Install App). Pode ser “Only select repositories”.
  3. No servidor do runner:
runner github-app register --app-id <APP_ID> < app.private-key.pem
runner tokens set <app> --github-app <APP_ID>
runner tokens test <app>      # gera um token de verdade e mostra repo, permissões e validade

A chave fica cifrada em /opt/runner/.keys/github-apps/. A cada uso o runner assina um JWT e troca por um installation token restrito ao repo da app e a contents: write. O token vale 1 h e fica em cache cifrado até 5 min antes de vencer.

runner add --token-from <app> de uma app que usa GitHub App reaponta para o repo novo (o App precisa estar instalado nele).

Escolher o App já no registro (2.141.0+)

runner add  --repo acme/loja --branch dist --github-app <APP_ID>
runner adopt loja --from-container loja -r acme/loja -b dist --github-app <APP_ID>
runner edit loja --github-app <APP_ID>     # = tokens set loja --github-app <APP_ID>

No add/adopt a instalação do App no repo é resolvida na hora: chave do App não registrada ou App não instalado no repo → o comando falha antes de clonar. --github-app não combina com --token/--token-from/--token-stdin (nem com --remove-token no edit); no adopt exige --repo.

Restrição por branch

O GitHub não restringe token por branch, nem o de App. Duas camadas cobrem:

  • No runner: credencial de App só faz push na branch de deploy da app (push_branch_negado para qualquer outra).
  • No GitHub: um ruleset no repo que restringe atualizações das branches protegidas, com o App fora da lista de bypass nas branches que ele não deve tocar.
runner github-app list
runner github-app remove --app-id <ID>   # recusa se alguma app ainda usa; --force para forçar
By Borlot.com.br on 01/10/2026