---
name: recon_osint
kind: pipeline
lang: py
domain: pipelines
version: "1.1.0"
purity: impure
signature: "def recon_osint(target: str, scan_type: str = 'whois', save: bool = True, profile: str = 'quick', record_types: list[str] | None = None, count: int = 4, max_hops: int = 30, timeout_s: int | None = None, confirm: bool = False) -> dict"
description: "One-shot que ejecuta un escaneo de red atomico (whois/rdap/dns/ping/traceroute/nmap) y SIEMPRE lo archiva en OSINT. Materializa la politica 'todo escaneo se guarda en osint': convierte el patron de 2 llamadas (scan atomico + sink) en 1 sola."
tags: [recon, osint, pipeline, cybersecurity, osint-passive, sink]
uses_functions:
  - whois_lookup_py_cybersecurity
  - rdap_lookup_py_cybersecurity
  - dns_records_py_cybersecurity
  - ping_host_py_cybersecurity
  - traceroute_host_py_cybersecurity
  - nmap_scan_py_cybersecurity
  - save_scan_to_osint_py_cybersecurity
uses_types: []
returns: []
returns_optional: false
error_type: "error_py_core"
imports: []
params:
  - name: target
    desc: "Dominio, host o IP objetivo del escaneo (ej. google.com, scanme.nmap.org, 8.8.8.8)."
  - name: scan_type
    desc: "Tipo de escaneo a ejecutar. Uno de: whois, rdap, dns, ping, traceroute, nmap. Default 'whois'."
  - name: save
    desc: "Si True (default) archiva el resultado en OSINT via save_scan_to_osint; si False solo ejecuta el escaneo y no toca el vault."
  - name: profile
    desc: "Perfil de nmap (solo aplica a scan_type='nmap'): quick, full-tcp, vuln, etc. Default 'quick'."
  - name: record_types
    desc: "Lista de tipos de registro DNS a consultar (solo scan_type='dns'), ej. ['A','MX','TXT']. None usa los defaults del atomico."
  - name: count
    desc: "Numero de paquetes ICMP a enviar (solo scan_type='ping'). Default 4."
  - name: max_hops
    desc: "Numero maximo de saltos a sondear (solo scan_type='traceroute'). Default 30."
  - name: timeout_s
    desc: "Timeout en segundos. Si se pasa, se propaga al escaneo atomico; None deja que cada atomico use su default. Sube este valor para nmap full-tcp/vuln."
  - name: confirm
    desc: "Confirmacion explicita para el escaneo activo de nmap (solo aplica a scan_type='nmap'); se propaga a nmap_scan(confirm=...). Default False: nmap rechaza targets publicos/desconocidos no autorizados (status error + needs_confirm). Pasar True solo con autorizacion. Se ignora para whois/rdap/dns/ping/traceroute. CLI: flag --confirm (y --allowlist a,b,c que activa confirm si el target esta autorizado)."
output: "dict con status ('ok'|'error'), target, scan_type, scan (dict crudo del atomico) y osint (dict de save_scan_to_osint con note_path/registered/scan_id, o None si save=False). scan_type invalido -> {status:error, stage:validate, valid:[...]}. Escaneo fallido -> {status:error, stage:scan, scan:<dict>} sin intentar guardar. Nunca lanza."
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/pipelines/recon_osint.py"
---

## Ejemplo

```python
from pipelines.recon_osint import recon_osint

# WHOIS de un dominio: ejecuta el lookup y lo archiva en OSINT (1 paso).
r = recon_osint("google.com", "whois")
print(r["status"])                 # "ok"
print(r["osint"]["note_path"])     # ruta de la nota creada en el vault osint
```

```python
from pipelines.recon_osint import recon_osint

# Escaneo nmap rapido de un host autorizado, archivado en OSINT.
r = recon_osint("scanme.nmap.org", "nmap", profile="quick")
print(r["scan"]["open_ports"])     # puertos abiertos detectados
print(r["osint"]["registered"])    # True si el service osint_db lo registro
```

## Cuando usarla

Para lanzar un escaneo de red y archivarlo en OSINT en un solo paso. Usalo en
vez de llamar el atomico (`whois_lookup`, `nmap_scan`, ...) + `save_scan_to_osint`
por separado. Garantiza que el resultado queda en el vault: es la materializacion
de la politica "todo escaneo que lancemos se guarda en osint".

## Gotchas

- Hereda los gotchas de cada escaneo atomico que compone:
  - **nmap**: guard anti-escaneo no autorizado — un target publico/desconocido
    se rechaza (status error + needs_confirm) salvo que pases `confirm=True`
    (o, por CLI, `--confirm` / `--allowlist`). Los privados/local proceden sin
    confirm. Solo escanea objetivos para los que tengas autorizacion legal;
    escaneos sin permiso pueden ser ilegales. Requiere `nmap` instalado.
  - **ping / traceroute**: el ICMP puede estar filtrado por firewalls; un
    `loss_pct` 100% o pocos `hops` no implican que el host este caido, solo que
    no responde a ICMP.
  - **whois / rdap**: dependen de la disponibilidad y rate-limit del servidor
    WHOIS/RDAP del TLD; respuestas truncadas o vacias son posibles.
  - **dns**: resuelve contra el resolver del sistema; resultados varian segun el
    DNS configurado.
- Requiere el service `osint_db` vivo (`http://127.0.0.1:8771`) para el registro
  estructurado; si no responde, `save_scan_to_osint` degrada a guardar solo la
  nota en el vault (sin entrada en DuckDB). El pipeline no falla por eso.
- Para nmap largos (`full-tcp`, `vuln`) pasa `profile` + un `timeout_s` alto y
  considera lanzarlo en background; el default `timeout_s` del atomico nmap es
  amplio (1800s) pero un escaneo completo puede excederlo.
- Si el escaneo atomico falla (`status == "error"`), el pipeline devuelve
  `{"status":"error","stage":"scan",...}` y **no** intenta guardar nada en OSINT.
- Pipeline impuro: hace red (escaneos) y FS/HTTP (vault + service). No es
  determinista entre ejecuciones.

## Notas

Pipeline que compone 7 funciones atomicas del dominio `cybersecurity`. No
reimplementa logica de escaneo ni de persistencia; solo despacha, normaliza un
`summary` por tipo de escaneo y delega el guardado. Nunca lanza excepciones:
todo fallo se refleja en la clave `status` del dict devuelto.

## Capability growth log

- v1.1.0 (2026-06-14) — param `confirm` propagado a `nmap_scan(confirm=...)`
  (solo scan_type='nmap') para el guard anti-escaneo-no-autorizado; CLI gana
  flag `--confirm` y `--allowlist a,b,c` (activa confirm si el target esta
  autorizado). Sin el flag, confirm=False (compatibilidad intacta).
