@chdlabs/my-shield 0.2.0 → 0.3.1

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,13 +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.
16
- - **MiniRocket Behavioral Biometrics**: Sub-2ms bot detection using deterministic 1D convolutional kernel transforms and Dual Ridge regression to identify automated splines and synthetic kinematics with zero runtime dependencies.
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`)**: Unified `ShieldClient` and `PointerTelemetryCollector` with mobile touch support (`pointerdown`, `touchmove`, tap dwell kinetics), 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.
17
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.
18
- - **Single-File Deduplicated Persistence**: Preserves learned probe patterns and promoted honeypots across process restarts in an atomic JSON file (`404_intelligence.json`).
19
- - **Self-Contained Security Dashboard**: Built-in dark-themed telemetry console with real-time Server-Sent Events (SSE), charts, and active block management.
20
- - **Safe By Default**: Admin dashboard is disabled by default (`admin.enabled: false`) with dedicated RBAC integration to prevent unauthorized telemetry access.
21
- - **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`).
22
25
 
23
26
  ---
24
27
 
@@ -29,9 +32,14 @@ Incoming Request
29
32
  │
30
33
  ▼
31
34
  ┌───────────────────────────────────────┐
35
+ │ Enterprise IPResolver │
36
+ │ Cloudflare / Nginx / HAProxy / Direct │
37
+ │ Gateway Protection (172.17.0.1 Immune)│
38
+ └──────────────────┬────────────────────┘
39
+ ▼
40
+ ┌───────────────────────────────────────┐
32
41
  │ L1 Shield Guard │
33
- │ │
34
- │ 1. IP Whitelist? ──▶ Pass │
42
+ │ 1. IP Whitelisted? ──▶ Pass │
35
43
  │ 2. Bloom Filter? ──▶ False = Pass │
36
44
  │ 3. LRU Cache? ──▶ Found = Block │
37
45
  └──────────────────┬────────────────────┘
@@ -43,11 +51,10 @@ Incoming Request
43
51
  └──────────────────┬────────────────────┘
44
52
  ▼
45
53
  ┌───────────────────────────────────────┐
46
- │ Behavioral Biometrics Guard (Optional)│
47
- │ MiniRocket + Dual Ridge (< 2ms) │
48
- │ Replay nonces? ──▶ Block 403 │
49
- │ Synthetic event? ──▶ Block 403 │
50
- │ Human probability? ──▶ >= 0.70 Pass │
54
+ │ Route-Level Bot Defenses (Optional) │
55
+ │ • strictBotGuard() on /login & /pay │
56
+ │ • behavioralGuard({ mode: 'audit' }) │
57
+ │ • costThrottle() on high-cost routes │
51
58
  └──────────────────┬────────────────────┘
52
59
  ▼
53
60
  ┌───────────────────────────────────────┐
@@ -57,7 +64,7 @@ Incoming Request
57
64
  ┌───────────────────────────────────────┐
58
65
  │ 404 Intelligence Collector │
59
66
  │ ≥ 5 unique 404s/60s? ──▶ Ban IP │
60
- │ Dedup snapshot saved to disk │
67
+ │ Auto-promotes frequent targets │
61
68
  └───────────────────────────────────────┘
62
69
  ```
63
70
 
@@ -81,63 +88,40 @@ const app = express();
81
88
 
82
89
  const shield = createShield({
83
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
84
94
  admin: {
85
- enabled: true // Set to true to activate dashboard & telemetry (Default: false)
86
- },
87
- bloom: {
88
- expectedItems: 100_000,
89
- falsePositiveRate: 0.01
90
- },
91
- lru: {
92
- maxSize: 10_000,
93
- ttlMs: 5 * 60 * 1000 // 5 minutes
94
- },
95
- honeypot: {
96
- enabled: true,
97
- delayMs: 500
98
- },
99
- intelligence: {
100
- anomalyThreshold: 5, // 5 unique 404s in 60s -> BAN
101
- anomalyWindowMs: 60_000,
102
- captureAll: true,
103
- filePersistence: {
104
- enabled: true,
105
- directory: './data/shield',
106
- filename: '404_intelligence.json',
107
- intervalMs: 60 * 60 * 1000, // 1 hour save interval
108
- loadOnStartup: true
109
- },
110
- autoPromote: {
111
- enabled: true,
112
- minHits: 50,
113
- minUniqueIPs: 10
114
- }
95
+ enabled: true // Set to true to activate dashboard (Default: false)
115
96
  }
116
97
  });
117
98
 
99
+ // Hydrate persisted threats into Bloom and LRU on application startup
100
+ await shield.init();
101
+
118
102
  // 1. Mount main defense guard (FIRST middleware after parsing)
119
103
  app.use(shield.middleware());
120
104
 
121
105
  // 2. Mount honeypot trap router (BEFORE application routes)
122
106
  app.use(shield.honeypot());
123
107
 
124
-
125
- // -----------------> ADD IN HERE ALL YOUR APPLICATION ROUTES <----------------//
126
- app.get('/api/data', (req, res) => res.json({ status: 'ok' }));
127
- // -----------------> ADD IN HERE ALL YOUR APPLICATION ROUTES <----------------//
128
-
129
-
130
-
108
+ // 3. Application Routes
109
+ app.get('/api/catalog', (req, res) => res.json({ items: [] }));
131
110
 
132
111
  // 4. Mount 404 intelligence collector (AFTER application routes)
133
112
  app.use(shield.notFoundCollector());
134
113
 
135
- // 5. Mount admin dashboard (protect API endpoints with your app's auth & RBAC middleware)
136
- app.use('/admin/shield', shield.adminRouter({
137
- 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
+ }
138
121
  }));
122
+ app.use('/admin/shield', shield.adminRouter());
139
123
 
140
- // Graceful shutdown: flushes 404 intelligence to disk
124
+ // Graceful shutdown: flushes intelligence and threat persistence to disk
141
125
  process.on('SIGTERM', async () => {
142
126
  await shield.shutdown();
143
127
  process.exit(0);
@@ -146,208 +130,219 @@ process.on('SIGTERM', async () => {
146
130
 
147
131
  ---
148
132
 
149
- ## 🔐 Admin Dashboard & Role-Based Access Control (RBAC)
133
+ ## 🛡️ Protecting Mission-Critical Routes (`/login`, `/checkout`, `/register`) From Bots
150
134
 
151
- The built-in admin dashboard provides live telemetry, attack velocity, probe intelligence, active threat management, and real-time Server-Sent Events (SSE).
152
-
153
- ### 1. Enabling the Dashboard
154
- 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:
155
- ```javascript
156
- const shield = createShield({
157
- admin: {
158
- enabled: true // Required to activate dashboard routes
159
- }
160
- });
161
- ```
162
-
163
- ### 2. Restricting Access to Administrators Only
164
- 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
-
166
- Instead, pass your authentication and authorization middleware into `shield.adminRouter({ authMiddleware })`:
167
- ```javascript
168
- app.use('/admin/shield', shield.adminRouter({
169
- authMiddleware: [authenticateUser, requireAdminRole]
170
- }));
171
- ```
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.
172
139
 
173
- #### Why this pattern is secure:
174
- 1. **Public Static Delivery**: The browser can freely download the dashboard SPA shell (`index.html`, `dashboard.css`, `dashboard.js`).
175
- 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`.
176
- 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.
140
+ ### 1. Backend Route Protection (`shield.strictBotGuard()`)
177
141
 
178
- ### 3. Complete Express RBAC Example
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**:
179
143
 
180
144
  ```javascript
181
- // Step A: Authentication middleware (verifies JWT / Bearer token)
182
- function authenticateUser(req, res, next) {
183
- const authHeader = req.headers.authorization || (req.query?.token ? `Bearer ${req.query.token}` : null);
184
- if (!authHeader || !authHeader.startsWith('Bearer ')) {
185
- return res.status(401).json({ error: 'Authentication required. Missing Authorization header.' });
186
- }
187
-
188
- const token = authHeader.split(' ')[1];
189
- try {
190
- const claims = verifyJwt(token); // Verify your JWT / PQC token
191
- req.user = claims;
192
- next();
193
- } catch (err) {
194
- return res.status(401).json({ error: 'Invalid or expired session token.' });
195
- }
196
- }
145
+ import express from 'express';
146
+ import { createShield } from '@chdlabs/my-shield';
197
147
 
198
- // Step B: Role-Based Access Control (RBAC) middleware
199
- function requireAdminRole(req, res, next) {
200
- // Check user role from token claims or database lookup
201
- if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'super_admin')) {
202
- return res.status(403).json({ error: 'Access denied: Administrator privileges required.' });
203
- }
204
- next();
205
- }
148
+ const app = express();
149
+ app.use(express.json());
206
150
 
207
- // Step C: Mount protected admin router
208
- app.use('/admin/shield', shield.adminRouter({
209
- authMiddleware: [authenticateUser, requireAdminRole]
210
- }));
211
- ```
151
+ const shield = createShield({ trustProxy: true });
152
+ await shield.init();
212
153
 
213
- ### 4. How the Dashboard Authenticates
214
- The dashboard client automatically looks for the session token in the following order:
215
- 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.
216
- 2. **Storage Fallback**: Checks `sessionStorage` and `localStorage` under standard keys: `shield_session_token`, `pqc_session_token`, `token`, `access_token`, `auth_token`, or `jwt`.
154
+ // Global ingress guard
155
+ app.use(shield.middleware());
217
156
 
218
- ---
157
+ // ── Protect High-Risk Mutations ──
219
158
 
220
- ## 🧠 Behavioral Biometrics via MiniRocket & Dual Ridge
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' });
163
+ });
221
164
 
222
- `@chdlabs/my-shield` incorporates client-side and server-side behavioral biometrics based on **MiniRocket** (*Minimally Random Convolutional Kernel Transform*) and a **Dual Ridge Classifier**.
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
+ });
223
169
 
224
- ### Why Behavioral Biometrics?
225
- Headless automation tools (Puppeteer, Playwright, curl) and synthetic scripts often lack realistic pointer physics or produce mathematically smoothed Bézier splines. Human users exhibit distinct continuous neuromuscular tremor, deceleration profiles, micro-corrections, and sub-movements.
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
+ );
226
178
 
227
- MiniRocket maps 128-point equispaced mouse velocity trajectories into a high-dimensional feature space using 84 deterministic length-9 kernels with multi-scale dilations and Proportion of Positive Values (PPV). Scoring is resolved via a single dot-product in Dual Ridge regression in **< 2.0 ms** with zero runtime dependencies.
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
+ });
184
+ ```
228
185
 
229
- ---
186
+ ### 2. Frontend Client Integration (`ShieldClient`)
230
187
 
231
- ### 1. Client-Side Telemetry Collection (Browser)
188
+ Install `@chdlabs/my-shield` in your frontend application (or import `./client`).
232
189
 
233
- Import the browser client module (`@chdlabs/my-shield/client`):
190
+ The client captures human pointer micro-movements across desktop mice, trackpads, and mobile touchscreens (measuring both continuous trajectory gestures and button tap dwell kinetics). When `instrumentFetch()` is enabled, it automatically attaches the `x-shield-telemetry` header to your API requests:
234
191
 
235
192
  ```javascript
236
- import { MouseTelemetryCollector } from '@chdlabs/my-shield/client';
193
+ // client/index.js (React, Vue, or Vanilla JS)
194
+ import { ShieldClient } from '@chdlabs/my-shield/client';
237
195
 
238
- // 1. Initialize telemetry collector (128 samples at 100Hz = 1.28s rolling window)
239
- const collector = new MouseTelemetryCollector({
196
+ // 1. Initialize client SDK
197
+ const shieldClient = new ShieldClient({
198
+ sampleIntervalMs: 10,
240
199
  windowLength: 128,
241
- sampleIntervalMs: 10
200
+ minPoints: 15, // Minimum raw events for continuous trajectories
201
+ maxIdleMs: 2500, // Freshness Guard: Discards trajectory if pointer idle > 2.5s
202
+ captureTouch: true, // Enables mobile touch & pointer dynamics
203
+ minTapDwellMs: 20, // Distinguishes genuine human taps from instant 0ms bot clicks
204
+ flushOnConsumption: true, // Prevents replaying identical trajectories
205
+ autoInjectTripwire: true // Injects invisible honeypot decoy trap into DOM
242
206
  });
243
207
 
244
- // 2. Start capturing pointer dynamics
245
- collector.start();
208
+ // 2. Start recording kinematics
209
+ shieldClient.start();
246
210
 
247
- // 3. Attach telemetry packet to sensitive API requests
248
- async function submitLogin(username, password) {
249
- // Extracts normalized 100Hz velocity series and event integrity metadata
250
- const telemetry = collector.getPayload(); // { velocity: number[], isTrusted: boolean, timestamp: number }
211
+ // 3. Transparently instrument fetch (or Axios)
212
+ shieldClient.instrumentFetch({
213
+ headerName: 'x-shield-telemetry',
214
+ endpoints: ['/api/auth/*', '/api/checkout*']
215
+ });
251
216
 
252
- const response = await fetch('/api/auth/login', {
253
- method: 'POST',
254
- headers: {
255
- 'Content-Type': 'application/json',
256
- 'x-shield-telemetry': telemetry ? JSON.stringify(telemetry) : ''
257
- },
258
- body: JSON.stringify({ username, password })
259
- });
217
+ // Now standard fetch calls automatically include kinematics telemetry!
218
+ async function submitLogin(email, password) {
219
+ try {
220
+ const res = await fetch('/api/auth/login', {
221
+ method: 'POST',
222
+ headers: { 'Content-Type': 'application/json' },
223
+ body: JSON.stringify({ email, password })
224
+ });
225
+
226
+ if (res.status === 403) {
227
+ const err = await res.json();
228
+ if (err.shieldCode === 'AUTOMATED_KINEMATICS_DETECTED') {
229
+ alert('Bot behavior detected. Please interact with the page normally.');
230
+ return;
231
+ }
232
+ }
260
233
 
261
- return response.json();
234
+ const data = await res.json();
235
+ console.log('Login successful:', data);
236
+ } catch (err) {
237
+ console.error('Request failed:', err);
238
+ }
262
239
  }
263
240
  ```
264
241
 
265
242
  ---
266
243
 
267
- ### 2. Server-Side Route Guard (Express)
244
+ ## 🌐 Enterprise Reverse Proxies & Gateway Protection
268
245
 
269
- Protect sensitive routes (e.g. login, payment checkout, AI prompt generation) with `shield.behavioralGuard()`:
246
+ When deploying in Docker, Kubernetes, AWS, or behind Cloudflare, standard `req.ip` lookups fail or ban internal container gateways. `IPResolver` resolves this natively:
270
247
 
271
248
  ```javascript
272
- import express from 'express';
273
- import { createShield } from '@chdlabs/my-shield';
274
-
275
- const app = express();
276
- app.use(express.json());
249
+ const shield = createShield({
250
+ // Trust proxy headers: true | false | 'loopback,linklocal,uniquelocal'
251
+ trustProxy: true,
277
252
 
278
- const shield = createShield();
279
-
280
- // Protect sensitive endpoints with behavioral biometrics
281
- app.post(
282
- '/api/auth/login',
283
- shield.behavioralGuard({
284
- threshold: 0.70, // Minimum human probability required (default: 0.70)
285
- headerName: 'x-shield-telemetry', // Header containing telemetry JSON
286
- replayWindowMs: 15_000, // Max acceptable age/drift in ms (default: 15s)
287
- autoBlockIP: true, // Auto-blacklist detected bots into Shield L1 Bloom + LRU
288
- allowFallbackOnError: false, // Fail-closed (default: false)
289
- onBotDetected: (req, res, meta) => {
290
- // Optional custom callback when bot is intercepted
291
- console.warn(`[BOT DETECTED] IP: ${req.ip}, Reason: ${meta.reason}, Confidence: ${meta.probability}`);
292
- res.status(403).json({ error: 'Automated kinematics detected.', code: meta.reason });
293
- }
294
- }),
295
- (req, res) => {
296
- // Verified human request! Access biometric audit metadata:
297
- console.log(req.shield.biometrics);
298
- // => { isHuman: true, humanConfidence: 0.94, latencyMs: 0.85, score: 2.75 }
253
+ // Permanently protects Docker bridge (172.17.0.1) & loopbacks from bans
254
+ protectGateways: true,
299
255
 
300
- res.json({ status: 'authenticated' });
301
- }
302
- );
256
+ // Optional custom subnets to shield from accidental bans
257
+ protectedSubnets: ['10.0.0.1', '192.168.1.1']
258
+ });
303
259
  ```
304
260
 
261
+ ### Supported Proxy Headers (in priority order):
262
+ 1. `cf-connecting-ip` (Cloudflare)
263
+ 2. `true-client-ip` (Akamai & Cloudflare Enterprise)
264
+ 3. `x-real-ip` (Nginx `proxy_set_header X-Real-IP $remote_addr`)
265
+ 4. `x-client-ip`
266
+ 5. `x-forwarded-for` (Multi-hop chains are parsed to find the first non-internal public IP)
267
+
268
+ If `trustProxy: false` is set (direct internet exposure without reverse proxy), all proxy headers are ignored to prevent header spoofing injection attacks.
269
+
305
270
  ---
306
271
 
307
- ### 3. Standalone Core Biometrics API
272
+ ## 💾 Pluggable Threat Persistence
308
273
 
309
- You can also use MiniRocket and the Dual Ridge Classifier directly for custom data pipelines or time series classification:
274
+ In containerized or serverless deployments, in-memory caches reset on every restart. Shield supports pluggable persistence adapters to maintain active threat bans:
310
275
 
276
+ ### 1. Single-Container File Persistence (Zero External Dependencies)
311
277
  ```javascript
312
- import { MiniRocket, DualRidgeClassifier } from '@chdlabs/my-shield/biometrics';
278
+ const shield = createShield({
279
+ storage: {
280
+ type: 'file',
281
+ directory: './data/shield',
282
+ filename: 'blocked_ips.json',
283
+ debounceMs: 500 // Debounced atomic writes
284
+ }
285
+ });
286
+ await shield.init();
287
+ ```
313
288
 
314
- // 1. Transform a 128-sample series into PPV features
315
- const mr = new MiniRocket(128, 336);
316
- mr.loadThresholds(fittedThresholds);
317
- const features = mr.transform(velocitySeries);
289
+ ### 2. Database & Cache Persistence (PostgreSQL, Redis, MongoDB, Prisma)
290
+ Plug any database into Shield with three async callbacks:
318
291
 
319
- // 2. Predict class probability
320
- const ridge = new DualRidgeClassifier();
321
- ridge.loadWeights(fittedWeights, bias);
322
- const result = ridge.predict(features);
292
+ ```javascript
293
+ const shield = createShield({
294
+ storage: {
295
+ async onLoad() {
296
+ // Return active unexpired blocked IPs on boot
297
+ const { rows } = await db.query(
298
+ 'SELECT ip, reason, metadata, expires_at AS "expiresAt" FROM blocked_threats WHERE expires_at IS NULL OR expires_at > NOW()'
299
+ );
300
+ return rows;
301
+ },
302
+ async onBlock(ip, reason, metadata, expiresAt) {
303
+ // Save or update blocked threat
304
+ await db.query(
305
+ `INSERT INTO blocked_threats (ip, reason, metadata, expires_at)
306
+ VALUES ($1, $2, $3, $4)
307
+ ON CONFLICT (ip) DO UPDATE SET reason = $2, metadata = $3, expires_at = $4`,
308
+ [ip, reason, JSON.stringify(metadata), expiresAt ? new Date(expiresAt) : null]
309
+ );
310
+ },
311
+ async onUnblock(ip) {
312
+ await db.query('DELETE FROM blocked_threats WHERE ip = $1', [ip]);
313
+ }
314
+ }
315
+ });
323
316
 
324
- console.log(result);
325
- // => { score: 1.42, probability: 0.805, isHuman: true }
317
+ // Restores unexpired database threats into Bloom filter and LRU cache
318
+ await shield.init();
326
319
  ```
327
320
 
328
321
  ---
329
322
 
330
- ### 4. Custom Model Retraining CLI
323
+ ## 🔑 Built-in Admin OTP / MFA Challenge Gate
331
324
 
332
- To retrain model weights against your own captured movement datasets:
325
+ Shield includes a standalone, zero-dependency dark-mode OTP challenge gate (`shield.otpGate()`) that protects `/admin/shield` without requiring external login libraries:
333
326
 
334
- ```bash
335
- node scripts/train-weights.js
336
- ```
337
- This fits MiniRocket thresholds and Dual Ridge primal weights from your kinematic data, serializing the bundle to `models/default-weights.json`.
338
-
339
- ---
340
-
341
- ### Behavioral Guard Options Reference
327
+ ```javascript
328
+ app.use('/admin/shield', shield.otpGate({
329
+ adminEmail: 'admin@company.com',
330
+ jwtSecret: process.env.SHIELD_SECRET, // Signs session cookies
331
+ codeTtlMs: 5 * 60 * 1000, // Code valid for 5 minutes
332
+ maxAttempts: 5, // Locks out after 5 invalid tries
333
+ async sendOtp(email, code) {
334
+ // Deliver via email or SMS
335
+ await mailer.sendMail({
336
+ to: email,
337
+ subject: 'Shield Admin Passcode',
338
+ text: `Your one-time passcode is: ${code}`
339
+ });
340
+ }
341
+ }));
342
342
 
343
- | Option | Type | Default | Description |
344
- |---|---|---|---|
345
- | `threshold` | `number` | `0.70` | Minimum human probability cutoff ($P \ge \text{threshold}$) |
346
- | `headerName` | `string` | `'x-shield-telemetry'` | Request header containing JSON telemetry payload |
347
- | `replayWindowMs` | `number` | `15000` | Sliding window in ms; rejects expired or futuristic timestamps |
348
- | `allowFallbackOnError` | `boolean` | `false` | Fail-open (`true`) vs fail-closed (`false`) when telemetry is missing or malformed |
349
- | `autoBlockIP` | `boolean` | `false` | Automatically add detected bot IP to Shield L1 Bloom + LRU cache |
350
- | `onBotDetected` | `Function` | `undefined` | Custom callback `(req, res, meta)` invoked when bot or replay is detected |
343
+ // Mount dashboard router
344
+ app.use('/admin/shield', shield.adminRouter());
345
+ ```
351
346
 
352
347
  ---
353
348
 
@@ -356,26 +351,18 @@ This fits MiniRocket thresholds and Dual Ridge primal weights from your kinemati
356
351
  | Option | Type | Default | Description |
357
352
  |---|---|---|---|
358
353
  | `whitelist` | `string[]` | `[]` | List of IP addresses that are never blocked |
359
- | `admin.enabled` | `boolean` | `false` | Explicit switch to enable the admin dashboard & telemetry |
360
- | `bloom.expectedItems` | `number` | `100000` | Estimated distinct IPs to hold in filter |
354
+ | `trustProxy` | `boolean\|string` | `'loopback,linklocal,uniquelocal'` | Reverse proxy trust configuration |
355
+ | `protectGateways` | `boolean` | `true` | Protects Docker bridge (`172.17.0.1`) and loopback from bans |
356
+ | `storage` | `string\|Object` | `'memory'` | Storage adapter (`'memory'`, `'file'`, or callback hooks) |
357
+ | `admin.enabled` | `boolean` | `false` | Explicit switch to enable admin dashboard & telemetry |
358
+ | `bloom.expectedItems` | `number` | `100000` | Estimated distinct IPs to hold in Bloom filter |
361
359
  | `bloom.falsePositiveRate` | `number` | `0.01` | Target false positive probability (1%) |
362
- | `bloom.sizeBytes` | `number` | `null` | Explicit bit array size in bytes |
363
360
  | `lru.maxSize` | `number` | `10000` | Max entries in confirmed threat cache |
364
361
  | `lru.ttlMs` | `number` | `300000` | Threat cache TTL in ms (5 minutes) |
365
- | `honeypot.enabled` | `boolean` | `true` | Enable/disable honeypot traps |
362
+ | `honeypot.enabled` | `boolean` | `true` | Enable/disable static honeypot traps |
366
363
  | `honeypot.delayMs` | `number` | `500` | Delay before sending silent 200 OK decoy |
367
- | `honeypot.additionalRoutes` | `string[]` | `[]` | Custom trap path patterns |
368
- | `biometrics.modelWeights` | `Object` | `null` | Custom MiniRocket thresholds, weights, and bias |
369
364
  | `intelligence.anomalyThreshold` | `number` | `5` | Unique 404s before IP is banned |
370
365
  | `intelligence.anomalyWindowMs` | `number` | `60000` | Sliding window in ms (60 seconds) |
371
- | `intelligence.filePersistence.enabled` | `boolean` | `true` | Enable periodic JSON snapshot saves |
372
- | `intelligence.filePersistence.directory` | `string` | `'./data/shield'` | Destination directory for JSON snapshot |
373
- | `intelligence.filePersistence.filename` | `string` | `'404_intelligence.json'` | Single deduplicated filename |
374
- | `intelligence.filePersistence.intervalMs`| `number` | `3600000` | Snapshot save interval (1 hour) |
375
- | `intelligence.filePersistence.loadOnStartup` | `boolean` | `true` | Restore intelligence on process start |
376
- | `intelligence.autoPromote.enabled` | `boolean` | `true` | Auto-promote frequent 404s to traps |
377
- | `intelligence.autoPromote.minHits` | `number` | `50` | Min 404 hits before promotion |
378
- | `intelligence.autoPromote.minUniqueIPs` | `number` | `10` | Min distinct IPs probing path |
379
366
 
380
367
  ---
381
368
 
@@ -386,7 +373,6 @@ This fits MiniRocket thresholds and Dual Ridge primal weights from your kinemati
386
373
  shield.blockIP('198.51.100.42', 'manual_ban', { admin: 'dev1' });
387
374
  shield.unblockIP('198.51.100.42');
388
375
  shield.allowIP('192.168.1.50'); // Add to whitelist
389
- shield.removeAllowedIP('192.168.1.50');
390
376
  shield.isWhitelisted('192.168.1.50'); // Returns boolean
391
377
 
392
378
  // Telemetry & Metrics
@@ -394,14 +380,14 @@ shield.getStats(); // Returns aggregate stats, LRU sizes, traps list
394
380
  shield.getIntelligence(); // Full 404 intelligence snapshot
395
381
  shield.getBloomHealth(); // Saturation percentage and estimated FPR
396
382
 
397
- // Behavioral Biometrics
398
- const outcome = shield.verifyBiometrics(velocityArray); // { score, probability, isHuman, latencyMs }
399
- app.post('/api/auth/login', shield.behavioralGuard({ threshold: 0.70 }), handler);
383
+ // Route-Level Bot Defenses
384
+ app.post('/api/auth/login', shield.strictBotGuard(), handler);
385
+ app.get('/api/search', shield.behavioralGuard({ mode: 'audit' }), handler);
400
386
 
401
- // Route-Level Denial-of-Wallet Cost Throttling
387
+ // Denial-of-Wallet Cost Throttling
402
388
  app.post('/api/ai-generate', shield.costThrottle({ weight: 10, maxCost: 100 }), handler);
403
389
 
404
- // Route-Level Token / Credential Leak Detection
390
+ // API Key / Secret Leak Detector
405
391
  app.use(shield.keyLeakDetector());
406
392
  ```
407
393
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chdlabs/my-shield",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Zero-latency security shield middleware with Bloom filter, honeypots, 404 intelligence, and MiniRocket behavioral biometrics",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -17,6 +17,10 @@
17
17
  "./biometrics": {
18
18
  "types": "./src/index.d.ts",
19
19
  "import": "./src/biometrics/index.js"
20
+ },
21
+ "./storage": {
22
+ "types": "./src/index.d.ts",
23
+ "import": "./src/storage/index.js"
20
24
  }
21
25
  },
22
26
  "publishConfig": {