- JavaScript 51.6%
- Python 39.8%
- PowerShell 7.7%
- CSS 0.8%
- HTML 0.1%
| api-cifrado | ||
| api-servicios | ||
| api-sql | ||
| documentos | ||
| frontend | ||
| libs/core_utils | ||
| scripts | ||
| .gitignore | ||
| README.md | ||
| run.ps1 | ||
| SESION.md | ||
Herramienta
Panel interno de utilidades de seguridad. Hoy incluye el Cifrador seguro (cifrar/descifrar texto con una palabra llave, guardar cadenas para reutilizar, compartir información protegida). Pensado para crecer con más módulos internos.
Índice de módulos
| Módulo | Qué es | Documentación |
|---|---|---|
frontend/ |
UI (React + Vite + pnpm) | frontend/README.md |
api-cifrado/ |
Backend de cifrado (FastAPI) | api-cifrado/README.md |
api-servicios/ |
Catálogo de APIs externas (FastAPI) | api-servicios/README.md |
api-sql/ |
Servidores/cuentas SQL, probar conexión y permisos (FastAPI) | api-sql/README.md |
libs/core_utils/ |
Librería Python compartida (no es un servicio) | libs/core_utils/README.md |
api-excel/ |
Lectura/escritura de Excel | diseñado y construido aparte, no integrado — ver documentos/api-excel.md |
api-archivos/ |
Archivos y carpetas (local/red) | diseñado y construido aparte, no integrado — ver documentos/api-archivos-api-pipeline.md |
api-pipeline/ |
Pasos de archivos + ejecutables | diseñado y construido aparte, no integrado — ver documentos/api-archivos-api-pipeline.md |
Cada módulo tiene su propio README con instalación y detalles específicos — este README solo cubre lo transversal a todo el proyecto.
Arquitectura
Un solo frontend consume varios backends independientes, cada uno en su propio proceso, con sus propias credenciales y su propio dominio de responsabilidad. Esto limita el radio de impacto si uno de los servicios se ve comprometido.
herramienta/
frontend/ → React + Vite + pnpm
api-cifrado/ → FastAPI (puerto 8001) — cifrado, cadenas, login/whitelist
api-servicios/ → FastAPI (puerto 8002) — catálogo de APIs, llave propia con caducidad
api-sql/ → FastAPI (puerto 8003) — servidores/cuentas SQL, llave propia (5 min, fija)
api-excel/ → FastAPI (puerto 8004*) — lectura/escritura de Excel (diseñado, no construido — ver Próximos pasos)
api-archivos/ → FastAPI (puerto 8004**) — archivos/carpetas local+red (diseñado, no construido — ver Próximos pasos)
api-pipeline/ → FastAPI (puerto 8005**) — pasos de archivos + ejecutables, usa core_utils.FileService (diseñado, no construido)
libs/
core_utils/ → librería Python compartida (NO es un servicio, ver abajo)
scripts/
common.ps1 → funciones compartidas por todos los run.ps1
run.ps1 → orquestador raíz, abre cada módulo en su propio run.ps1
* Puerto tentativo del diseño de api-excel (proponía 8003, ya tomado por
api-sql).
** Puertos tentativos del diseño de api-archivos/api-pipeline, elegidos
sin coordinar con el de api-excel — 8004 quedó propuesto para ambos.
Ninguno de los tres se construyó todavía; resolver los tres puertos juntos
al integrarlos, no uno a la vez.
api-servicios está deliberadamente separado de api-cifrado: su función de
"llamada de prueba" hace que el servidor salga a internet a pedido del
usuario (el mecanismo de un ataque SSRF), así que un problema ahí no puede
tocar el cifrado ni las cadenas guardadas. Tampoco comparte el sistema de
login/whitelist — usa su propia llave de menú, con su propia caducidad.
api-sql es el servicio con más riesgo real de todo el proyecto: guarda
credenciales de acceso a bases de datos que pueden ser de producción. Por
eso su llave de menú es obligatoria (no opcional como en api-servicios) y su
desbloqueo dura fijo 5 minutos, sin configuración posible desde la UI. Ver
api-sql/README.md para el detalle completo,
incluida una advertencia importante: la conexión real a SQL Server y la
impersonación de cuenta de dominio no se pudieron probar en el entorno de
desarrollo (sin Windows ni dominio disponibles) — se probó todo lo demás
exhaustivamente, pero esa pieza específica necesita validarse en una máquina
Windows real antes de confiar en ella para algo productivo.
libs/core_utils — código compartido, no datos ni proceso compartido
Cada backend sigue siendo dueño de sus propios datos (su propio data/, su
propio .env, su propio proceso) — eso no cambió. Lo que sí se comparte
es la lógica que se repetía casi idéntica en cada servicio (hash de
secretos, tokens de sesión en memoria, rate limiting, lectura/escritura
atómica de JSON): vive una sola vez en libs/core_utils, y cada servicio la
importa como una librería normal de Python (pip install -e ../libs/core_utils).
Deliberadamente no es una API de red centralizada — eso reintroduciría
justo el problema que la separación por dominio busca evitar (un punto único
de falla del que todo dependería). Ver libs/core_utils/README.md
para el detalle, incluida la política de versionado semver: cada servicio
declara la versión mínima que espera y se niega a arrancar si hay un cambio
de versión MAYOR incompatible.
Cada servicio expone su propia URL configurable en Configuración dentro del
frontend, que hace GET /health cada 15s por servicio (polling, no detección
al primer error) para saber si debe bloquear los menús que dependen de él.
Configuración queda siempre accesible, incluso sin conexión.
Cómo correr todo (Windows)
Desde la raíz del proyecto:
.\run.ps1
Abre un menú que delega a cada módulo, lanzando su run.ps1 en una pestaña
nueva de Windows Terminal (o una ventana normal de PowerShell si wt no está
instalado). Así puedes tener el frontend y la API corriendo en paralelo sin que
el menú principal quede bloqueado.
1. Frontend (cifrador)
2. API Cifrado
3. API Servicios
4. API SQL
5. Core (utils) - mantenimiento
6. Salir
Cada módulo tiene además su propio run.ps1 independiente — puedes entrar
directo a frontend/ o api-cifrado/ y correrlo ahí sin pasar por el
orquestador. Todos comparten las funciones de scripts/common.ps1 (logging y
validación de las opciones del menú), así que el comportamiento es consistente
entre módulos.
Si PowerShell bloquea cualquier script por no estar firmado digitalmente, corre esto una vez como administrador:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
O, sin permisos de administrador, salta la restricción solo para esa ejecución:
powershell -ExecutionPolicy Bypass -File .\run.ps1
Autenticación
Dos secretos con propósitos y nombres distintos — no confundirlos:
| Nombre | Para qué |
|---|---|
| Palabra llave | Cifra/descifra un texto puntual (/encrypt, /decrypt), incluido el export/import de configuración |
| Palabra de acceso | Entrar a la herramienta (whitelist, /login) |
No hay un tercer secreto tipo "admin token": administrar la whitelist requiere
sesión + que la cuenta tenga es_admin=true (un atributo de la cuenta, no un
secreto aparte). El acceso creado en el setup inicial queda marcado admin
automáticamente, y desde ahí puede promover a otros.
Además, api-servicios y api-sql tienen cada uno su propia llave de
menú (no la "palabra de acceso" de arriba, un mecanismo aparte, propio de
cada servicio) — con caducidad configurable en api-servicios y fija en 5
minutos en api-sql, dado lo sensible de lo que protege ahí.
Ninguna de las dos vive compilada en el frontend — un frontend siempre es
100% legible (código fuente visible en el navegador), así que cualquier
secreto ahí es inútil. Ambas se piden en el momento y se validan en el
backend. Detalle completo en
api-cifrado/README.md.
Principios de seguridad (transversales a todos los módulos)
- La palabra llave nunca se guarda ni se loguea, en ningún servicio.
- Salt y nonce aleatorios en cada operación de cifrado — nunca reutilizados.
- El tag de autenticación de GCM es lo que detecta una palabra llave incorrecta; no hay "descifrado parcial" silencioso.
- Al fallar el descifrado, el error es genérico ("palabra llave incorrecta o dato corrupto"), sin dar pistas de cuál de las dos cosas ocurrió.
- Credenciales de cada backend (cifrado, SQL, etc.) viven separadas entre sí — comprometer una no debe arrastrar a las demás.
- Las palabras de acceso se hashean (Argon2id) — nunca se guardan en texto plano, ni siquiera cifradas de forma reversible.
- Los tokens de sesión viven solo en memoria del navegador, nunca en
localStorageni en el código fuente.
Diseños pendientes de integrar
Hay módulos con diseño ya acordado y una implementación de referencia
construida aparte (fuera de este repo, entregada como .zip) — no
están integrados todavía. El detalle completo de cada uno vive en
documentos/, para no inflar este README cada
vez que se suma un diseño nuevo.
| Documento | Qué es |
|---|---|
documentos/api-excel.md |
Lectura/escritura de Excel, dumps cifrados para libros pesados |
documentos/api-archivos-api-pipeline.md |
core_utils.FileService + archivos/carpetas + ejecución de pipelines |
⚠️ Los tres proponen puertos que se pisan entre sí (api-excel sugiere
8003, ya tomado por api-sql; api-archivos y api-pipeline sugieren 8004
y 8005, y api-excel también propone 8004 como alternativa). Resolver los
tres puertos de una sola vez al integrar, no uno a la vez.
Próximos pasos
- Construir
api-cifrado(FastAPI + endpoints/encrypt,/decrypt,/health) - Script
run.ps1por módulo + orquestador raíz +scripts/common.ps1compartido - Agregar
GET/POST/DELETE /cadenas(SQLite) para reemplazar los datos de ejemplo - Autenticación: whitelist con palabra de acceso, sesiones, admin de accesos
- Rate limiting en
/login(mitiga fuerza bruta contra la palabra de acceso) - Logout real (invalida la sesión en el servidor, no solo en el navegador)
api-servicios: catálogo de APIs, llave de menú propia con caducidad, export OpenAPI, guardia anti-SSRFlibs/core_utils: librería compartida (hash, tokens, rate limit, JSON) con chequeo de versión semver- Vista principal tipo tarjetas (Inicio), Configuración fuera de las tarjetas
- Marcadores: categorías + links, sin llave de menú (no hay riesgo real que proteger)
api-sql: catálogo de servidores/cuentas, cifrado de contraseñas, llave obligatoria (5 min fijos), introspección de permisos — conexión real y modo dominio sin probar en el entorno de desarrollo, validar en Windows- Vista de Servidores y cuentas en el frontend (probar conexión + permisos)
core_utils.tags(0.3.0): etiquetas en Cadenas, catálogo de APIs y Servidores — con edición, mantenedor (renombrar/eliminar en cascada), y filtro por etiqueta en el frontend- Edición completa de Cadenas (antes solo crear/eliminar)
- Comandos: snippets de PowerShell/CMD con etiquetas, en
api-servicios, sin llave de menú (mismo criterio que Marcadores) - Advertencia visual (🔴) antes de probar conexión contra un servidor etiquetado como "producción"
- Rate limiting en
/decrypt(mitiga fuerza bruta contra la palabra llave, ya autenticado) — poracceso_id, 10 intentos / 10 min (envDECRYPT_MAX_ATTEMPTS/DECRYPT_WINDOW_MINUTES) - Fix CORS:
PATCHfaltaba enallow_methodsdeapi-serviciosyapi-sql— edición y rename de etiquetas estaban rotos desde el browser - Fix Swagger
api-sql:/docsy/openapi.jsonestaban públicos sin auth — ahora desactivados por defecto, toggle requiere desbloqueo (igual que los otros servicios). Agregadocs_state.pyyDocsStatusschema - Refactor
core_utils→ 0.4.0: nueva claseLlaveMenu[M](unifica lógica compartida dellave_utils.pyen api-servicios y api-sql), nueva claseDocsState(unificadocs_state.pyen los 3 servicios). Tests escritos pero SIN EJECUTAR — sin Python en el equipo de desarrollo. Correr antes de hacer deploy:cd libs/core_utils && pip install -e ".[dev]" && pytest tests/ -v - Integrar
api-excelal repo (diseño y build de referencia ya existen, aparte — verdocumentos/api-excel.md) - Integrar
api-archivos+api-pipelineal repo (diseño y build de referencia ya existen, aparte — verdocumentos/api-archivos-api-pipeline.md). Resolver los tres puertos pendientes junto conapi-excelantes de integrar cualquiera de los tres. - Sección Reportes (placeholder por ahora)