--- 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: ``. - 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 :: `. - 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.