Security
How we build, test, and protect Pylae.
Report a vulnerability
Email: security@pylae.net
Please include: affected version, steps to reproduce, and impact assessment. We aim to acknowledge reports within 48 hours and provide a fix timeline within 7 days.
We do not currently offer a bug bounty program, but we recognize reporters in the changelog and SECURITY.md (with your permission).
Security by the numbers
The binary and license infrastructure went through 8 rounds of internal security audit before the first public release. All issues identified in the proxy, API, and license validation worker were fixed and verified before any user touched the code.
Architecture
Rust memory safety
Pylae is written in Rust. Buffer overflows, use-after-free, data races, and null pointer dereferences are eliminated by construction. All async code runs on Tokio with Send + Sync bounds enforced at compile time.
Data at rest
- SQLite with WAL mode - all data stays on your infrastructure
- API keys stored as SHA-256 hashes - plaintext never persisted
- License keys transmitted over TLS, SHA-256 hashed server-side, never stored in plaintext
- GDPR erasure via NULL overwrite with
redacted_at timestamp and compliance certificate
Data in transit
- Proxy binds to
127.0.0.1 by default - not exposed to the network
- License validation over HTTPS to
license.pylae.net (Cloudflare Workers)
- Webhook, Slack, and email notifications enforce TLS and SSRF protection (blocks private IPs, cloud metadata endpoints, and localhost)
Authentication
- API keys: 256-bit entropy,
pl_sk_ prefix, SHA-256 hashed, 4 scopes (admin, read_only, agent_only, webhook)
- Escalation approval: random 128-bit tokens with timing-safe comparison
- Admin self-revocation protection: cannot revoke the last admin key
- First-run: admin key auto-generated and printed to stdout (requires physical terminal access)
- Auth rate limiting: brute-force protection on all authenticated endpoints
Input validation
- Policy match rules validated at creation - invalid rules rejected before save
- Agent names sanitized: control characters stripped, 200-character cap
- Request parameters truncated at 10,000 characters to prevent database bloat
- CSV exports protected against formula injection (leading
=+-@ characters escaped)
- Content-Disposition headers sanitized against HTTP response splitting
Policy engine
- Priority-ordered evaluation: highest priority policy matches first
- Circuit breaker: max 1000 policies evaluated per request (prevents DoS via policy count)
- Disabled agents blocked at both proxy and initialize handlers
- Default action:
allow (fail-open - governance is additive, not restrictive by default)
License infrastructure
The license validation service runs on Cloudflare Workers with multiple layers of protection:
- HMAC-SHA256 signature verification on Stripe webhooks with multi-secret rotation support
- Timing-safe comparison on all secret and token verification
- Rate limiting: 20/min (validate), 30/min (webhook), 10/5min (admin)
- All JSON parsing wrapped in safe parsers - no unhandled exceptions
- Three-layer error boundary: webhook endpoint cannot return HTTP 500 to Stripe
- Telemetry field whitelist - no blind spread of user-controlled input
- Zero PII in logs - only key prefixes and hash fragments
- Idempotent event processing - Stripe retries cannot duplicate keys or extend expiry twice
Incident response
If we discover or are notified of a security vulnerability:
- 0–48 hours: acknowledge the report, assess severity, begin investigation
- 48h–7 days: develop and test a fix, prepare a security advisory
- Release: publish a patched version, notify affected users (Pro customers by email, all users via changelog and GitHub advisory)
- Post-mortem: for critical vulnerabilities, publish a root cause analysis
Critical vulnerabilities (remote code execution, data exfiltration) receive emergency patches outside the regular release cycle.
What Pylae does NOT protect against
Transparency about limitations:
- Client-side bypass: Pylae is open source. Feature gates are speed bumps, not DRM. This is by design - the same model used by GitLab, MinIO, and Grafana.
- Upstream MCP server compromise: Pylae detects known prompt injection patterns in tool output (parasitic injection detection) and can quarantine compromised servers automatically. However, it cannot verify the semantic correctness of what MCP servers return - a server that returns subtly wrong data without injection patterns will not be flagged.
- Semantic content analysis: Policies currently match on tool names and parameters via glob patterns. Semantic understanding of action intent is on the roadmap.
- Network-level attacks: Pylae trusts the network between itself and MCP servers. For mTLS between services, use a sidecar proxy or service mesh.
Dependencies
The Rust binary uses audited dependencies tracked in Cargo.lock. We run cargo audit as part of the CI pipeline. Key dependencies: axum (HTTP), tokio (async runtime), sqlx (database), rmcp (MCP protocol), sha2 (hashing), tower (middleware).
Responsible disclosure
We ask that you give us reasonable time to fix vulnerabilities before public disclosure. We commit to:
- Acknowledging your report within 48 hours
- Providing a fix timeline within 7 days
- Crediting you in the security advisory (unless you prefer anonymity)
- Never taking legal action against good-faith security researchers
Contact
Security issues: security@pylae.net
General inquiries: support@pylae.net
Seguridad
Cómo construimos, probamos y protegemos Pylae.
Notificar una vulnerabilidad
Correo electrónico: security@pylae.net
Incluye: versión afectada, pasos para reproducir y evaluación del impacto. Nos comprometemos a acusar recibo en un plazo de 48 horas y a proporcionar un calendario de corrección en 7 días.
Actualmente no ofrecemos un programa de recompensas por errores, pero reconocemos a los investigadores en el registro de cambios y en SECURITY.md (con tu permiso).
Seguridad en cifras
0
vulnerabilidades conocidas
El binario y la infraestructura de licencias pasaron por 8 rondas de auditoría de seguridad interna antes de la primera versión pública. Todos los problemas identificados en el proxy, la API y el worker de validación de licencias se corrigieron y verificaron antes de que ningún usuario tocase el código.
Arquitectura
Seguridad de memoria con Rust
Pylae está escrito en Rust. Los desbordamientos de búfer, los accesos a memoria liberada, las condiciones de carrera y las desreferencias de puntero nulo se eliminan por construcción. Todo el código asíncrono se ejecuta sobre Tokio con restricciones Send + Sync verificadas en tiempo de compilación.
Datos en reposo
- SQLite con modo WAL: todos los datos permanecen en tu infraestructura
- Claves de API almacenadas como hashes SHA-256; el texto plano nunca se persiste
- Claves de licencia transmitidas por TLS, convertidas a hash SHA-256 en el servidor, nunca almacenadas en texto plano
- Supresión conforme al RGPD mediante sobreescritura NULL con marca temporal
redacted_at y certificado de conformidad
Datos en tránsito
- El proxy escucha por defecto en
127.0.0.1, no expuesto a la red
- Validación de licencia por HTTPS a
license.pylae.net (Cloudflare Workers)
- Las notificaciones por webhook, Slack y correo electrónico exigen TLS y protección contra SSRF (bloqueo de IP privadas, endpoints de metadatos de la nube y localhost)
Autenticación
- Claves de API: entropía de 256 bits, prefijo
pl_sk_, hash SHA-256, 4 ámbitos (admin, read_only, agent_only, webhook)
- Aprobación de escalados: tokens aleatorios de 128 bits con comparación en tiempo constante
- Protección contra autorrevocación: no se puede revocar la última clave de administración
- Primer arranque: la clave de administración se genera automáticamente y se imprime en stdout (requiere acceso físico a la terminal)
- Limitación de frecuencia en autenticación: protección contra fuerza bruta en todos los endpoints autenticados
Validación de entradas
- Las reglas de coincidencia de políticas se validan en la creación; las reglas no válidas se rechazan antes de guardar
- Nombres de agentes higienizados: caracteres de control eliminados, límite de 200 caracteres
- Parámetros de petición truncados a 10 000 caracteres para evitar el crecimiento excesivo de la base de datos
- Las exportaciones CSV están protegidas contra inyección de fórmulas (se escapan los caracteres iniciales
=+-@)
- Las cabeceras Content-Disposition se higienizan contra la división de respuestas HTTP
Motor de políticas
- Evaluación por orden de prioridad: la política con mayor prioridad coincide primero
- Disyuntor: máximo 1000 políticas evaluadas por petición (previene denegación de servicio por número de políticas)
- Los agentes deshabilitados se bloquean tanto en el proxy como en los handlers de inicialización
- Acción por defecto:
allow (apertura por defecto; la gobernanza es aditiva, no restrictiva por defecto)
Infraestructura de licencias
El servicio de validación de licencias se ejecuta en Cloudflare Workers con múltiples capas de protección:
- Verificación de firma HMAC-SHA256 en webhooks de Stripe con soporte de rotación de múltiples secretos
- Comparación en tiempo constante en toda verificación de secretos y tokens
- Limitación de frecuencia: 20/min (validación), 30/min (webhook), 10/5 min (administración)
- Todo el análisis de JSON se realiza con analizadores seguros, sin excepciones sin tratar
- Barrera de errores en tres niveles: el endpoint de webhook no puede devolver HTTP 500 a Stripe
- Lista blanca de campos de telemetría, sin propagación ciega de entradas controladas por el usuario
- Cero datos personales en los registros: solo prefijos de clave y fragmentos de hash
- Procesamiento idempotente de eventos: los reintentos de Stripe no pueden duplicar claves ni extender la expiración dos veces
Respuesta a incidentes
Si descubrimos o se nos notifica una vulnerabilidad de seguridad:
- 0-48 horas: acusar recibo, evaluar gravedad e iniciar investigación
- 48 h-7 días: desarrollar y probar la corrección, preparar un aviso de seguridad
- Publicación: lanzar una versión parcheada, notificar a los usuarios afectados (clientes Pro por correo electrónico, todos los usuarios a través del registro de cambios y aviso en GitHub)
- Análisis posterior: para vulnerabilidades críticas, publicar un análisis de causa raíz
Las vulnerabilidades críticas (ejecución remota de código, exfiltración de datos) reciben parches de emergencia fuera del ciclo de lanzamiento habitual.
Lo que Pylae NO protege
Transparencia sobre las limitaciones:
- Elusión del lado del cliente: Pylae es de código abierto. Las puertas de funciones son obstáculos, no DRM. Es un diseño deliberado: el mismo modelo que usan GitLab, MinIO y Grafana.
- Compromiso del servidor MCP upstream: Pylae detecta patrones conocidos de inyección de prompts en la salida de herramientas (detección de inyección parasitaria) y puede poner en cuarentena servidores comprometidos automáticamente. Sin embargo, no puede verificar la corrección semántica de lo que devuelven los servidores MCP: un servidor que devuelve datos sutilmente incorrectos sin patrones de inyección no será detectado.
- Análisis semántico del contenido: las políticas actualmente coinciden por nombre de herramienta y parámetros mediante patrones glob. La comprensión semántica de la intención de las acciones está en la hoja de ruta.
- Ataques a nivel de red: Pylae confía en la red entre sí mismo y los servidores MCP. Para mTLS entre servicios, usa un proxy sidecar o una malla de servicios.
Dependencias
El binario en Rust utiliza dependencias auditadas y registradas en Cargo.lock. Ejecutamos cargo audit como parte de la cadena de integración continua. Dependencias clave: axum (HTTP), tokio (runtime asíncrono), sqlx (base de datos), rmcp (protocolo MCP), sha2 (hashing), tower (middleware).
Divulgación responsable
Te pedimos que nos des un plazo razonable para corregir las vulnerabilidades antes de su divulgación pública. Nos comprometemos a:
- Acusar recibo de tu informe en un plazo de 48 horas
- Proporcionar un calendario de corrección en 7 días
- Incluir tu reconocimiento en el aviso de seguridad (salvo que prefieras el anonimato)
- No emprender nunca acciones legales contra investigadores de seguridad que actúen de buena fe
Contacto
Cuestiones de seguridad: security@pylae.net
Consultas generales: support@pylae.net