# Capability: browser-profiles Catálogo operativo de los perfiles del navegador Chromium para investigaciones multicuenta OSINT. Por cada perfil de Chromium (un `--profile-directory` dentro de un user-data-dir) guarda **qué correo/cuentas usar, propósito, persona e identidad de la investigación** y la nota del vault que lo documenta, y permite **lanzar el perfil** listo para trabajar mostrando sus cuentas. La fuente de verdad vive en el service `osint_db` (FastAPI + DuckDB, `http://127.0.0.1:8771`), en las tablas `browser_profiles` + `browser_profile_accounts` (schema main, pobladas solo por API, como `network_scans`). Estas funciones son clientes HTTP finos a ese service. **Regla de seguridad dura:** una cuenta guarda `secret_ref` — una **referencia** al secreto (ej. `pass show osint/p1/gmail`), NUNCA la contraseña en claro. Ni el service ni estas funciones almacenan o resuelven credenciales: `browser_profile_open` solo expone el `secret_ref` para que el operador (o otra herramienta) lo resuelva con `pass`/keepass. Comparte el ecosistema del project `osint` (vault Obsidian + service `osint_db`) con los grupos `recon`, `osint-passive` y `dav`. El perfil real de Chromium vive en `~/.config/chromium-cdp` (user-data-dir con CDP 9222 inyectado por el wrapper `/usr/bin/chromium`); el catálogo NO toca el perfil en disco, solo su metadata. ## Funciones | ID | Firma | Qué hace | |---|---|---| | `browser_profile_register_py_browser` | `browser_profile_register(profile_dir, label="", persona="", purpose="", note_path="", tags=None, notes="", user_data_dir="", status="active", accounts=None, base_url=...) -> dict` | Registra/actualiza un perfil y, opcionalmente, sus cuentas en una sola llamada (1 POST del perfil + 1 POST por cuenta). Idempotente (upsert por `profile_dir` y por `id` de cuenta). `accounts` es una lista de dicts `{service, identity, secret_ref?, role?, status?, notes?}`. | | `browser_profile_list_py_browser` | `browser_profile_list(status=None, base_url=...) -> dict` | Lista los perfiles del catálogo con su nº de cuentas (`n_accounts`). Filtro opcional por `status` (active/archived). Devuelve `{"status":"ok","profiles":[...]}`. | | `browser_profile_show_py_browser` | `browser_profile_show(profile_dir, base_url=...) -> dict` | Muestra un perfil con todas sus cuentas. Devuelve `{"status":"ok","profile":{...},"accounts":[...]}` o error si no existe. Las cuentas traen `secret_ref` (referencia), nunca el password. | | `browser_profile_open_py_browser` | `browser_profile_open(profile_dir, url=None, base_url=..., dry_run=False) -> dict` | Lanza Chromium en el perfil (`--profile-directory`) vía `systemd-run --user --scope` (evita exit-144) y devuelve sus cuentas/`secret_ref` para saber qué usar. `dry_run=True` devuelve el comando sin abrir nada. Compone `browser_profile_show` para leer la metadata. | ## Ejemplo canónico (end-to-end) ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from browser.browser_profile_register import browser_profile_register from browser.browser_profile_list import browser_profile_list from browser.browser_profile_show import browser_profile_show from browser.browser_profile_open import browser_profile_open # 1. Registrar un perfil con sus cuentas (secret_ref = referencia a pass, NO el password) browser_profile_register( "osint_01", label="osint_01", persona="sock-puppet Marta R.", purpose="infiltración foros nicho X", tags=["osint", "sockpuppet"], accounts=[ {"service": "gmail", "identity": "marta.r.osint@gmail.com", "secret_ref": "pass show osint/osint_01/gmail", "role": "primary"}, {"service": "twitter", "identity": "@marta_r_osint", "secret_ref": "pass show osint/osint_01/x", "role": "burner"}, ], ) # 2. Listar el catálogo browser_profile_list() # {"status":"ok","profiles":[{profile_dir, label, n_accounts, ...}]} # 3. Ver un perfil con sus cuentas browser_profile_show("osint_01") # {"profile": {...}, "accounts": [{service, identity, secret_ref, role}]} # 4. Abrir el perfil listo para trabajar (lanza Chromium + dice qué cuentas usar) browser_profile_open("osint_01", url="https://twitter.com") # -> systemd-run --user --scope -- chromium --profile-directory=osint_01 https://twitter.com # -> accounts: [(gmail, pass show osint/osint_01/gmail), (twitter, pass show osint/osint_01/x)] ``` Vía `fn run` (un id conocido a la vez): ```bash ./fn run browser_profile_list ./fn run browser_profile_show osint_01 ./fn run browser_profile_open osint_01 https://twitter.com ``` ## Fronteras (qué NO cubre) - **No gestiona el perfil de Chromium en disco** (crear/clonar/extensiones/avatar): eso es `create_chrome_profile_bash_browser`, `list_chrome_profiles_go_browser`, `set_chrome_profile_appearance_bash_browser`. Este grupo solo guarda metadata operativa y lanza un perfil existente. - **No almacena ni resuelve contraseñas.** Solo referencias (`secret_ref`). El password se resuelve aparte con `pass`/keepass. - **No automatiza el login** ni rellena formularios: para eso usa el `browser_mcp` o el grupo `flow-replay` una vez el perfil está abierto. - **Requiere el service `osint_db` vivo** en `:8771`. Si está caído, las funciones devuelven `{"status":"error", ...}` sin lanzar. ## Gotchas - El `profile_dir` es el nombre del directorio REAL del perfil de Chromium (lo que va en `--profile-directory`): `"Default"`, `"Profile 1"`, `"osint_01"`. NO es el nombre legible (ese es `label`). Verlos con `list_chrome_profiles_go_browser` o el `Local State` del user-data-dir. - `browser_profile_open` por defecto NO pasa `--user-data-dir` (el perfil vive en `~/.config/chromium-cdp`, que el wrapper `/usr/bin/chromium` ya inyecta). Si el perfil está en otro user-data-dir, regístralo con `user_data_dir=` y la función lo pasará explícito. - Se lanza vía `systemd-run --user --scope` a propósito: lanzar Chromium directo desde un proceso hijo da exit-144 en este entorno. - `secret_ref` NUNCA es el password. Si te ves tentado a meter la contraseña ahí, para: guárdala en `pass`/keepass y referencia el comando.