Pular para o conteúdo

Atestação

A atestação é o material que o control-plane verifica no enrollment para decidir de que tenant este runner é. Ela é escolhida por RUNNER_ATTESTATION_MODE.

Modo Estado Onde usar
bootstrap-token default Desenvolvimento e prova de conceito. É o elo mais fraco: um segredo que alguém precisa mintar e entregar.
aws-sts implementado EC2, EKS, ou um laptop autenticado por aws sso login.
gke-oidc implementado GKE com Workload Identity.
eks-oidc não implementado Em lugar nenhum. No EKS, use aws-sts.
Terminal window
RUNNER_ATTESTATION_MODE=bootstrap-token
RUNNER_BOOTSTRAP_TOKEN=<token mintado por tenant>

O token é mintado por tenant e é ele que crava em qual organização o runner entra. Sem o token o boot falha rápido, com mensagem própria:

RUNNER_ATTESTATION_MODE=bootstrap-token requires RUNNER_BOOTSTRAP_TOKEN

Esse fail-fast existe porque a alternativa é pior: sem ele o runner sobe, tenta enrolar, leva 401 e entra em ciclo de reconexão, um erro que parece de rede e é de credencial.

Terminal window
RUNNER_ATTESTATION_MODE=aws-sts
AWS_REGION=us-east-1

Este é o modo que fecha o problema de cold start numa frota: com identidade AWS não existe token para mintar à mão, então subir a frota deixa de exigir um humano no navegador.

O runner pré-assina uma requisição sts:GetCallerIdentity (o estilo de IAM auth do Vault) e envia as partes (headers assinados, corpo e região), nunca uma URL. O control-plane executa a chamada contra um endpoint STS da própria allowlist e lê o ARN da resposta.

Duas propriedades saem disso:

  • Quem valida a assinatura é a AWS. O control-plane não assina nada e não pode ser induzido a chamar host arbitrário: é anti-SSRF por construção.
  • Nada secreto viaja. A assinatura SigV4 prova posse da credencial sem revelá-la, e o X-Amz-Security-Token que acompanha credencial temporária já é público por construção.

A credencial vem da cadeia default do SDK: variáveis de ambiente, cache de SSO, IRSA no EKS, IMDS na EC2.

RUNNER_ATTESTATION_MODE=aws-sts requires AWS_REGION

A região não é adivinhada de propósito: o control-plane só aceita região da própria allowlist, e um palpite errado viraria um attestation_invalid que se lê como problema de credencial.

Terminal window
RUNNER_ATTESTATION_MODE=gke-oidc
# RUNNER_GKE_TOKEN_PATH=/var/run/secrets/tokens/gke-oidc/token # default

O runner lê o token OIDC projetado da ServiceAccount do Kubernetes e o envia como atestação. Nada secreto entra na imagem: o token é um JWT de vida curta, com audiência fixa, projetado pelo kubelet. O control-plane o verifica contra o JWKS do Google e mapeia a KSA e o projeto para o tenant.

O pod precisa de um volume projected com serviceAccountToken montado exatamente no caminho configurado. Se faltar, o erro diz isso:

RUNNER_ATTESTATION_MODE=gke-oidc: failed to read projected KSA token at
/var/run/secrets/tokens/gke-oidc/token (is the Workload Identity token volume mounted?)

E se o arquivo existir vazio:

RUNNER_ATTESTATION_MODE=gke-oidc: projected token at … is empty

A renovação de certificado usa uma atestação própria, mtls-renewal, que não é um modo configurável. Veja Enrollment e mTLS.