
Escanea. Redacta. Haz commit limpio.
Encuentra el secreto. Corrígelo. Haz commit limpio.
Los escáneres de secretos son buenos para dar la alarma y no ayudan mucho a apagarla. Te entregan una lista de credenciales filtradas y te dejan la limpieza a ti. Credactor cierra el ciclo: encuentra un secreto codificado y lo reescribe en su lugar, de modo que una filtración pasa de la detección a la corrección en un solo comando.
Mantener las credenciales fuera del código fuente es una práctica de seguridad básica, no opcional. Credactor hace que esa base sea barata de mantener, en tu máquina antes de un commit o en CI antes de un merge. Ejecútalo por sí solo, o junto a los escáneres en los que ya confías.
# Credactor finds this:
db_password = "h8Tq2vKp9mRz4Wd"
# By default it rewrites the secret as a sentinel that fails loudly at runtime:
db_password = "REDACTED_BY_CREDACTOR"
# With --replace-with env, it writes a reference that reads from the environment:
db_password = os.environ["DB_PASSWORD"]
La redacción reescribe archivos en tu árbol de trabajo. Si un secreto ya se ha confirmado en un commit, rota la clave y limpia también el historial (por ejemplo, con
git filter-repo). Reescribir un archivo no sustituye la revocación de una credencial filtrada.
REDACTED_BY_CREDACTOR que falla en tiempo de ejecución de forma predeterminada, o una referencia a variable de entorno consciente del lenguaje (Python, JavaScript/TypeScript, Go, Java/Kotlin, Ruby, PHP y shell) como os.environ["KEY"]. El reemplazo es código válido. Si el archivo aún no incluye la importación correspondiente (por ejemplo import os), añádela..bak automáticas, protecciones de límites de enlaces simbólicos y permisos de archivo, y enmascaramiento completo de secretos en cada salida. Si no se puede escribir una copia de seguridad segura, Credactor omite el archivo en lugar de reescribirlo a ciegas, y un fallo a mitad de escritura deja el original intacto.--ci de solo lectura con códigos de salida precisos, un hook de pre-commit e ingesta de informes de Gitleaks, TruffleHog o Betterleaks. Detecta con el escáner que ya ejecutas, remedia con Credactor.pip install credactor
Requiere Python 3.11+. Sin otras dependencias. Funciona en Linux, macOS y Windows (probado en CI en Linux y Windows).
En macOS y Linux puedes instalarlo con Homebrew en su lugar:
brew install rxb06/tap/credactor
La fórmula se instala en su propio virtualenv e incluye el extra opcional
[encoding], por lo que una instalación con Homebrew también detecta secretos en archivos
no UTF-8. Un simple pip install credactor deja fuera ese extra; añádelo con
pip install 'credactor[encoding]' si quieres la misma cobertura.
Desde el código fuente:
git clone https://github.com/rxb06/credactor.git
cd credactor
pip install -e .
credactor entonces funciona desde cualquier directorio.
Ejecuta
--dry-runprimero y revisa los hallazgos antes de redactar. Los falsos positivos son posibles, y bajo--fix-allun falso positivo se reescribe. Suprime valores conocidos como seguros con# credactor:ignoreo una entrada en.credactorignore.
credactor --dry-run . # scan, change nothing
credactor . # scan, then redact interactively (y/n per finding)
credactor --fix-all . # redact everything after one confirmation
credactor --fix-all --yes . # redact non-interactively (CI / scripts)
credactor --ci . # read-only gate: exit 1 on findings
credactor --replace-with env . # redact to env-var references instead of the sentinel
El hook solo controla el contenido preparado, por lo que un secreto que ya está confirmado no se vuelve a marcar. Usa
credactor --scan-history .para comprobar lo que ya está en el repositorio.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/rxb06/credactor
rev: v2.7.4 # pin to the latest release tag
hooks:
- id: credactor
- uses: rxb06/[email protected]
La acción siempre pasa --ci, por lo que informa y controla pero nunca reescribe el
checkout. Los hallazgos hacen fallar el paso; establece fail-on-findings: false para informar
sin controlar. Un error hace fallar el paso de cualquier manera.
Sube a Code Scanning en lugar de fallar por hallazgos:
- uses: rxb06/[email protected]
with:
format: sarif
upload-sarif: true
fail-on-findings: false
El job necesita permissions: security-events: write para la subida. Consulta la
guía de integración de CI para cada entrada,
incluida la ingesta de informes de Gitleaks, TruffleHog y Betterleaks.
Credactor detecta los tipos de credenciales que se filtran con más frecuencia y asigna a cada una una severidad para que puedas hacer triaje de un vistazo.
| Categoría | Ejemplos | Severidad |
|---|---|---|
| Claves de proveedores cloud | AWS (AKIA…), GCP (AIza…), Stripe (sk_live_…), Slack (xoxb-…) | Crítica |
| Tokens de plataformas | GitHub (ghp_, github_pat_), GitLab (glpat-), npm (npm_), PyPI (pypi-) | Crítica |
| Claves privadas | Bloques PEM (-----BEGIN … PRIVATE KEY-----) | Crítica |
| JWT | Tokens de tres segmentos eyJ… | Alta |
| Cadenas de conexión | URLs con credenciales en línea (scheme://user:pass@host) | Alta |
| Variables de credenciales | password = "…", api_key = "…", secret_key = "…" | Alta/Media/Baja |
| Atributos XML | <add key="Password" value="…" /> | Alta/Media/Baja |
| Cadenas de alta entropía | hex entre comillas (32–64 caracteres) / Base64 (60+ caracteres) | Media/Baja |
Los tokens deterministas de proveedores (los prefijos anteriores) se marcan independientemente de la entropía. Los detectores heurísticos (JWT, cadenas de conexión, hex, Base64) deben superar un umbral de entropía. El hex o Base64 aislado se marca solo cuando está entre comillas. Un valor de alta entropía sin comillas solo se detecta en una variable con nombre de credencial, lo que evita los SHA de git y las sumas de comprobación. Para las reglas completas de detección y severidad, consulta el Manual.
El conjunto de reglas nativo de Credactor es más limitado que el de un escáner dedicado, y algunos formatos de proveedores (por ejemplo, SendGrid, Twilio y webhooks de Slack) no se detectan. Su ventaja es la remediación: combínalo con Gitleaks, TruffleHog o Betterleaks para la detección más amplia, o ejecútalo por sí solo.