// Open Source · MIT License · v0.2.0

Detect the Intent.
Before the Exploit.

Trappsec embeds deception directly in your application code — catching adversaries while they're still mapping your APIs, before a single perimeter is crossed.

# pip install trappsec
import trappsec

# 1. Initialize once per service
ts = trappsec.Sentry(app, service='PaymentService', environment='Production')

# 2. Decoy route — catches API enumeration
ts.trap('/api/v1/payouts') \
  .intent('financial_fraud')

# 3. Honey field — catches privilege escalation
ts.watch('/profile').body('is_admin', intent='PrivEsc')

# ✓ event: trappsec.trap_hit
# ✓ intent: privilege_escalation
# ✓ user: uid_8849 | role: standard
Python · Node.js · Go
Pre‑exploit
Detection
Zero
Infra Changes
MIT
OSS License

Attackers don't break in. They look around first.

Live request log — what your WAF sees
01 — The Reality

Attackers map before they exploit.

Probing your API structure, testing parameters, tracing workflows — all through valid requests that look identical to real user traffic.

02 — The Blindspot

WAFs catch signatures. They can't catch intent.

Most security programs optimize for what's easy to monitor — known patterns at the perimeter. They have no model of your business logic, so reconnaissance traffic passes through clean.

03 — The Cost

Traditional honeypots fire after the fact.

Disconnected from real application paths, they only trigger post-breach — when the attacker already knows your system. That's a post-compromise signal, not pre-exploitation detection.

The Hall of Mirrors

Trappsec embeds decoy routes and honey fields directly in your application code. The API surface looks completely uniform to an attacker. Only you can see what's real — and what's a trap.

Attacker's view — everything looks real
Defender's view
GET /api/v2/users 200
GET /api/v1/users 200
POST /api/v2/roles 200
GET /api/v1/admin/config 200
PUT /profile {"username":"x","is_admin":true} 200
GET /api/v2/transactions 200
DEL /api/v1/payouts/export 200
GET /api/v2/users real
GET /api/v1/users Decoy Route
POST /api/v2/roles Decoy Route
GET /api/v1/admin/config Decoy Route
PUT /profile is_admin Honey Field
GET /api/v2/transactions real
DEL /api/v1/payouts/export Decoy Route
Every trap triggers a high-fidelity alert enriched with the attacker's identity and intent — before a single real endpoint is exploited.

No identity,
no alert.

Unauthenticated probes — bots, scanners, fuzzers — get a 401 and are logged as signals. Only an attacker who returns with credentials triggers an alert. This single requirement eliminates all scanner noise and ensures every alert carries a real identity.

A — noise Anonymous probe
Scanner hits a decoy endpoint

No credentials. Indistinguishable from a thousand other probes you receive daily.

401
Trappsec returns 401 Unauthorized

A convincing response — identical to what your real protected endpoints return. The scanner sees nothing unusual.

Scanner moves on

Logged as a low-priority signal. No alert fires. No noise in your queue.

Signal Logged quietly. No action required.
vs
B — threat Targeted attacker
Attacker hits the same decoy endpoint

No credentials — gets the same 401. But unlike the scanner, they care about this endpoint.

Returns with credentials

The 401 signals "this exists and needs auth." A targeted attacker treats that as confirmation — and authenticates.

!
Alert fires with full identity

User ID, role, IP, and the intent you declared on the trap — captured at the moment of contact.

Alert uid_8849  ·  role: standard  ·  intent: privilege_escalation

Plant the traps.
Let attackers find them.

ts.trap( )

Decoy Routes

Ghost endpoints that mirror your real API structure. An attacker doing path discovery can't distinguish them from live routes. When accessed, they intercept the request, return a convincing dummy response, and fire an alert.

# A trap that looks like a real payouts endpoint
ts.trap("/api/v1/payouts/export") \
  .methods("GET") \
  .intent("financial_fraud") \
  .respond(200, {"records": []})
Unauthenticated → 401 bounce, zero noise
Authenticated → realistic response + covert alert
Alert includes user, role, IP, and declared intent
ts.watch( )

Honey Fields

Non-functional parameters baked into your real API responses. A regular user never touches "is_admin": false. An attacker probing privilege escalation will try to flip it. That's the trigger.

# Watch for tampering with is_admin in /profile
ts.watch("/profile") \
  .body("is_admin", intent="PrivEsc")

# App logic runs normally — alert fires silently
Application logic proceeds uninterrupted
Bait via GET response: "is_admin": false
Covert alert on any POST/PUT that mutates the field

Open the alert.
Start responding.

Every event arrives pre-classified with intent and identity. No triage overhead, no log pivoting — everything you need to act is in the payload.

// trappsec.trap_hit
{
  "event": "trappsec.trap_hit",
  "type": "alert",
  "intent": "privilege_escalation",
  "user": "uid_8849",
  "role": "standard",
  "ip": "192.168.1.42",
  "path": "/api/v1/admin/config",
  "service": "PaymentService"
}
"intent"
Pre-mapped intent
Classified at capture time by you — privilege escalation, financial fraud, reconnaissance. No manual triage to name what happened.
"user"  "role"
Identity attribution
User ID and role extracted via framework hooks. You know who it was — not just which IP hit the endpoint.
"type": "alert"
Confirmed actor, not a scanner
Unauthenticated probes are logged as signals — only authenticated contacts become alerts. Every alert in your queue is a real person - or AI agent.

Native Integration.
Zero Friction.

Trappsec operates as a lightweight SDK inside your applications. Events route to standard handlers by default, or pipe directly into your existing observability stack.

# pip install trappsec

import trappsec

# Initialize once per service
ts = trappsec.Sentry(app, service="PaymentService", environment="Production")

# Decoy route — catches API enumeration
ts.trap("/api/v1/payouts") \
  .intent("financial_fraud")

# Honey field — catches privilege escalation
ts.watch("/profile").body("is_admin", intent="PrivEsc")

Supported Frameworks

Python

Flask, FastAPI, Django, Starlette, Sanic, Litestar

pip install

Node.js

Express, Fastify, Hapi, Koa, NestJS

npm install
Go

Go

Gin, net/http, Echo

go get

Routes Events To

📋

Standard Logging

JSON events to your existing log pipeline

Default

Webhooks / Slack

Real-time alerts to your incident channel

Built-in
🔭

OpenTelemetry

Push into Datadog, Honeycomb, Grafana, etc.

Native

Moving Deception
into the Code

Trappsec shifts detection earlier in the attack lifecycle, bringing the signal quality of honeypots directly to the application's real attack surface.

Traditional Network Deception Business Logic Deception (Trappsec)
Placement Adjacent to infrastructure Embedded inside application code
Detection Phase Post-Breach (Assumed Compromise) Pre-Exploitation (Reconnaissance)
Target Activity Network scanning, lateral movement API probing, parameter tampering
Alert Context Infrastructure-level (IPs, ports) Identity-attributed intent
Alert Volume High — many false positives from scanners Low — only authenticated, targeted actors
Integration Separate appliance or agent Lightweight SDK
Traditional Trappsec ✦
Placement
Adjacent to infrastructure
Inside application code
Detection Phase
Post-breach
Pre-exploitation
Target Activity
Network scanning, lateral movement
API probing, parameter tampering
Alert Context
IPs, ports
Identity-attributed intent
Alert Volume
High — scanner noise
Low — authenticated actors only
Integration
Separate appliance or agent
Lightweight SDK

Your code is now
a security sensor.

Built for the 1% of people who actually look at their security alerts — and the 99% who just like the idea of having them.