Code: Vault para Tokens com Escopo e Rotação

Como ler esta reflexão: Leia como um problema de Autoridade, não de DevOps. Se o Token é estático e amplo, o agente vira um Superusuário por acidente — e você só descobre no dia do incidente.

Contexto — em Agentic AI, Segredo é Permissão em tempo real

Quando um agente chama Ferramentas, integra APIs e dispara ações, o Token deixa de ser “configuração” e vira Autoridade em runtime. A diferença entre “assistente” e “executor perigoso” costuma ser apenas uma string: um Token com Escopo amplo, longa duração e pouca rastreabilidade.

Vault entra aqui como Plano de Controle de Segredos: reduzir permanência (Tokens curtos), reduzir superfície (Escopo), e tornar a resposta a incidente possível (Revogação). Sem isso, a organização compra velocidade e herda um modo de falha silencioso.

O desafio — Token estático vira Autoridade Implícita

O padrão AS-IS mais comum é simples: um Token longo fica em ENV, CI/CD ou Secret do cluster, e o agente usa para tudo.

Funciona bem na média, porque elimina fricção. Mas cria duas fragilidades caras na cauda: você não sabe “quem usou o quê” com clareza e não consegue “desligar rápido” sem quebrar o sistema inteiro.

O objetivo não é “esconder melhor”. É tornar o acesso governável: Escopo explícito por Ferramenta, Rotação previsível, e Revogação praticável quando algo vaza.

O cenário — vazou um Token e ninguém sabe o blast radius

Um agente de operações usa integrações com CRM, e-mail e pagamentos. O Token está em variável de ambiente do worker. Um log de debug, um crash dump, um backup ou um print de pipeline expõe esse Token. Não precisa ser ataque sofisticado: basta o Token parar no lugar errado.

O time corre para revogar, mas percebe o problema: o Token é compartilhado, longo e usado por vários fluxos. Revogar “resolve o risco”, mas derruba a operação.

Manter “salva o uptime”, mas mantém a porta aberta. A organização fica presa entre Segurança e Continuidade porque o Token não foi desenhado para ser revogável sem crise.

Implicações — do Token estático ao Token de curta duração com Escopo

Abaixo, um exemplo típico (AS-IS): Token estático carregado em ENV. Funciona, mas cria Autoridade Implícita e dificulta Rotação sem interrupção.

# AS-IS: Token estático em ENV (alto risco na cauda)
import os
import requests

API_TOKEN = os.environ["THIRD_PARTY_API_TOKEN"]  # longo, compartilhado, difícil de revogar sem quebrar tudo

def call_tool(payload: dict) -> dict:
  resp = requests.post(
    "https://api.exemplo.com/acao",
    json=payload,
    headers={"Authorization": f"Bearer {API_TOKEN}"},
    timeout=10,
  )
  resp.raise_for_status()
  return resp.json()

Esse padrão falha no ponto mais sensível: ele mistura Identidade, Escopo e Duração em uma única credencial. A correção madura separa as coisas: o workload autentica no Vault com um método próprio (AppRole, Kubernetes Auth, etc.), recebe um Token de curta duração e busca Segredos com Escopo mínimo. Assim, Rotação e Revogação viram capacidades operacionais, não “projetos”.

# TO-BE: Vault como Plano de Controle (Token curto + Escopo + Rotação)
# Requer: hvac (pip install hvac) e VAULT_ADDR + método de auth (ex.: AppRole)
import os
import time
import hvac
import requests

VAULT_ADDR = os.environ["VAULT_ADDR"]
ROLE_ID = os.environ["VAULT_ROLE_ID"]
SECRET_ID = os.environ["VAULT_SECRET_ID"]

client = hvac.Client(url=VAULT_ADDR)

def vault_login() -> None:
  # AppRole dá identidade ao workload; o Token resultante deve ser de curta duração.
  auth = client.auth.approle.login(role_id=ROLE_ID, secret_id=SECRET_ID)
  client.token = auth["auth"]["client_token"]

def get_tool_token() -> str:
  # Segredo com Escopo: idealmente, um token por Ferramenta/Ação/Coorte.
  # Use KV v2: secret/data/tools/crm (exemplo). Evite armazenar PII aqui.
  secret = client.secrets.kv.v2.read_secret_version(path="tools/crm")
  return secret["data"]["data"]["token"]

def call_tool(payload: dict) -> dict:
  if not client.is_authenticated():
    vault_login()

  tool_token = get_tool_token()  # pode ser rotacionado sem redeploy do agente
  resp = requests.post(
    "https://api.exemplo.com/acao",
    json=payload,
    headers={"Authorization": f"Bearer {tool_token}"},
    timeout=10,
  )
  resp.raise_for_status()
  return resp.json()

# Em workers longos, você também pode renovar o Token do Vault (lease) quando aplicável.
def keep_alive(poll_sec: int = 60) -> None:
  while True:
    try:
      if client.is_authenticated():
        client.renew_self_token()
    except Exception:
      vault_login()
    time.sleep(poll_sec)

O impacto operacional é direto: Rotação deixa de ser evento traumático e passa a ser mudança controlada. Escopo reduz blast radius quando algo vaza. Revogação deixa de derrubar o mundo inteiro e passa a atingir um corredor específico. E, quando você precisa explicar um incidente, a conversa muda de “quem tinha a chave” para “qual Identidade acessou qual Segredo, em qual janela”.

Síntese final — Segredo governável é o que separa autonomia de superusuário

Vault não é sobre “guardar string”. É sobre impedir que Tokens virem Autoridade Implícita em produção. Quando o agente opera com Tokens curtos, Escopo mínimo e Rotação previsível, você ganha algo raro: capacidade de conter sem parar o negócio.

O que ainda poderia melhorar — sinais de próxima maturidade

O próximo degrau aparece quando cada Ferramenta crítica tem Tokens por Escopo e por Ambiente, quando Rotação ocorre sem mudança manual no app, quando Revogação é uma ação rápida e segmentada, quando Auditoria consegue reconstruir acesso sem arqueologia, quando existe Modo Seguro para degradar chamadas externas, e quando “Segredo” deixa de ser configuração e vira parte do desenho de governança do fluxo.

Veja também: