
Rileva e corregge automaticamente segreti hardcoded in repository Python — rifiuta quando la correzione potrebbe rompere il tuo codice
Autonoma rileva segreti hardcoded e li sostituisce con riferimenti a os.environ[...] utilizzando riscritture AST. Le modifiche vengono applicate solo quando la riscrittura è deterministica e preserva la semantica.
Le riscritture utilizzano l'albero sintattico analizzato — non espressioni regolari su testo grezzo. Viene eseguito localmente senza chiamate di rete. Funziona in CI con differenziali idempotenti e minimi.

Segreti hardcoded nei codebase:
La maggior parte degli strumenti li rileva. Autonoma tocca solo ciò che può dimostrare essere sicuro da modificare.
autonoma scan .
autonoma fix .
git diff
pip install autonoma-cli
Aggiungi questo al tuo .pre-commit-config.yaml per impedire che i segreti entrino nella tua cronologia:
- repo: local
hooks:
- id: autonoma
name: Autonoma Scan
entry: autonoma scan
language: system
types: [python]
# 1. Create a test file with hardcoded secrets
cat > test_secrets.py << 'EOF'
SENDGRID_API_KEY = "sg-live-abc123xyz789"
DB_PASSWORD = "Pr0dAccess2024!"
EOF
# Also create the env contract file (required for safe remediation)
printf 'SENDGRID_API_KEY=\nDB_PASSWORD=\n' > .env.example
# 2. Scan — emits JSON findings to stdout
autonoma scan test_secrets.py
# 3. Fix — rewrites the file in place
autonoma fix test_secrets.py
# 4. Scan again — should now be clean (exit 0)
autonoma scan test_secrets.py
# 5. Inspect the result
cat test_secrets.py
Risultato atteso dopo la risoluzione:
import os
SENDGRID_API_KEY = os.environ["SENDGRID_API_KEY"]
DB_PASSWORD = os.environ["DB_PASSWORD"]
Modalità di rilevamento. Emette JSON su stdout e un riepilogo leggibile su stderr. Non muta — non modifica mai i file.
# Scan a directory (JSON findings to stdout)
autonoma scan src/
# Save JSON results to a file
autonoma scan src/ > findings.json
Codici di uscita per scan:
| Codice | Significato |
|---|---|
0 | Nessun risultato |
1 | Risultati rilevati |
3 | Errore dello strumento |
Rimedita i segreti hardcoded utilizzando riscritture AST. Muta i file sul posto.
# Apply fixes
autonoma fix src/
# Preview patches before writing
autonoma fix src/ --diff
# Write remediation audit log
autonoma fix src/ --report-out audit.json
Codici di uscita per fix:
| Codice | Significato |
|---|---|
0 | Nessun risultato — il repo era già pulito |
1 | Risultati esistenti prima della remediation (la remediation potrebbe essere riuscita — controlla l'output per i conteggi FIXED/REFUSED) |
3 | Errore dello strumento |
Il comando
fixesce con codice1ogni volta che trova segreti prima di tentare la remediation, indipendentemente dal successo della riscrittura. Questo è intenzionale: le pipeline CI dovrebbero segnalare il commit in cui sono stati introdotti i segreti, anche dopo l'auto-fix. Eseguiautonoma scanin seguito per confermare che il repo sia pulito.
Analizza la cronologia git per segreti che sono stati committati e successivamente rimossi o modificati.
[!NOTE] Solo rilevamento. Questo comando non riscrive la cronologia git né modifica i commit.
autonoma history-scan .
Questi sono i pattern che Autonoma effettivamente risolve oggi.
# 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 — refused because the rewrite would change semantics
api_key = f"prefix_{BASE_KEY}"
# → REFUSED: refuse_fstring_mixed_expression
# Dict/nested value — refused because the target is not a simple assignment
DATABASES = {
"default": {"PASSWORD": "Pr0d@ccess2024!"}
}
# → REFUSED: unsupported assignment target type
I risultati rifiutati vengono segnalati nell'output JSON e causano un codice di uscita diverso da zero in CI. I file con risultati rifiutati non vengono mai modificati.
Eseguendo nuovamente su un file pulito non vengono apportate modifiche. Le riscritture mantengono l'indentazione originale e i commenti. import os viene aggiunto solo se mancante.
Per far fallire il build se vengono rilevati segreti:
- name: Scan for secrets
run: autonoma scan .
analyze è mantenuto per retrocompatibilità. Esegui la migrazione a scan o fix.
# Equivalent to 'autonoma scan'
autonoma analyze src/ --detect-only
# Equivalent to 'autonoma fix'
autonoma analyze src/ --auto-fix
API_KEY = "secret"class Config: PASS = "secret"connect(password="secret")A = B = "secret") o unpacking di tuple..env.example o un contratto ambiente nel repo.I casi rifiutati vengono segnalati nell'output JSON e causeranno codici di uscita diversi da zero in CI. Il file non viene mai modificato se anche un solo problema in esso viene rifiutato.
<file>.bak prima della modifica.SEC002 attualmente combina pattern di valori di credenziali con logica di routing condizionata da parole chiave. Le credenziali assegnate a nomi di variabili altamente atipici potrebbero non essere attualmente rilevate.
Autonoma evita intenzionalmente il rilevamento di segreti basato esclusivamente sull'entropia, a meno che l'impatto sulla precisione non possa essere misurato rispetto a un corpus di falsi positivi etichettato.
autonoma scan emette un report detect-only su 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..."
}
]
}
Licenza MIT
| Pattern | Esempio | Comportamento | Motivo |
|---|
| Assegnazione semplice | api_key = "sk-abc123" | Risolto | Riscrittura AST deterministica |
| Attributo di classe | class C: SECRET = "abc" | Risolto | Riscrittura AST deterministica |
| Argomento keyword | connect(password="abc") | Risolto | Riscrittura AST deterministica |
| f-string | key = f"prefix_{v}" | Rifiutato | La riscrittura cambierebbe il comportamento a runtime |
| Concatenazione | key = "sk-" + suffix | Rifiutato | La riscrittura cambierebbe il comportamento a runtime |
| Valore in dict/nidificato | cfg = {"pass": "abc"} | Rifiutato | Non è un target di assegnazione semplice |
| Assegnazione multipla | A = B = "secret" | Rifiutato | Target ambiguo |
| Già sicuro | key = os.getenv("KEY") | Saltato | Nessuna modifica necessaria |
Manca .env.example | qualsiasi pattern | Rifiutato | Nessun contratto env da cui derivare il nome della variabile |