Janee API Security
Servidor MCP que se sitúa entre agentes de IA y APIs. Los agentes solicitan acceso, Janee realiza la llamada con las credenciales reales, los agentes nunca ven los secretos.
Documentación
Janee 🔐
Gestión de secretos para agentes de IA mediante MCP
Tus agentes de IA necesitan acceso a APIs para ser útiles. Pero no deberían tener tus claves API en bruto. Janee se sitúa entre tus agentes y tus APIs: inyecta credenciales, aplica políticas y registra todo.
✨ Características
| 🔒 Agentes de conocimiento cero | Los agentes llaman a las APIs sin ver nunca las claves |
| 📋 Registro de auditoría completo | Cada solicitud registrada con marca de tiempo, método, ruta, estado |
| 🛡️ Políticas de solicitud | Reglas de permitir/denegar por capacidad (p. ej., Stripe de solo lectura) |
| ⏱️ TTL de sesión | Acceso limitado en el tiempo con revocación instantánea |
| 🔌 Funciona con cualquier cliente MCP | Claude Desktop, Cursor, OpenClaw y más |
| 🏠 Local primero | Claves cifradas en tu máquina, nunca enviadas a la nube |
| 🖥️ Modo exec | Ejecuta herramientas CLI con credenciales inyectadas: los agentes nunca ven las claves |
| 🤖 Autenticación de GitHub App | Tokens de corta duración para agentes autónomos: sin PAT estáticos |
| 🐦 Twitter/X OAuth 1.0a | Firma OAuth por solicitud: 4 secretos permanecen cifrados |
| ☁️ AWS SigV4 | Firma solicitudes de API de AWS en el servidor: SES, S3 y más |
| 🔧 Autenticación git automática | git push/pull funciona cuando las credenciales incluyen tokens de GitHub |
El Problema
Los agentes de IA necesitan acceso a APIs para ser útiles. El enfoque actual es darles tus claves y esperar que se comporten.
- 🔓 Los agentes tienen acceso completo a Stripe, Gmail, bases de datos
- 📊 Sin registro de auditoría de qué se accedió o por qué
- 🚫 Sin interruptor de apagado cuando algo sale mal
- 💉 A una inyección de prompt de distancia del desastre
La Solución
Janee es un servidor MCP que gestiona secretos de API para agentes de IA:
- Almacena tus claves API — cifradas localmente en
~/.janee/ - Ejecuta
janee serve— inicia el servidor MCP - El agente solicita acceso — mediante la herramienta MCP
execute - Janee inyecta la clave real — el agente nunca la ve
- Todo queda registrado — registro de auditoría completo
Tus claves permanecen en tu máquina. Los agentes nunca las ven. Tú mantienes el control.
Configura una Vez, Úsalo en Todas Partes
Configura tus APIs en Janee una sola vez:
services:
stripe:
baseUrl: https://api.stripe.com
auth: { type: bearer, key: sk_live_xxx }
github:
baseUrl: https://api.github.com
auth: { type: bearer, key: ghp_xxx }
openai:
baseUrl: https://api.openai.com
auth: { type: bearer, key: sk-xxx }
Ahora cada agente que se conecte a Janee puede usarlas:
- Claude Desktop — accede a tus APIs
- Cursor — accede a tus APIs
- OpenClaw — accede a tus APIs
- Cualquier cliente MCP — accede a tus APIs
No más copiar claves entre herramientas. No más "¿qué agente tiene qué API configurada?" ¿Añadir un nuevo agente? Ya tiene acceso a todo. ¿Revocar una clave? Actualízala una vez en Janee.
Una configuración. Cada agente. Registro de auditoría completo.
Inicio Rápido
Instalación
npm install -g @true-and-useful/janee
Inicialización
janee init
Esto crea ~/.janee/config.yaml con servicios de ejemplo.
Añadir Servicios
Opción 1: Interactiva (recomendada para usuarios primerizos)
janee add
Janee te guiará para añadir un servicio:
Service name: stripe
Base URL: https://api.stripe.com
Auth type: bearer
API key: sk_live_xxx
✓ Added service "stripe"
Create a capability for this service? (Y/n): y
Capability name (default: stripe):
TTL (e.g., 1h, 30m): 1h
Auto-approve? (Y/n): y
✓ Added capability "stripe"
Done! Run 'janee serve' to start.
¿Usas un agente de IA? Consulta Configuración no interactiva para ver las banderas que omiten los avisos, o las guías específicas para agentes más abajo.
Opción 2: Editar la configuración directamente
Edita ~/.janee/config.yaml:
services:
stripe:
baseUrl: https://api.stripe.com
auth:
type: bearer
key: sk_live_xxx
capabilities:
stripe:
service: stripe
ttl: 1h
autoApprove: true
Añadir herramientas CLI (modo exec)
Algunas herramientas necesitan credenciales como variables de entorno, no como cabeceras HTTP. El modo exec gestiona esto:
janee add twitter --exec \
--key "tvly-xxx" \
--allow-commands "bird,tweet-cli" \
--env-map "TWITTER_API_KEY={{credential}}"
Ahora los agentes pueden ejecutar herramientas CLI a través de Janee sin ver nunca la clave API:
// Agent calls janee_exec tool
janee_exec({
capability: "twitter",
command: ["bird", "post", "Hello world!"],
cwd: "/home/agent/project", // optional working directory
reason: "User asked to post a tweet"
})
Janee inicia el proceso con TWITTER_API_KEY inyectado, ejecuta el comando y devuelve stdout/stderr. La credencial nunca entra en el contexto del agente.
Banderas clave:
--exec— configurar como modo exec (envoltorio CLI en lugar de proxy HTTP)--allow-commands— lista blanca de ejecutables permitidos (seguridad)--env-map— asignar credenciales a variables de entorno--work-dir— directorio de trabajo para el subproceso--timeout— tiempo máximo de ejecución (predeterminado: 30s)
Operaciones Git (autenticación HTTPS automática)
Cuando se usa el modo exec con credenciales de GitHub, Janee gestiona automáticamente la autenticación de git. No se necesita configuración adicional: git push, git pull y git clone simplemente funcionan:
capabilities:
- name: git-ops
service: github
mode: exec
allowCommands: [git]
env:
GH_TOKEN: "{{credential}}"
// Agent can push code without ever seeing the token
janee_exec({
capability: "git-ops",
command: ["git", "push", "origin", "main"],
cwd: "/workspace/my-repo"
})
Janee detecta comandos git con GH_TOKEN/GITHUB_TOKEN en el entorno y crea un script askpass temporal para la autenticación HTTPS. El script se limpia automáticamente después de que el comando se complete.
Añadir autenticación de GitHub App (para agentes autónomos)
Los tokens estáticos son arriesgados para agentes de larga duración. La autenticación de GitHub App genera tokens de instalación de corta duración bajo demanda: no se requieren PAT de larga duración.
Opción 1: Usar create-gh-app (recomendado)
npx @true-and-useful/create-gh-app create my-agent --owner @me
# Opens browser → creates app → saves credentials locally
# Install the app on your repos
# https://github.com/apps/my-agent/installations/new
# Register with Janee in one command
npx @true-and-useful/create-gh-app janee-add my-agent
Listo. Tu agente ahora recibe tokens de GitHub de corta duración a través del proxy MCP de Janee.
Opción 2: Configuración manual
janee add github-app \
--auth-type github-app \
--app-id 123456 \
--pem-file /path/to/private-key.pem \
--installation-id 789
O mediante configuración:
services:
github:
baseUrl: https://api.github.com
auth:
type: github-app
appId: "123456"
pemFile: /path/to/private-key.pem
installationId: "789"
Cómo funciona: Cuando un agente solicita acceso, Janee firma un JWT con la clave privada de la app, lo intercambia por un token de instalación de 1 hora mediante la API de GitHub y almacena el token en caché hasta su expiración. El agente nunca ve la clave privada: solo el token de corta duración llega a la API.
Iniciar el servidor MCP
janee serve
Usar con tu agente
Los agentes que admiten MCP (Claude Desktop, Cursor, OpenClaw) ahora pueden llamar a la herramienta execute para hacer solicitudes de API a través de Janee:
// Agent calls the execute tool
execute({
capability: "stripe",
method: "GET",
path: "/v1/balance",
reason: "User asked for account balance"
})
Janee descifra la clave, hace la solicitud, registra todo y devuelve la respuesta.
Integraciones
Funciona con cualquier agente que hable MCP:
- OpenClaw — Plugin nativo (
@true-and-useful/janee-openclaw)- ¿Agentes en contenedores? Consulta la Guía de configuración de contenedores
- Cursor — Guía de configuración
- Claude Code — Guía de configuración
- Codex CLI — Guía de configuración
- Cualquier cliente MCP — solo apunta a
janee serve
Integración con OpenClaw
Si usas OpenClaw, instala el plugin para soporte nativo de herramientas:
npm install -g @true-and-useful/janee
janee init
# Edit ~/.janee/config.yaml with your services
# Install the OpenClaw plugin
openclaw plugins install @true-and-useful/janee-openclaw
Actívalo en la configuración de tu agente:
{
agents: {
list: [{
id: "main",
tools: { allow: ["janee"] }
}]
}
}
Tu agente ahora tiene estas herramientas:
janee_list_services— Descubre las APIs disponiblesjanee_execute— Haz solicitudes de API a través de Janee
El plugin inicia janee serve automáticamente. Todas las solicitudes se registran en ~/.janee/logs/.
Herramientas MCP
Janee expone tres herramientas MCP:
| Herramienta | Descripción |
|---|---|
list_services | Descubre las APIs disponibles y sus políticas |
execute | Haz una solicitud de API a través de Janee (modo proxy HTTP) |
exec | Ejecuta un comando CLI con credenciales inyectadas (modo exec) |
manage_credential | Ver, otorgar o revocar acceso a credenciales con ámbito de agente |
reload_config | Recarga la configuración desde el disco después de añadir/eliminar servicios (disponible cuando se inicia con janee serve) |
Los agentes descubren lo que está disponible y luego llaman a las APIs a través de Janee. Mismo registro de auditoría, misma protección.
Configuración
La configuración vive en ~/.janee/config.yaml:
server:
host: localhost
services:
stripe:
baseUrl: https://api.stripe.com
auth:
type: bearer
key: sk_live_xxx # encrypted at rest
github:
baseUrl: https://api.github.com
auth:
type: bearer
key: ghp_xxx
capabilities:
stripe:
service: stripe
ttl: 1h
autoApprove: true
stripe_sensitive:
service: stripe
ttl: 5m
requiresReason: true
Servicios = APIs reales con claves reales Capacidades = Lo que los agentes pueden solicitar, con políticas
Tipos de autenticación admitidos
| Tipo | Descripción | Ejemplo |
|---|---|---|
bearer | Token Bearer en la cabecera Authorization | Stripe, OpenAI, GitHub |
basic | Autenticación Básica HTTP (usuario + contraseña) | APIs internas |
hmac-bybit | Firma HMAC-SHA256 para Bybit | Exchange Bybit |
hmac-okx | HMAC-SHA256 + frase de contraseña para OKX | Exchange OKX |
hmac-mexc | Firma HMAC-SHA256 para MEXC | Exchange MEXC |
headers | Cabeceras clave-valor personalizadas | APIs no estándar |
service-account | Clave JSON de cuenta de servicio de Google | Google Cloud |
github-app | Tokens de instalación de GitHub de corta duración | API de GitHub |
oauth1a-twitter | Firma OAuth 1.0a por solicitud | API de Twitter/X v2 |
aws-sigv4 | Firma AWS Signature V4 por solicitud | SES, S3 y otros servicios de AWS |
Twitter/X OAuth 1.0a
Janee calcula las firmas OAuth 1.0a (HMAC-SHA1) en el servidor, por lo que tus 4 secretos de Twitter permanecen cifrados en reposo y nunca entran en el contexto del agente:
services:
twitter:
baseUrl: https://api.x.com
auth:
type: oauth1a-twitter
consumerKey: xxx # encrypted at rest
consumerSecret: xxx # encrypted at rest
accessToken: xxx # encrypted at rest
accessTokenSecret: xxx # encrypted at rest
capabilities:
twitter:
service: twitter
ttl: 1h
autoApprove: true
O usa la plantilla integrada:
janee add twitter
AWS SigV4
Janee calcula AWS Signature V4 (HMAC-SHA256) por solicitud, manteniendo tus claves de acceso cifradas en reposo. Los campos no secretos (region, awsService) permanecen en la configuración en texto plano:
services:
aws-ses:
baseUrl: https://email.us-east-1.amazonaws.com
auth:
type: aws-sigv4
accessKeyId: AKIA... # encrypted at rest
secretAccessKey: xxx # encrypted at rest
region: us-east-1
awsService: ses
capabilities:
aws-ses:
service: aws-ses
ttl: 1h
autoApprove: true
Plantillas integradas para servicios comunes de AWS:
janee add aws-ses # Amazon SES
janee add aws-s3 # Amazon S3
Control de acceso
Controla qué agentes pueden usar qué capacidades:
server:
host: localhost
defaultAccess: restricted # capabilities require explicit allowlist
capabilities:
stripe:
service: stripe
ttl: 1h
allowedAgents: ["agent-a", "agent-b"] # only these agents can use it
github:
service: github
ttl: 1h
# no allowedAgents + defaultAccess: restricted → no agent can use this
defaultAccess: restricted— las capacidades sin una lista deallowedAgentsestán ocultas para todos los agentesdefaultAccess: open(predeterminado) — las capacidades sin una lista deallowedAgentsestán disponibles para todos los agentesallowedAgents— lista por capacidad de nombres de agentes (comparada conclientInfo.namedel apretón de manos de inicialización de MCP)
Las credenciales creadas por los agentes en tiempo de ejecución tienen por defecto acceso agent-only: solo el agente creador puede usarlas a menos que otorgue acceso explícitamente mediante la herramienta manage_credential.
Capacidades de modo exec
services:
twitter:
auth:
type: bearer
key: tvly-xxx
capabilities:
twitter:
service: twitter
mode: exec
allowCommands: ["bird", "tweet-cli"]
envMap:
TWITTER_API_KEY: "{{credential}}"
ttl: 1h
autoApprove: true
Las capacidades de modo exec usan janee_exec en lugar de execute. La credencial se inyecta como variable de entorno: el agente solo ve stdout/stderr.
Valores predeterminados de endurecimiento del runner en modo exec:
- entorno mínimo aislado (sin herencia completa del entorno del host)
HOMEtemporal por comando- el tiempo de espera mata el grupo de procesos
Modo Runner/Authority (para contenedores)
Cuando los agentes se ejecutan dentro de contenedores Docker, janee_exec en un host remoto no puede acceder al sistema de archivos del contenedor. La arquitectura Runner/Authority resuelve esto:
- Authority se ejecuta en el host: mantiene las credenciales, aplica políticas, hace de proxy para las solicitudes de API
- Runner se ejecuta dentro de cada contenedor: sirve MCP al agente, reenvía llamadas no exec al Authority, ejecuta
janee_execlocalmente
# Host: start Authority (MCP + exec authorization on one port)
janee serve -t http -p 3100 --host 0.0.0.0 --runner-key "$JANEE_RUNNER_KEY"
# Container: start Runner (agent talks to this)
janee serve -t http -p 3200 --host 127.0.0.1 \
--authority http://host.docker.internal:3100 --runner-key "$JANEE_RUNNER_KEY"
El agente solo necesita JANEE_URL=http://localhost:3200.
También puedes ejecutar el Authority como proceso independiente:
janee authority --runner-key "$JANEE_RUNNER_KEY" --host 127.0.0.1 --port 9120
Consulta la Guía de Runner/Authority para ver la arquitectura completa, el flujo de autorización de exec, el ejemplo de Docker Compose y la resolución de problemas.
Políticas de Solicitud
Controla exactamente qué solicitudes puede hacer cada capacidad usando rules:
capabilities:
stripe_readonly:
service: stripe
ttl: 1h
rules:
allow:
- GET *
deny:
- POST *
- PUT *
- DELETE *
stripe_billing:
service: stripe
ttl: 15m
requiresReason: true
rules:
allow:
- GET *
- POST /v1/refunds/*
- POST /v1/invoices/*
deny:
- POST /v1/charges/* # Can't charge cards
- DELETE *
Cómo funcionan las reglas:
- Los patrones de
denyse comprueban primero — la denegación explícita siempre gana - Luego se comprueban los patrones de
allow— deben coincidir para continuar - Sin reglas definidas → permitir todo (compatible con versiones anteriores)
- Reglas definidas pero sin coincidencia → denegado por defecto
Formato de patrón: METHOD PATH
GET *→ cualquier solicitud GETPOST /v1/charges/*→ POST a /v1/charges/ y subrutas* /v1/customers→ cualquier método a /v1/customersDELETE /v1/customers/*→ DELETE cualquier cliente
Esto hace que la seguridad sea real: Incluso si un agente miente sobre su "motivo", solo puede acceder a los endpoints que la política permite. La aplicación se realiza en el servidor.
Referencia CLI
janee init # Set up ~/.janee/ with example config
janee add # Add a service (interactive)
janee add stripe -u https://api.stripe.com -k sk_xxx # Add with args
janee remove <service> # Remove a service
janee remove <service> --yes # Remove without confirmation
janee list # List configured services
janee list --json # Output as JSON (for integrations)
janee search [query] # Search service directory
janee search stripe --json # Search with JSON output
janee cap list # List capabilities
janee cap list --json # List capabilities as JSON
janee cap add <name> --service <service> # Add capability
janee cap edit <name> # Edit capability
janee cap remove <name> # Remove capability
janee serve # Start MCP server (stdio, default)
janee serve --transport http --port 9100 # Start with HTTP transport (for containers)
janee serve --authority https://janee.example.com --runner-key $JANEE_RUNNER_KEY # Runner mode
janee authority --runner-key $JANEE_RUNNER_KEY # Start authority API
janee logs # View audit log
janee logs -f # Tail audit log
janee logs --json # Output as JSON
janee sessions # List active sessions
janee sessions --json # Output as JSON
janee revoke <id> # Kill a session
Configuración no interactiva (para agentes de IA)
Los agentes de IA no pueden responder a avisos interactivos. Usa las banderas --*-from-env para leer credenciales de variables de entorno: esto mantiene los secretos fuera de la ventana de contexto del agente:
# Bearer auth (Stripe, OpenAI, etc.)
janee add stripe -u https://api.stripe.com --auth-type bearer --key-from-env STRIPE_KEY
# HMAC auth (Bybit)
janee add bybit --auth-type hmac-bybit --key-from-env BYBIT_KEY --secret-from-env BYBIT_SECRET
# HMAC auth with passphrase (OKX)
janee add okx --auth-type hmac-okx --key-from-env OKX_KEY --secret-from-env OKX_SECRET --passphrase-from-env OKX_PASS
# GitHub App auth (short-lived tokens)
janee add github --auth-type github-app --app-id-from-env GH_APP_ID --pem-from-env GH_PEM --installation-id-from-env GH_INSTALL_ID
# Twitter/X OAuth 1.0a (per-request signing)
janee add twitter --consumer-key $TWITTER_CONSUMER_KEY --consumer-secret $TWITTER_CONSUMER_SECRET \
--access-token $TWITTER_ACCESS_TOKEN --access-token-secret $TWITTER_ACCESS_TOKEN_SECRET
# AWS SigV4 (SES, S3, etc.)
janee add aws-ses --access-key-id $AWS_ACCESS_KEY_ID --secret-access-key $AWS_SECRET_ACCESS_KEY \
--region us-east-1 --aws-service ses
Cuando todas las credenciales requeridas se proporcionan mediante banderas, Janee:
- Nunca abre readline (sin bloqueo en stdin)
- Crea automáticamente una capacidad con valores predeterminados sensatos (TTL de 1h, aprobación automática)
También puedes editar ~/.janee/config.yaml directamente si lo prefieres.
Cómo Funciona
┌─────────────┐ ┌──────────┐ ┌─────────┐
│ AI Agent │─────▶│ Janee │─────▶│ Stripe │
│ │ MCP │ MCP │ HTTP │ API │
└─────────────┘ └──────────┘ └─────────┘
│ │
No key Injects key
+ logs request
- El agente llama a la herramienta MCP
executecon capacidad, método, ruta - Janee busca la configuración del servicio, descifra la clave real
- Hace la solicitud HTTP a la API real con la clave
- Registra: marca de tiempo, servicio, método, ruta, estado
- Devuelve la respuesta al agente
El agente nunca toca la clave real.
📐 Inmersión profunda: Consulta Arquitectura y Modelo de Seguridad para ver diagramas detallados, modelo de amenazas y comparación con alternativas.
Seguridad
- Cifrado: Claves almacenadas con AES-256-GCM
- Identidad del agente: Derivada de
clientInfo.nameen el handshake de inicialización de MCP — no se necesitan encabezados personalizados - Aislamiento del agente: Cada agente obtiene su propia sesión con identidad aislada (el transporte HTTP crea un Server+Transport por sesión)
- Control de acceso: Lista blanca de
allowedAgentspor capacidad + política dedefaultAccessa nivel de servidor - Alcance de credenciales: Las credenciales creadas por agentes tienen como valor predeterminado
agent-only - Registro de auditoría: Cada solicitud se registra en
~/.janee/logs/ - Sesiones: Con límite de tiempo, revocables
- Interruptor de apagado:
janee revokeo eliminar configuración
Docker
Ejecuta Janee como un contenedor — no se requiere Node.js local:
# Build
docker build -t janee .
# Run in HTTP mode
docker run -d -p 3000:3000 \
-v ~/.janee:/root/.janee:ro \
janee --transport http --port 3000 --host 0.0.0.0
O usa Docker Compose:
mkdir -p config && cp ~/.janee/config.yaml config/
docker compose up -d
Para Claude Desktop con Docker, consulta Documentación de Docker.
Contribuciones
¡Agradecemos las contribuciones! Por favor, lee CONTRIBUTING.md antes de enviar un PR — incluye la lista de verificación requerida para PR (pruebas, changelog, aumento de versión, etc.).
Licencia
MIT — Creado por True and Useful LLC
Deja de dar tus claves a los agentes de IA. Comienza a controlar el acceso. 🔐