
Detecta e corrige automaticamente segredos codificados em repositórios Python — recusa quando a correção pode quebrar seu código
Autonoma detecta segredos codificados e os substitui por referências os.environ[...] usando reescritas de AST. As alterações são aplicadas apenas quando a reescrita é determinística e preserva a semântica.
As reescritas usam a árvore sintática analisada — não regex em texto bruto.
Executa localmente sem chamadas de rede. Funciona em CI com diffs idempotentes e mínimos.

Segredos codificados em bases de código:
A maioria das ferramentas os detecta.
Autonoma só mexe no que consegue provar que é seguro alterar.
autonoma scan .
autonoma fix .
git diff
pip install autonoma-cli
Adicione isto ao seu .pre-commit-config.yaml para impedir que segredos entrem no histórico:
- repo: local
hooks:
- id: autonoma
name: Autonoma Scan
entry: autonoma scan
language: system
types: [python]
# 1. Crie um arquivo de teste com segredos codificados
cat > test_secrets.py << 'EOF'
SENDGRID_API_KEY = "sg-live-abc123xyz789"
DB_PASSWORD = "Pr0dAccess2024!"
EOF
# Crie também o arquivo de contrato de ambiente (necessário para remediação segura)
printf 'SENDGRID_API_KEY=\nDB_PASSWORD=\n' > .env.example
# 2. Escaneie — emite resultados JSON para stdout
autonoma scan test_secrets.py
# 3. Corrija — reescreve o arquivo no lugar
autonoma fix test_secrets.py
# 4. Escaneie novamente — agora deve estar limpo (código de saída 0)
autonoma scan test_secrets.py
# 5. Inspecione o resultado
cat test_secrets.py
Saída esperada após a correção:
import os
SENDGRID_API_KEY = os.environ["SENDGRID_API_KEY"]
DB_PASSWORD = os.environ["DB_PASSWORD"]
Modo de detecção. Envia JSON para stdout e um resumo legível para stderr. Não mutante — nunca modifica arquivos.
# Escaneie um diretório (resultados JSON para stdout)
autonoma scan src/
# Salve resultados JSON em um arquivo
autonoma scan src/ > findings.json
Códigos de saída para scan:
| Código | Significado |
|---|---|
0 | Nenhuma ocorrência |
1 | Ocorrências detectadas |
3 | Erro da ferramenta |
Remedia segredos codificados usando reescritas de AST. Modifica arquivos no lugar.
# Aplique correções
autonoma fix src/
# Visualize as alterações antes de escrever
autonoma fix src/ --diff
# Escreva um registro de auditoria da remediação
autonoma fix src/ --report-out audit.json
Códigos de saída para fix:
| Código | Significado |
|---|---|
0 | Nenhuma ocorrência — repositório já estava limpo |
1 | Ocorrências existiam antes da remediação (a remediação pode ter sido bem-sucedida — verifique a saída para contagens de CORRIGIDO/RECUSADO) |
3 | Erro da ferramenta |
O comando
fixsai com código1sempre que encontra segredos antes de tentar a remediação, independentemente de a reescrita ter sido bem-sucedida. Isso é intencional: pipelines de CI devem sinalizar o commit onde os segredos foram introduzidos, mesmo após a correção automática. Executeautonoma scandepois para confirmar que o repositório está limpo.
Escaneia o histórico do git em busca de segredos que foram commitados e depois removidos ou alterados.
[!NOTE] Apenas detecção. Este comando não reescreve o histórico do git nem modifica commits.
autonoma history-scan .
Estes são os padrões que a Autonoma corrige atualmente.
# settings.py
SENDGRID_API_KEY = "sg-live-abc123xyz789"
DB_PASSWORD = "Pr0dAccess2024!"
autonoma fix .)# settings.py
import os
SENDGRID_API_KEY = os.environ["SENDGRID_API_KEY"]
DB_PASSWORD = os.environ["DB_PASSWORD"]
# f-string — recusado porque a reescrita mudaria a semântica
api_key = f"prefix_{BASE_KEY}"
# → RECUSADO: refuse_fstring_mixed_expression
# Valor aninhado em dicionário — recusado porque o alvo não é uma atribuição simples
DATABASES = {
"default": {"PASSWORD": "Pr0d@ccess2024!"}
}
# → RECUSADO: tipo de alvo de atribuição não suportado
Ocorrências recusadas são relatadas na saída JSON e causam um código de saída diferente de zero no CI. Arquivos com ocorrências recusadas nunca são modificados.
| Padrão | Exemplo | Comportamento | Porquê |
|---|---|---|---|
| Atribuição simples | api_key = "sk-abc123" | Corrigido | Reescrita determinística de AST |
| Atributo de classe | class C: SECRET = "abc" | Corrigido | Reescrita determinística de AST |
| Argumento nomeado | connect(password="abc") | Corrigido | Reescrita determinística de AST |
| f-string | key = f"prefix_{v}" | Recusado | A reescrita alteraria o comportamento em tempo de execução |
| Concatenação | key = "sk-" + suffix | Recusado | A reescrita alteraria o comportamento em tempo de execução |
| Valor aninhado em dicionário | cfg = {"pass": "abc"} | Recusado | Não é um alvo de atribuição simples |
| Atribuição múltipla | A = B = "secret" | Recusado | Alvo ambíguo |
| Já seguro | key = os.getenv("KEY") | Ignorado | Nenhuma alteração necessária |
.env.example ausente | qualquer padrão | Recusado | Nenhum contrato de ambiente para derivar o nome da variável |
Reexecutar em um arquivo limpo não faz alterações. As reescritas mantêm a indentação original e os comentários. import os é adicionado apenas se estiver ausente.
Para falhar a build se qualquer segredo for detectado:
- name: Scan for secrets
run: autonoma scan .
analyze é mantido para compatibilidade retroativa. Migre para scan ou fix.
# Equivalente a 'autonoma scan'
autonoma analyze src/ --detect-only
# Equivalente a 'autonoma fix'
autonoma analyze src/ --auto-fix
API_KEY = "secret"class Config: PASS = "secret"connect(password="secret")A = B = "secret") ou desempacotamento de tuplas..env.example ou contrato de ambiente for encontrado no repositório.Casos recusados são relatados na saída JSON e causarão códigos de saída diferentes de zero no CI. O arquivo nunca é modificado se qualquer problema nele for recusado.
<arquivo>.bak antes da modificação.Atualmente, o SEC002 combina padrões de valor de credenciais com lógica de roteamento condicionada por palavras-chave. Credenciais atribuídas a nomes de variáveis altamente atípicos podem não ser detectadas.
A Autonoma evita intencionalmente detecção de segredos baseada apenas em entropia ampla, a menos que o impacto na precisão possa ser medido contra um corpus rotulado de falsos positivos.
autonoma scan envia um relatório detect-only para stdout:
{
"schema_version": "1.0",
"tool_name": "autonoma",
"tool_version": "0.1.5",
"generated_at": "2026-03-24T12:00:00Z",
"mode": "detect-only",
"summary": {
"files_processed": 3,
"total_findings": 2,
"safe_to_fix": 1,
"refused": 1
},
"findings": [
{
"file": "settings.py",
"line": 4,
"pattern_type": "api_key",
"severity": "high",
"rule_id": "SEC002",
"safe_to_fix": true,
"suggested_env_var": "SENDGRID_API_KEY",
"refusal_reason": null,
"fingerprint": "sha256:abc123..."
}
]
}
MIT License