Documentation Index
Fetch the complete documentation index at: https://docs.lintliot.com/llms.txt
Use this file to discover all available pages before exploring further.
The Express adapter wraps LintLiot’s full protection stack into standard Express middleware. You mount it once before your routes and every request is inspected — no per-route changes required. The adapter also exports helpers for per-route rate limits and permission guards when you need finer control.
Prerequisites
Basic setup
Create a Lintliot instance
Import createLintliot and initialize it with your API key. Create the instance once at the module level — not inside a request handler.import { createLintliot } from '@lintliot/sdk'
const lintliot = createLintliot({
apiKey: process.env.LINTLIOT_API_KEY!,
})
Mount the global middleware
Use lintliot.protect() as the first app.use call, before any router or route definition.import express from 'express'
import { createLintliot } from '@lintliot/sdk'
const app = express()
const lintliot = createLintliot({ apiKey: process.env.LINTLIOT_API_KEY! })
// Mount before all routes
app.use(lintliot.protect())
app.get('/api/users', (req, res) => {
res.json({ users: [] })
})
app.listen(3000)
lintliot.protect() must be registered before any route or router middleware. Mounting it after routes means those routes will not be protected.
Use the Express-specific adapter
For tighter Express integration — including typed req.lintliot context and proper error forwarding via next(err) — import from @lintliot/sdk/express:
import express from 'express'
import { createLintliot } from '@lintliot/sdk'
import { createExpressMiddleware } from '@lintliot/sdk/express'
const app = express()
const lintliot = createLintliot({ apiKey: process.env.LINTLIOT_API_KEY! })
app.use(createExpressMiddleware(lintliot, {
rateLimit: { max: 200, windowMs: 60_000 },
waf: 'block',
securityHeaders: true,
skipRoutes: ['/health', '/metrics'],
}))
After createExpressMiddleware runs, downstream handlers can read req.lintliot for the resolved IP address and user ID:
app.get('/api/profile', (req, res) => {
const { ip, userId } = req.lintliot
res.json({ ip, userId })
})
Per-route rate limiting
Use lintliot.rateLimit() to apply a stricter limit to a specific route, such as a login endpoint. Add it as a route-level middleware before the handler:
app.post(
'/api/auth/login',
lintliot.rateLimit({ max: 5, windowMs: 60_000 }),
loginHandler
)
Or use the adapter’s expressRateLimit helper:
import { expressRateLimit } from '@lintliot/sdk/express'
app.post(
'/api/auth/login',
expressRateLimit(lintliot, { max: 5, windowMs: 60_000 }),
loginHandler
)
The global lintliot.protect() middleware already applies a baseline rate limit to all routes. Per-route limits let you enforce tighter thresholds for sensitive endpoints like authentication and password reset.
Permission middleware
Use lintliot.can('permission') to guard a route. It checks the authenticated user’s permissions against LintLiot IAM before the handler runs:
// Single permission check
app.delete('/api/users/:id', lintliot.can('users:delete'), deleteUserHandler)
// Protect an admin route
app.get('/api/admin/reports', lintliot.can('admin:read'), reportsHandler)
Or use expressCan from the adapter for multiple permissions (all must pass):
import { expressCan } from '@lintliot/sdk/express'
app.post(
'/api/admin/billing',
expressCan(lintliot, 'admin:write', 'billing:manage'),
billingHandler
)
If the request is not authenticated, the middleware returns 401. If the user lacks the required permission, it returns 403.
One-line setup (no separate instance)
If you prefer not to manage the lintliot instance yourself, use lintliotExpress which handles instance caching internally:
import express from 'express'
import { lintliotExpress } from '@lintliot/sdk/express'
const app = express()
app.use(lintliotExpress({ apiKey: process.env.LINTLIOT_API_KEY! }))
Register routes for pentest discovery
After defining all your routes, call registerExpressRoutes to send the route list to the LintLiot API. This powers the Pentest Engine’s route discovery:
import { registerExpressRoutes } from '@lintliot/sdk/express'
// Define all routes first
app.get('/api/users', usersHandler)
app.post('/api/login', loginHandler)
// Then register them (fire-and-forget, non-blocking)
registerExpressRoutes(lintliot, app)
Error handling
Mount lintliotErrorHandler as your last middleware to format LintLiot errors consistently:
import { lintliotErrorHandler } from '@lintliot/sdk/express'
// After all routes
app.use(lintliotErrorHandler())