@chdlabs/my-shield 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 🛡️ @chdlabs/my-shield
2
2
 
3
- > High-performance, zero-latency security shield middleware for Express. Built with pure JavaScript probabilistic data structures (Bloom filter + LRU cache), honeypot traps, and a self-improving 404 intelligence engine.
3
+ > High-performance, zero-latency security shield middleware for Express. Built with pure JavaScript probabilistic data structures (Bloom filter + LRU cache), honeypot traps, MiniRocket behavioral biometrics, pluggable threat persistence, and container-native enterprise IP resolution.
4
4
 
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
6
  [![Node: >=20](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen.svg)](https://nodejs.org/)
@@ -12,12 +12,16 @@
12
12
 
13
13
  - **Sub-0.1ms Clean Pass**: Legitimate requests pass through the L1 Bloom filter in `< 0.1ms`.
14
14
  - **Zero False-Positive Blocks**: Two-tiered L1 caching (Bloom filter + LRU confirmed threat cache) guarantees statistical Bloom false positives are never blocked.
15
- - **Silent Honeypot Decoys**: Static trap routes (`/.env`, `/wp-login.php`, `/.git/config`, etc.) return a silent `200 OK` decoy response after a brief delay and instantly blacklist scanners.
15
+ - **Enterprise Client IP Resolution (`IPResolver`)**: Production-tested parsing for Cloudflare (`CF-Connecting-IP`), Akamai (`True-Client-IP`), Nginx (`X-Real-IP`), and multi-hop HAProxy chains (`X-Forwarded-For`) with IPv6-mapped IPv4 normalization and port stripping.
16
+ - **Docker & Gateway Protection**: Docker bridge gateways (`172.17.0.1`) and loopback addresses (`127.0.0.1`, `::1`) are permanently immune from bans, preventing accidental container isolation.
17
+ - **Mission-Critical Route Protection**: First-class `shield.strictBotGuard()` to protect `/login`, `/checkout`, and `/register` against credential stuffing, carding (card testing), and automated account spam.
18
+ - **Dual-Mode Behavioral Biometrics**: Calibrated Ridge decision boundary (`0.50`) supporting non-blocking `'audit'` mode (for searches and queries) alongside strict `'block'` mode (for auth and checkout).
19
+ - **First-Party Client SDK (`@chdlabs/my-shield/client`)**: Full-featured `ShieldClient` with pointer freshness guards ($t_{\text{idle}} \le 2.5\text{s}$), buffer flushes on consumption, and automatic `fetch`/`Axios` interceptors.
20
+ - **Pluggable Threat Persistence**: Zero-overhead in-memory adapter, local JSON file persistence (`FileStorageAdapter`), or universal database hooks (`PostgreSQL`, `MySQL`, `Redis`, `Prisma`).
21
+ - **Built-in Admin OTP / MFA Challenge Gate**: Standalone, dark-mode OTP verification portal (`shield.otpGate()`) with timing-safe HMAC validation and brute-force protection.
22
+ - **Silent Honeypot Decoys**: Static trap routes (`/.env`, `/wp-login.php`, `/.git/config`, etc.) return a silent `200 OK` decoy response and instantly blacklist scanners.
16
23
  - **404 Anomaly & Intelligence**: Captures every 404 URL probe, bans scanners probing $\ge 5$ unique paths in 60s, and auto-promotes frequent attack targets to active honeypots.
17
- - **Single-File Deduplicated Persistence**: Preserves learned probe patterns and promoted honeypots across process restarts in an atomic JSON file (`404_intelligence.json`).
18
- - **Self-Contained Security Dashboard**: Built-in dark-themed telemetry console with real-time Server-Sent Events (SSE), charts, and active block management.
19
- - **Safe By Default**: Admin dashboard is disabled by default (`admin.enabled: false`) with dedicated RBAC integration to prevent unauthorized telemetry access.
20
- - **Zero Production Dependencies**: Pure JavaScript built exclusively with Node.js built-ins (`crypto`, `fs`, `path`, `events`).
24
+ - **Zero Production Dependencies**: Pure JavaScript built exclusively with Node.js built-ins (`crypto`, `fs`, `path`, `events`, `net`).
21
25
 
22
26
  ---
23
27
 
@@ -28,9 +32,14 @@ Incoming Request
28
32
  │
29
33
  ▼
30
34
  ┌───────────────────────────────────────┐
35
+ │ Enterprise IPResolver │
36
+ │ Cloudflare / Nginx / HAProxy / Direct │
37
+ │ Gateway Protection (172.17.0.1 Immune)│
38
+ └──────────────────┬────────────────────┘
39
+ ▼
40
+ ┌───────────────────────────────────────┐
31
41
  │ L1 Shield Guard │
32
- │ │
33
- │ 1. IP Whitelist? ──▶ Pass │
42
+ │ 1. IP Whitelisted? ──▶ Pass │
34
43
  │ 2. Bloom Filter? ──▶ False = Pass │
35
44
  │ 3. LRU Cache? ──▶ Found = Block │
36
45
  └──────────────────┬────────────────────┘
@@ -42,13 +51,20 @@ Incoming Request
42
51
  └──────────────────┬────────────────────┘
43
52
  ▼
44
53
  ┌───────────────────────────────────────┐
54
+ │ Route-Level Bot Defenses (Optional) │
55
+ │ • strictBotGuard() on /login & /pay │
56
+ │ • behavioralGuard({ mode: 'audit' }) │
57
+ │ • costThrottle() on high-cost routes │
58
+ └──────────────────┬────────────────────┘
59
+ ▼
60
+ ┌───────────────────────────────────────┐
45
61
  │ Application Routes (Your API) │
46
62
  └──────────────────┬────────────────────┘
47
63
  ▼
48
64
  ┌───────────────────────────────────────┐
49
65
  │ 404 Intelligence Collector │
50
66
  │ ≥ 5 unique 404s/60s? ──▶ Ban IP │
51
- │ Dedup snapshot saved to disk │
67
+ │ Auto-promotes frequent targets │
52
68
  └───────────────────────────────────────┘
53
69
  ```
54
70
 
@@ -72,63 +88,40 @@ const app = express();
72
88
 
73
89
  const shield = createShield({
74
90
  whitelist: ['127.0.0.1', '::1'],
91
+ trustProxy: true, // Auto-resolve Cloudflare, Nginx, or HAProxy client IPs
92
+ protectGateways: true, // Prevents 172.17.0.1 & loopbacks from ever being banned
93
+ storage: 'file', // Persist bans to ./data/shield/blocked_ips.json across restarts
75
94
  admin: {
76
- enabled: true // Set to true to activate dashboard & telemetry (Default: false)
77
- },
78
- bloom: {
79
- expectedItems: 100_000,
80
- falsePositiveRate: 0.01
81
- },
82
- lru: {
83
- maxSize: 10_000,
84
- ttlMs: 5 * 60 * 1000 // 5 minutes
85
- },
86
- honeypot: {
87
- enabled: true,
88
- delayMs: 500
89
- },
90
- intelligence: {
91
- anomalyThreshold: 5, // 5 unique 404s in 60s -> BAN
92
- anomalyWindowMs: 60_000,
93
- captureAll: true,
94
- filePersistence: {
95
- enabled: true,
96
- directory: './data/shield',
97
- filename: '404_intelligence.json',
98
- intervalMs: 60 * 60 * 1000, // 1 hour save interval
99
- loadOnStartup: true
100
- },
101
- autoPromote: {
102
- enabled: true,
103
- minHits: 50,
104
- minUniqueIPs: 10
105
- }
95
+ enabled: true // Set to true to activate dashboard (Default: false)
106
96
  }
107
97
  });
108
98
 
99
+ // Hydrate persisted threats into Bloom and LRU on application startup
100
+ await shield.init();
101
+
109
102
  // 1. Mount main defense guard (FIRST middleware after parsing)
110
103
  app.use(shield.middleware());
111
104
 
112
105
  // 2. Mount honeypot trap router (BEFORE application routes)
113
106
  app.use(shield.honeypot());
114
107
 
115
-
116
- // -----------------> ADD IN HERE ALL YOUR APPLICATION ROUTES <----------------//
117
- app.get('/api/data', (req, res) => res.json({ status: 'ok' }));
118
- // -----------------> ADD IN HERE ALL YOUR APPLICATION ROUTES <----------------//
119
-
120
-
121
-
108
+ // 3. Application Routes
109
+ app.get('/api/catalog', (req, res) => res.json({ items: [] }));
122
110
 
123
111
  // 4. Mount 404 intelligence collector (AFTER application routes)
124
112
  app.use(shield.notFoundCollector());
125
113
 
126
- // 5. Mount admin dashboard (protect API endpoints with your app's auth & RBAC middleware)
127
- app.use('/admin/shield', shield.adminRouter({
128
- authMiddleware: [authenticateUser, requireAdminRole]
114
+ // 5. Standalone OTP Protected Admin Console
115
+ app.use('/admin/shield', shield.otpGate({
116
+ adminEmail: 'security@company.com',
117
+ async sendOtp(email, code) {
118
+ // Send OTP via your email service (Nodemailer, SendGrid, etc.)
119
+ console.log(`[OTP] Sent code ${code} to ${email}`);
120
+ }
129
121
  }));
122
+ app.use('/admin/shield', shield.adminRouter());
130
123
 
131
- // Graceful shutdown: flushes 404 intelligence to disk
124
+ // Graceful shutdown: flushes intelligence and threat persistence to disk
132
125
  process.on('SIGTERM', async () => {
133
126
  await shield.shutdown();
134
127
  process.exit(0);
@@ -137,74 +130,217 @@ process.on('SIGTERM', async () => {
137
130
 
138
131
  ---
139
132
 
140
- ## 🔐 Admin Dashboard & Role-Based Access Control (RBAC)
133
+ ## 🛡️ Protecting Mission-Critical Routes (`/login`, `/checkout`, `/register`) From Bots
141
134
 
142
- The built-in admin dashboard provides live telemetry, attack velocity, probe intelligence, active threat management, and real-time Server-Sent Events (SSE).
135
+ Automated bots attack high-value mutation endpoints in three distinct ways:
136
+ 1. **Credential Stuffing & Brute Force (`/login`)**: Trying thousands of leaked email/password combinations.
137
+ 2. **Card Testing / Carding (`/checkout`)**: Testing stolen credit card numbers, which triggers costly payment gateway decline fees and chargebacks.
138
+ 3. **Account Farming (`/register`)**: Creating fake accounts for spamming or exploiting promotional credits.
139
+
140
+ ### 1. Backend Route Protection (`shield.strictBotGuard()`)
141
+
142
+ Mount `shield.strictBotGuard()` directly on your sensitive POST endpoints. It verifies behavioral mouse dynamics, rejects synthetic or automated bot vectors with `403 Forbidden`, and **instantly auto-bans the attacker's IP**:
143
143
 
144
- ### 1. Enabling the Dashboard
145
- By default, the admin dashboard is **disabled** (`admin.enabled: false`). If mounted while disabled, `/admin/shield` safely returns `404 Not Found`. To enable it, explicitly configure:
146
144
  ```javascript
147
- const shield = createShield({
148
- admin: {
149
- enabled: true // Required to activate dashboard routes
150
- }
145
+ import express from 'express';
146
+ import { createShield } from '@chdlabs/my-shield';
147
+
148
+ const app = express();
149
+ app.use(express.json());
150
+
151
+ const shield = createShield({ trustProxy: true });
152
+ await shield.init();
153
+
154
+ // Global ingress guard
155
+ app.use(shield.middleware());
156
+
157
+ // ── Protect High-Risk Mutations ──
158
+
159
+ // Protect Login against credential stuffing
160
+ app.post('/api/auth/login', shield.strictBotGuard(), (req, res) => {
161
+ // Only authentic human users reach this handler!
162
+ res.json({ success: true, token: 'session_token' });
151
163
  });
152
- ```
153
164
 
154
- ### 2. Restricting Access to Administrators Only
155
- Do **not** wrap `shield.adminRouter()` at the top-level route (e.g., `app.use('/admin/shield', requireAdmin, ...)`). Doing so causes browser page visits to fail with an immediate `401 Unauthorized` JSON response because web browsers do not send `Authorization` headers on initial page navigations.
165
+ // Protect User Registration against fake accounts
166
+ app.post('/api/auth/register', shield.strictBotGuard(), (req, res) => {
167
+ res.json({ success: true, user: req.body.email });
168
+ });
156
169
 
157
- Instead, pass your authentication and authorization middleware into `shield.adminRouter({ authMiddleware })`:
158
- ```javascript
159
- app.use('/admin/shield', shield.adminRouter({
160
- authMiddleware: [authenticateUser, requireAdminRole]
161
- }));
170
+ // Protect Checkout: Combine Strict Bot Defense with Cost Throttling
171
+ app.post('/api/checkout',
172
+ shield.strictBotGuard(),
173
+ shield.costThrottle({ weight: 5, maxCost: 50, windowMs: 60000 }),
174
+ (req, res) => {
175
+ res.json({ success: true, orderId: 'ord_123' });
176
+ }
177
+ );
178
+
179
+ // ── Protect High-Volume Reads with Audit Mode ──
180
+ // Does not reject searches, but logs kinematics and attaches X-Shield-Verdict header
181
+ app.get('/api/search', shield.behavioralGuard({ mode: 'audit' }), (req, res) => {
182
+ res.json({ results: [] });
183
+ });
162
184
  ```
163
185
 
164
- #### Why this pattern is secure:
165
- 1. **Public Static Delivery**: The browser can freely download the dashboard SPA shell (`index.html`, `dashboard.css`, `dashboard.js`).
166
- 2. **Protected API & Telemetry**: All data-bearing endpoints (`/admin/shield/api/stats`, `/admin/shield/api/blocked`, `/admin/shield/api/stream`, etc.) are strictly guarded by your `authMiddleware`.
167
- 3. **Graceful UI Feedback**: If a non-admin or unauthenticated visitor accesses the page, the dashboard renders an informative warning banner rather than a raw, broken JSON error.
186
+ ### 2. Frontend Client Integration (`ShieldClient`)
187
+
188
+ Install `@chdlabs/my-shield` in your frontend application (or import `./client`).
168
189
 
169
- ### 3. Complete Express RBAC Example
190
+ The client captures human pointer micro-movements as the user fills out the form and clicks "Submit" or "Pay Now". When `instrumentFetch()` is enabled, it automatically attaches the `x-shield-telemetry` header to your API requests:
170
191
 
171
192
  ```javascript
172
- // Step A: Authentication middleware (verifies JWT / Bearer token)
173
- function authenticateUser(req, res, next) {
174
- const authHeader = req.headers.authorization || (req.query?.token ? `Bearer ${req.query.token}` : null);
175
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
176
- return res.status(401).json({ error: 'Authentication required. Missing Authorization header.' });
177
- }
193
+ // client/index.js (React, Vue, or Vanilla JS)
194
+ import { ShieldClient } from '@chdlabs/my-shield/client';
195
+
196
+ // 1. Initialize client SDK
197
+ const shieldClient = new ShieldClient({
198
+ sampleIntervalMs: 10,
199
+ windowLength: 128,
200
+ minPoints: 15, // Requires at least 15 raw events to prevent flatlines
201
+ maxIdleMs: 2500, // Freshness Guard: Discards trajectory if pointer idle > 2.5s
202
+ flushOnConsumption: true, // Prevents replaying identical trajectories
203
+ autoInjectTripwire: true // Injects invisible honeypot decoy trap into DOM
204
+ });
178
205
 
179
- const token = authHeader.split(' ')[1];
206
+ // 2. Start recording kinematics
207
+ shieldClient.start();
208
+
209
+ // 3. Transparently instrument fetch (or Axios)
210
+ shieldClient.instrumentFetch({
211
+ headerName: 'x-shield-telemetry',
212
+ endpoints: ['/api/auth/*', '/api/checkout*']
213
+ });
214
+
215
+ // Now standard fetch calls automatically include kinematics telemetry!
216
+ async function submitLogin(email, password) {
180
217
  try {
181
- const claims = verifyJwt(token); // Verify your JWT / PQC token
182
- req.user = claims;
183
- next();
218
+ const res = await fetch('/api/auth/login', {
219
+ method: 'POST',
220
+ headers: { 'Content-Type': 'application/json' },
221
+ body: JSON.stringify({ email, password })
222
+ });
223
+
224
+ if (res.status === 403) {
225
+ const err = await res.json();
226
+ if (err.shieldCode === 'AUTOMATED_KINEMATICS_DETECTED') {
227
+ alert('Bot behavior detected. Please interact with the page normally.');
228
+ return;
229
+ }
230
+ }
231
+
232
+ const data = await res.json();
233
+ console.log('Login successful:', data);
184
234
  } catch (err) {
185
- return res.status(401).json({ error: 'Invalid or expired session token.' });
235
+ console.error('Request failed:', err);
186
236
  }
187
237
  }
238
+ ```
239
+
240
+ ---
241
+
242
+ ## 🌐 Enterprise Reverse Proxies & Gateway Protection
243
+
244
+ When deploying in Docker, Kubernetes, AWS, or behind Cloudflare, standard `req.ip` lookups fail or ban internal container gateways. `IPResolver` resolves this natively:
245
+
246
+ ```javascript
247
+ const shield = createShield({
248
+ // Trust proxy headers: true | false | 'loopback,linklocal,uniquelocal'
249
+ trustProxy: true,
250
+
251
+ // Permanently protects Docker bridge (172.17.0.1) & loopbacks from bans
252
+ protectGateways: true,
253
+
254
+ // Optional custom subnets to shield from accidental bans
255
+ protectedSubnets: ['10.0.0.1', '192.168.1.1']
256
+ });
257
+ ```
258
+
259
+ ### Supported Proxy Headers (in priority order):
260
+ 1. `cf-connecting-ip` (Cloudflare)
261
+ 2. `true-client-ip` (Akamai & Cloudflare Enterprise)
262
+ 3. `x-real-ip` (Nginx `proxy_set_header X-Real-IP $remote_addr`)
263
+ 4. `x-client-ip`
264
+ 5. `x-forwarded-for` (Multi-hop chains are parsed to find the first non-internal public IP)
265
+
266
+ If `trustProxy: false` is set (direct internet exposure without reverse proxy), all proxy headers are ignored to prevent header spoofing injection attacks.
267
+
268
+ ---
269
+
270
+ ## 💾 Pluggable Threat Persistence
188
271
 
189
- // Step B: Role-Based Access Control (RBAC) middleware
190
- function requireAdminRole(req, res, next) {
191
- // Check user role from token claims or database lookup
192
- if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
193
- return res.status(403).json({ error: 'Access denied: Administrator privileges required.' });
272
+ In containerized or serverless deployments, in-memory caches reset on every restart. Shield supports pluggable persistence adapters to maintain active threat bans:
273
+
274
+ ### 1. Single-Container File Persistence (Zero External Dependencies)
275
+ ```javascript
276
+ const shield = createShield({
277
+ storage: {
278
+ type: 'file',
279
+ directory: './data/shield',
280
+ filename: 'blocked_ips.json',
281
+ debounceMs: 500 // Debounced atomic writes
194
282
  }
195
- next();
196
- }
283
+ });
284
+ await shield.init();
285
+ ```
197
286
 
198
- // Step C: Mount protected admin router
199
- app.use('/admin/shield', shield.adminRouter({
200
- authMiddleware: [authenticateUser, requireAdminRole]
201
- }));
287
+ ### 2. Database & Cache Persistence (PostgreSQL, Redis, MongoDB, Prisma)
288
+ Plug any database into Shield with three async callbacks:
289
+
290
+ ```javascript
291
+ const shield = createShield({
292
+ storage: {
293
+ async onLoad() {
294
+ // Return active unexpired blocked IPs on boot
295
+ const { rows } = await db.query(
296
+ 'SELECT ip, reason, metadata, expires_at AS "expiresAt" FROM blocked_threats WHERE expires_at IS NULL OR expires_at > NOW()'
297
+ );
298
+ return rows;
299
+ },
300
+ async onBlock(ip, reason, metadata, expiresAt) {
301
+ // Save or update blocked threat
302
+ await db.query(
303
+ `INSERT INTO blocked_threats (ip, reason, metadata, expires_at)
304
+ VALUES ($1, $2, $3, $4)
305
+ ON CONFLICT (ip) DO UPDATE SET reason = $2, metadata = $3, expires_at = $4`,
306
+ [ip, reason, JSON.stringify(metadata), expiresAt ? new Date(expiresAt) : null]
307
+ );
308
+ },
309
+ async onUnblock(ip) {
310
+ await db.query('DELETE FROM blocked_threats WHERE ip = $1', [ip]);
311
+ }
312
+ }
313
+ });
314
+
315
+ // Restores unexpired database threats into Bloom filter and LRU cache
316
+ await shield.init();
202
317
  ```
203
318
 
204
- ### 4. How the Dashboard Authenticates
205
- The dashboard client automatically looks for the session token in the following order:
206
- 1. **URL Query Parameter**: Navigating to `http://your-server.com/admin/shield?token=<jwt>` extracts the token into `sessionStorage` and automatically scrubs the parameter from the browser's address bar to prevent token leakage.
207
- 2. **Storage Fallback**: Checks `sessionStorage` and `localStorage` under standard keys: `shield_session_token`, `pqc_session_token`, `token`, `access_token`, `auth_token`, or `jwt`.
319
+ ---
320
+
321
+ ## 🔑 Built-in Admin OTP / MFA Challenge Gate
322
+
323
+ Shield includes a standalone, zero-dependency dark-mode OTP challenge gate (`shield.otpGate()`) that protects `/admin/shield` without requiring external login libraries:
324
+
325
+ ```javascript
326
+ app.use('/admin/shield', shield.otpGate({
327
+ adminEmail: 'admin@company.com',
328
+ jwtSecret: process.env.SHIELD_SECRET, // Signs session cookies
329
+ codeTtlMs: 5 * 60 * 1000, // Code valid for 5 minutes
330
+ maxAttempts: 5, // Locks out after 5 invalid tries
331
+ async sendOtp(email, code) {
332
+ // Deliver via email or SMS
333
+ await mailer.sendMail({
334
+ to: email,
335
+ subject: 'Shield Admin Passcode',
336
+ text: `Your one-time passcode is: ${code}`
337
+ });
338
+ }
339
+ }));
340
+
341
+ // Mount dashboard router
342
+ app.use('/admin/shield', shield.adminRouter());
343
+ ```
208
344
 
209
345
  ---
210
346
 
@@ -213,25 +349,18 @@ The dashboard client automatically looks for the session token in the following
213
349
  | Option | Type | Default | Description |
214
350
  |---|---|---|---|
215
351
  | `whitelist` | `string[]` | `[]` | List of IP addresses that are never blocked |
216
- | `admin.enabled` | `boolean` | `false` | Explicit switch to enable the admin dashboard & telemetry |
217
- | `bloom.expectedItems` | `number` | `100000` | Estimated distinct IPs to hold in filter |
352
+ | `trustProxy` | `boolean\|string` | `'loopback,linklocal,uniquelocal'` | Reverse proxy trust configuration |
353
+ | `protectGateways` | `boolean` | `true` | Protects Docker bridge (`172.17.0.1`) and loopback from bans |
354
+ | `storage` | `string\|Object` | `'memory'` | Storage adapter (`'memory'`, `'file'`, or callback hooks) |
355
+ | `admin.enabled` | `boolean` | `false` | Explicit switch to enable admin dashboard & telemetry |
356
+ | `bloom.expectedItems` | `number` | `100000` | Estimated distinct IPs to hold in Bloom filter |
218
357
  | `bloom.falsePositiveRate` | `number` | `0.01` | Target false positive probability (1%) |
219
- | `bloom.sizeBytes` | `number` | `null` | Explicit bit array size in bytes |
220
358
  | `lru.maxSize` | `number` | `10000` | Max entries in confirmed threat cache |
221
359
  | `lru.ttlMs` | `number` | `300000` | Threat cache TTL in ms (5 minutes) |
222
- | `honeypot.enabled` | `boolean` | `true` | Enable/disable honeypot traps |
360
+ | `honeypot.enabled` | `boolean` | `true` | Enable/disable static honeypot traps |
223
361
  | `honeypot.delayMs` | `number` | `500` | Delay before sending silent 200 OK decoy |
224
- | `honeypot.additionalRoutes` | `string[]` | `[]` | Custom trap path patterns |
225
362
  | `intelligence.anomalyThreshold` | `number` | `5` | Unique 404s before IP is banned |
226
363
  | `intelligence.anomalyWindowMs` | `number` | `60000` | Sliding window in ms (60 seconds) |
227
- | `intelligence.filePersistence.enabled` | `boolean` | `true` | Enable periodic JSON snapshot saves |
228
- | `intelligence.filePersistence.directory` | `string` | `'./data/shield'` | Destination directory for JSON snapshot |
229
- | `intelligence.filePersistence.filename` | `string` | `'404_intelligence.json'` | Single deduplicated filename |
230
- | `intelligence.filePersistence.intervalMs`| `number` | `3600000` | Snapshot save interval (1 hour) |
231
- | `intelligence.filePersistence.loadOnStartup` | `boolean` | `true` | Restore intelligence on process start |
232
- | `intelligence.autoPromote.enabled` | `boolean` | `true` | Auto-promote frequent 404s to traps |
233
- | `intelligence.autoPromote.minHits` | `number` | `50` | Min 404 hits before promotion |
234
- | `intelligence.autoPromote.minUniqueIPs` | `number` | `10` | Min distinct IPs probing path |
235
364
 
236
365
  ---
237
366
 
@@ -242,7 +371,6 @@ The dashboard client automatically looks for the session token in the following
242
371
  shield.blockIP('198.51.100.42', 'manual_ban', { admin: 'dev1' });
243
372
  shield.unblockIP('198.51.100.42');
244
373
  shield.allowIP('192.168.1.50'); // Add to whitelist
245
- shield.removeAllowedIP('192.168.1.50');
246
374
  shield.isWhitelisted('192.168.1.50'); // Returns boolean
247
375
 
248
376
  // Telemetry & Metrics
@@ -250,10 +378,14 @@ shield.getStats(); // Returns aggregate stats, LRU sizes, traps list
250
378
  shield.getIntelligence(); // Full 404 intelligence snapshot
251
379
  shield.getBloomHealth(); // Saturation percentage and estimated FPR
252
380
 
253
- // Route-Level Denial-of-Wallet Cost Throttling
381
+ // Route-Level Bot Defenses
382
+ app.post('/api/auth/login', shield.strictBotGuard(), handler);
383
+ app.get('/api/search', shield.behavioralGuard({ mode: 'audit' }), handler);
384
+
385
+ // Denial-of-Wallet Cost Throttling
254
386
  app.post('/api/ai-generate', shield.costThrottle({ weight: 10, maxCost: 100 }), handler);
255
387
 
256
- // Route-Level Token / Credential Leak Detection
388
+ // API Key / Secret Leak Detector
257
389
  app.use(shield.keyLeakDetector());
258
390
  ```
259
391