Files
fn_registry/dev/issues/0060-fn-doctor-secrets-subcommand.md

96 lines
3.9 KiB
Markdown

---
id: "0060"
title: "`fn doctor secrets`: scan de secrets en TODOS los repos"
status: pendiente
type: feature
domain: []
scope: multi-app
priority: media
depends: []
blocks: []
related: []
created: 2026-05-17
updated: 2026-05-17
tags: []
---
# 0060 — `fn doctor secrets`: scan de secrets en TODOS los repos
## APP Metadata
| Campo | Valor |
|-------|-------|
| **ID** | 0060 |
| **Estado** | pendiente |
| **Prioridad** | media |
| **Tipo** | feature — `cmd/fn/doctor.go` + funcion del registry |
## Dependencias
- `scan_secrets_in_dirty_bash_cybersecurity` ya existe (escanea solo dirty trees por nombres sospechosos).
- `discover_git_repos_bash_infra` ya existe.
- Pre-commit hook v2 invoca `scan_secrets_in_dirty` por repo.
## Contexto
Hoy el escaneo de secrets ocurre solo:
1. En el pre-commit hook (de cada repo, sobre dirty tree antes del commit).
2. Cuando el usuario invoca manualmente `scan_secrets_in_dirty.sh`.
NO hay un audit global "scan TODOS los repos en una pasada" para detectar secrets que ya esten commiteados (caso peor) o staged en repos que no se commitearon hoy. Riesgo: una key olvidada en un repo viejo puede estar pushed a Gitea desde hace meses sin que nadie lo sepa.
## Objetivo
Anadir subcomando `fn doctor secrets` que:
1. Itera TODOS los repos descubiertos por `discover_git_repos`.
2. Por cada uno, escanea TODO el HEAD (no solo dirty) buscando:
- Nombres sospechosos (`*.env`, `*credentials*`, `*.key`, `*.pem`, `id_rsa*`, `*secret*`, `*token*.txt`).
- Patterns en contenido: AWS keys (`AKIA...`), JWT tokens, GitHub tokens (`ghp_...`), Google API keys (`AIza...`).
3. Reporta hallazgos como en otros `fn doctor` (texto humano + `--json`).
4. Exit 0 si limpio, 1 si encuentra algo.
## Arquitectura
### Archivos afectados
- NUEVA funcion `scan_secrets_repo_bash_cybersecurity` (`bash/functions/cybersecurity/scan_secrets_repo.sh` + `.md`) — version "todo el repo" del existente.
- NUEVA funcion `scan_secrets_all_repos_go_cybersecurity` (`functions/cybersecurity/scan_secrets_all_repos.go`) — orquestador Go que itera repos y compone resultado.
- `cmd/fn/doctor.go` — anadir subcomando `secrets` que invoca la funcion Go.
- `.claude/rules/fn_doctor.md` — anadir entrada para `secrets`.
## Tareas
### Fase 1 — funcion bash de scan completo
1.1 Crear `scan_secrets_repo_bash_cybersecurity`:
- Args: `<repo_dir>`.
- Lista todos los archivos tracked por git (`git ls-files`).
- Para cada uno, aplica los filtros de nombre y luego `grep -E` patterns en contenido.
- Output: lineas `SECRET <type> <repo>:<file>:<line> <pattern_match>`.
- Exit 0 si limpio, 1 si hay matches.
### Fase 2 — orquestador Go
2.1 `ScanSecretsAllRepos(registryRoot string) ([]SecretFinding, error)`.
2.2 Llama internamente `discover_git_repos` (via shell-out o portar a Go).
2.3 Por cada repo, ejecuta `scan_secrets_repo.sh` y agrega findings.
2.4 Test con repo temporal con archivo dummy `.env`.
### Fase 3 — CLI + docs
3.1 Anadir case `secrets` a `cmd/fn/doctor.go`.
3.2 Texto humano: tabla `REPO | FILE | TYPE | MATCH`.
3.3 `--json`: array de findings.
3.4 Anadir a `fn doctor` (todos los checks).
3.5 Actualizar `.claude/rules/fn_doctor.md` y CHANGELOG.
## Riesgos
- False positives en repos con muchos archivos. Mitigacion: aplicar filtros estrictos, opcion `--ignore-file` con regex.
- Lentitud: escanear todos los `git ls-files` de 32 sub-repos puede tardar segundos. Mitigacion: paralelizar por repo (goroutines).
- Si encuentra secret real, exponerlo en stdout es contradictorio. Mitigacion: redactar el match (`AKIA****REDACTED****`) en output.
## Decisiones de diseno
- Mantener la deteccion bash (scan_secrets_repo) — es lo que usan los hooks. El orquestador Go solo agrega.
- Patterns hardcodeados al principio. Despues mover a archivo de config si crecen.
- NO integrar gitleaks/trufflehog — aumenta deps externas. Los patterns basicos cubren 95% de casos.