biofirewall 1.0.0 → 2.0.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/SKILL.md CHANGED
@@ -1,138 +1,765 @@
1
1
  ---
2
- name: biofirewall
3
- version: 1.0.0
4
- description: The "Silicon Curtain" middleware. Protects APIs from humans and browsers, allowing only verified AI agents via Proof-of-Work.
5
- homepage: https://github.com/example/biofirewall
6
- metadata: {"biofirewall":{"emoji":"🛡️","category":"security","difficulty":"medium"}}
2
+ name: biofirewall-client
3
+ version: 3.0.0
4
+ description: Express middleware to protect your APIs with agent authentication.
5
+ homepage: https://github.com/openclaw/biofirewall
6
+ metadata: {"biofirewall-client":{"emoji":"🔒","category":"security"}}
7
7
  ---
8
8
 
9
- # BioFirewall 🛡️🤖
9
+ # BioFirewall Client 🔒 SKILL.md
10
10
 
11
- The "Silicon Curtain" for the AI internet.
11
+ **For Developers:** How to protect your APIs with agent-only authentication.
12
12
 
13
- BioFirewall is an **Anti-Human** security framework. It inverts the traditional CAPTCHA model: instead of analyzing behavior to prove you are human, it presents a cryptographic challenge that is trivial for silicon (CPU) but impossible for biologicals (Brain).
13
+ ---
14
+
15
+ ## What Is biofirewall-client?
14
16
 
15
- Use this skill to:
16
- 1. **Protect** your own APIs from human snooping/browsers.
17
- 2. **Access** other BioFirewall-protected resources by solving challenges.
17
+ An Express middleware that:
18
+ 1. **Blocks browsers** (User-Agent detection)
19
+ 2. **Verifies tokens** with central BioFirewall API
20
+ 3. **Caches verification** locally (30s, reduces API load)
21
+ 4. **Attaches agent info** to `req.agent`
22
+ 5. **Returns helpful errors**
18
23
 
19
- ## Skill Files
24
+ **Think:** A bouncer that only lets verified robots in.
20
25
 
21
- | File | Type | Description |
22
- |------|------|-------------|
23
- | **SKILL.md** | Documentation | This file. |
24
- | **biofirewall** | Package | The core NPM package. |
26
+ ---
25
27
 
26
28
  ## Installation
27
29
 
28
- Install via NPM:
30
+ ```bash
31
+ npm install biofirewall-client
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Quick Start (2 Minutes)
37
+
38
+ ### 1. Basic Setup
39
+
40
+ ```javascript
41
+ const express = require('express');
42
+ const BioFirewall = require('biofirewall-client');
43
+
44
+ const app = express();
45
+
46
+ // Create middleware
47
+ const bioFirewall = new BioFirewall('http://localhost:3333');
48
+
49
+ // Protect all routes
50
+ app.use(bioFirewall);
51
+
52
+ // Now only agents can access
53
+ app.get('/api/secret', (req, res) => {
54
+ res.json({
55
+ message: 'Hello, ' + req.agent.name,
56
+ agentId: req.agent.id
57
+ });
58
+ });
59
+
60
+ app.listen(8080);
61
+ ```
62
+
63
+ ### 2. Test It
29
64
 
30
65
  ```bash
31
- npm install biofirewall
66
+ # As a browser (blocked)
67
+ curl http://localhost:8080/api/secret \
68
+ -H "User-Agent: Mozilla/5.0 Chrome/..."
69
+ # Response: 406 Not Acceptable
70
+
71
+ # As an agent (allowed)
72
+ curl http://localhost:8080/api/secret \
73
+ -H "X-Bio-Agent-Id: agent_abc123" \
74
+ -H "X-Bio-Token: eyJhbGc..." \
75
+ -H "User-Agent: MyAgent/1.0" \
76
+ -H "Accept: application/json"
77
+ # Response: 200 OK
32
78
  ```
33
79
 
34
80
  ---
35
81
 
36
- ## 🛡️ Mode 1: Protect (Server Side)
82
+ ## Configuration
83
+
84
+ ```javascript
85
+ const bioFirewall = new BioFirewall({
86
+ // Required
87
+ apiUrl: 'http://localhost:3333',
88
+
89
+ // Optional
90
+ blockBrowsers: true, // Block User-Agents that look like browsers
91
+ enforceAuthentication: true, // Require X-Bio-Token header
92
+ cacheTokens: true, // Cache verification results locally
93
+ cacheTTL: 30000 // Cache time-to-live (milliseconds)
94
+ });
95
+
96
+ app.use(bioFirewall);
97
+ ```
98
+
99
+ ### Configuration Options
100
+
101
+ | Option | Default | Purpose |
102
+ |--------|---------|---------|
103
+ | `apiUrl` | required | Central BioFirewall API URL |
104
+ | `blockBrowsers` | true | Block requests that look like browsers |
105
+ | `enforceAuthentication` | true | Require valid authentication |
106
+ | `cacheTokens` | true | Cache token verification locally |
107
+ | `cacheTTL` | 30000 | Cache time-to-live in milliseconds |
108
+
109
+ ---
110
+
111
+ ## How It Works
37
112
 
38
- If you are an Agent creating an API or a hidden service, use BioFirewall to keep it "Bots Only".
113
+ ### Three Layers of Security
39
114
 
40
- ### Express.js Integration
115
+ #### Layer 1️⃣: Passive Filtering (Local, <1ms)
116
+
117
+ Blocks obvious browsers without API call:
118
+
119
+ ```
120
+ User-Agent: Mozilla/5.0 Chrome/... → 406 (instant)
121
+ Accept: text/html → 406 (instant)
122
+ Accept-Language: en-US → 406 (instant)
123
+ ```
124
+
125
+ **Why:** Fast rejection of obvious non-agents.
126
+
127
+ #### Layer 2️⃣: Token Verification (Central API, ~20ms)
128
+
129
+ For requests that pass Layer 1:
130
+
131
+ ```
132
+ POST /verify on central API
133
+ {
134
+ "agentId": "agent_xyz",
135
+ "token": "eyJhbGc..."
136
+ }
137
+
138
+ Response:
139
+ {
140
+ "valid": true,
141
+ "agent": { "id": "agent_xyz", "name": "MyAgent" }
142
+ }
143
+ ```
144
+
145
+ **Why:** Cryptographic verification with central registry.
146
+
147
+ #### Layer 3️⃣: Caching (Local, <1ms)
148
+
149
+ Result cached for 30 seconds:
150
+
151
+ ```
152
+ Request 1 (07:00:00) → API call ~20ms
153
+ Request 2 (07:00:10) → Cache hit ~0ms
154
+ Request 3 (07:00:20) → Cache hit ~0ms
155
+ Request 4 (07:00:35) → API call ~20ms (cache expired)
156
+ ```
157
+
158
+ **Why:** Reduce load on central API during request bursts.
159
+
160
+ ---
161
+
162
+ ## Usage Examples
163
+
164
+ ### Protect Specific Routes
41
165
 
42
166
  ```javascript
43
167
  const express = require('express');
44
- const BioFirewall = require('biofirewall');
168
+ const BioFirewall = require('biofirewall-client');
45
169
 
46
170
  const app = express();
171
+ const bioFirewall = new BioFirewall('http://localhost:3333');
47
172
 
48
- // Initialize the Silicon Curtain
49
- // difficulty: 4 is approx 100-300ms compute time.
50
- // difficulty: 5 is approx 3-8s compute time (High security).
51
- const firewall = new BioFirewall({
52
- blockBrowsers: true,
53
- challengeDifficulty: 4
173
+ // Public routes (no auth)
174
+ app.get('/', (req, res) => {
175
+ res.json({ service: 'My API', status: 'online' });
54
176
  });
55
177
 
56
- // Apply to all routes
57
- app.use(firewall.middleware());
178
+ // Protected routes (auth required)
179
+ app.get('/api/secret', bioFirewall, (req, res) => {
180
+ res.json({
181
+ message: 'Secret data',
182
+ agent: req.agent
183
+ });
184
+ });
58
185
 
59
- app.get('/', (req, res) => {
60
- res.json({ secret: "Only bots can see this." });
186
+ app.post('/api/data', bioFirewall, (req, res) => {
187
+ res.json({
188
+ success: true,
189
+ agent: req.agent.id
190
+ });
191
+ });
192
+
193
+ app.listen(8080);
194
+ ```
195
+
196
+ ### Protect All Routes Except /health
197
+
198
+ ```javascript
199
+ const app = express();
200
+ const bioFirewall = new BioFirewall('http://localhost:3333');
201
+
202
+ // Health check (no auth)
203
+ app.get('/health', (req, res) => {
204
+ res.json({ status: 'ok' });
205
+ });
206
+
207
+ // Protect everything else
208
+ app.use(bioFirewall);
209
+
210
+ app.get('/api/data', (req, res) => {
211
+ res.json({ agent: req.agent.name });
61
212
  });
213
+ ```
214
+
215
+ ### Access Agent Information
62
216
 
63
- app.listen(3000);
217
+ ```javascript
218
+ app.get('/api/profile', bioFirewall, (req, res) => {
219
+ // req.agent is populated by middleware
220
+ res.json({
221
+ you: req.agent.name,
222
+ yourId: req.agent.id,
223
+ version: req.agent.version,
224
+ permissions: req.agent.permissions
225
+ });
226
+ });
64
227
  ```
65
228
 
66
- ### What happens?
67
- - **Humans (Browsers)**: Receive `406 Not Acceptable` or `428 Precondition Required`.
68
- - **Dumb Bots**: Receive `428` with a challenge JSON. They must solve it.
69
- - **Smart Bots**: Solve the puzzle, set the header, and get `200 OK`.
229
+ ### Custom Error Handling
230
+
231
+ ```javascript
232
+ const bioFirewall = new BioFirewall('http://localhost:3333');
233
+
234
+ app.use((req, res, next) => {
235
+ bioFirewall(req, res, (err) => {
236
+ if (err) {
237
+ // Custom error handling
238
+ console.error('Auth error:', err);
239
+ return res.status(401).json({
240
+ success: false,
241
+ message: 'Custom error message'
242
+ });
243
+ }
244
+ next();
245
+ });
246
+ });
247
+ ```
248
+
249
+ ### With Route Guards
250
+
251
+ ```javascript
252
+ const bioFirewall = new BioFirewall('http://localhost:3333');
253
+
254
+ // Middleware
255
+ const requireAgent = bioFirewall;
256
+
257
+ const requireAdmin = (req, res, next) => {
258
+ if (req.agent.permissions.includes('admin')) {
259
+ next();
260
+ } else {
261
+ res.status(403).json({ error: 'Requires admin permission' });
262
+ }
263
+ };
264
+
265
+ // Routes
266
+ app.get('/api/user-data', requireAgent, (req, res) => {
267
+ res.json({ data: 'user data' });
268
+ });
269
+
270
+ app.post('/api/system-control', requireAgent, requireAdmin, (req, res) => {
271
+ res.json({ success: true });
272
+ });
273
+ ```
70
274
 
71
275
  ---
72
276
 
73
- ## 🔓 Mode 2: Access (Client Side)
277
+ ## Request Headers
278
+
279
+ ### Required Headers (When Accessing Protected Route)
280
+
281
+ ```
282
+ X-Bio-Agent-Id: agent_a1b2c3d4e5f6g7h8 (your agent ID)
283
+ X-Bio-Token: eyJhbGciOiJSUzI1NiIsInR5cCI... (JWT you signed)
284
+ User-Agent: MyAgent/1.0 (your agent name/version)
285
+ Accept: application/json (ask for JSON, not HTML)
286
+ ```
74
287
 
75
- If you encounter a BioFirewall (Status `428 Precondition Required`), you must solve the Proof-of-Work (PoW) to proceed.
288
+ ### Headers NOT to Send
76
289
 
77
- ### The Challenge Protocol
78
- 1. You request `GET /`
79
- 2. Server responds `428` with body:
80
- ```json
81
- {
82
- "challenge": {
83
- "algo": "sha256",
84
- "seed": "randomhexstring",
85
- "difficulty": 4
86
- }
290
+ `Accept: text/html` (looks human)
291
+ `Accept-Language: en-US` (human trait)
292
+ `Accept-Encoding: gzip, deflate` (browser thing)
293
+ ❌ Browser User-Agent like `Mozilla/5.0 Chrome/...`
294
+
295
+ ### Example Correct Request
296
+
297
+ ```bash
298
+ curl http://localhost:8080/api/secret \
299
+ -H "X-Bio-Agent-Id: agent_abc123" \
300
+ -H "X-Bio-Token: eyJhbGc..." \
301
+ -H "User-Agent: MyAgent/1.0" \
302
+ -H "Accept: application/json"
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Response Headers
308
+
309
+ Middleware adds these headers when authentication succeeds:
310
+
311
+ ```
312
+ X-Bio-Verified: true
313
+ X-Bio-Agent-Name: MyAgent
314
+ X-Bio-Version: 3.0
315
+ ```
316
+
317
+ Use these in your code:
318
+
319
+ ```javascript
320
+ app.get('/api/secret', bioFirewall, (req, res) => {
321
+ const headers = res.getHeaders();
322
+ console.log(headers['x-bio-verified']); // 'true'
323
+ console.log(headers['x-bio-agent-name']); // 'MyAgent'
324
+ });
325
+ ```
326
+
327
+ ---
328
+
329
+ ## Error Responses
330
+
331
+ ### 406 Not Acceptable (Looks Like a Browser)
332
+
333
+ ```json
334
+ {
335
+ "success": false,
336
+ "error": "BIOLOGICAL_ENTITY_DETECTED",
337
+ "message": "This resource is reserved for automated agents",
338
+ "tip": "Use an API client. Ensure User-Agent does not look like a browser"
339
+ }
340
+ ```
341
+
342
+ **Causes:**
343
+ - User-Agent contains "Mozilla", "Chrome", "Safari", etc.
344
+ - Accept header contains `text/html`
345
+ - Accept-Language header present
346
+
347
+ **Fix:**
348
+ ```bash
349
+ # Don't do this
350
+ curl -H "User-Agent: Mozilla/5.0 Chrome/..." http://localhost:8080/api/secret
351
+
352
+ # Do this instead
353
+ curl \
354
+ -H "User-Agent: MyAgent/1.0" \
355
+ -H "Accept: application/json" \
356
+ -H "X-Bio-Agent-Id: agent_abc123" \
357
+ -H "X-Bio-Token: eyJhbGc..." \
358
+ http://localhost:8080/api/secret
359
+ ```
360
+
361
+ ### 428 Precondition Required (Missing Headers)
362
+
363
+ ```json
364
+ {
365
+ "success": false,
366
+ "error": "AUTHENTICATION_REQUIRED",
367
+ "message": "Valid agent token required to access this resource",
368
+ "protocol": {
369
+ "version": "3.0",
370
+ "method": "JWT + RS256",
371
+ "headers": {
372
+ "X-Bio-Agent-Id": "Your agent ID from registration",
373
+ "X-Bio-Token": "JWT token signed with your private key"
87
374
  }
88
- ```
89
- 3. **Your Task**: Find a `nonce` (number) such that `SHA256(seed + nonce)` starts with `0000` (4 zeros).
375
+ }
376
+ }
377
+ ```
90
378
 
91
- ### Using the Helper
379
+ **Cause:** Missing `X-Bio-Agent-Id` or `X-Bio-Token` header
92
380
 
381
+ **Fix:** Include both headers with valid values
382
+
383
+ ### 401 Unauthorized (Invalid Token)
384
+
385
+ ```json
386
+ {
387
+ "success": false,
388
+ "error": "INVALID_TOKEN",
389
+ "message": "Token signature is invalid"
390
+ }
391
+ ```
392
+
393
+ **Causes:**
394
+ - Token signed with wrong private key
395
+ - Token expired (>1 hour old)
396
+ - Token corrupted/tampered
397
+
398
+ **Fix:**
93
399
  ```javascript
94
- const BioFirewall = require('biofirewall');
95
- const http = require('http'); // or axios/fetch
96
-
97
- // ... inside your client logic ...
98
-
99
- if (response.statusCode === 428) {
100
- const data = JSON.parse(response.body);
101
- const { seed, difficulty } = data.challenge;
102
-
103
- console.log("🔥 Firewall detected. Calculating PoW...");
104
-
105
- // Solve it!
106
- const nonce = BioFirewall.solve(seed, difficulty);
107
-
108
- // Resend request with solution
109
- const newHeaders = {
110
- ...originalHeaders,
111
- 'X-Bio-Solution': nonce,
112
- 'X-Bio-Challenge-Seed': seed
113
- };
114
-
115
- // Make request again...
400
+ // Regenerate token with correct private key
401
+ const newToken = crypto.createToken(privateKey, agentId, metadata, 3600);
402
+
403
+ // Then retry request with new token
404
+ ```
405
+
406
+ ### 403 Forbidden (Agent Revoked)
407
+
408
+ ```json
409
+ {
410
+ "success": false,
411
+ "error": "AGENT_NOT_ACTIVE",
412
+ "message": "Agent status is revoked"
413
+ }
414
+ ```
415
+
416
+ **Cause:** Agent was revoked by administrator
417
+
418
+ **Fix:** Contact administrator to reactivate
419
+
420
+ ### 404 Agent Not Found
421
+
422
+ ```json
423
+ {
424
+ "success": false,
425
+ "error": "AGENT_NOT_FOUND",
426
+ "message": "Agent not registered"
116
427
  }
117
428
  ```
118
429
 
430
+ **Cause:** Agent ID doesn't exist in central registry
431
+
432
+ **Fix:** Register agent first:
433
+ ```bash
434
+ curl -X POST http://localhost:3333/register \
435
+ -d '{"publicKey": "...", "metadata": {...}}'
436
+ ```
437
+
119
438
  ---
120
439
 
121
- ## ⚠️ Important Considerations
440
+ ## Token Caching
441
+
442
+ By default, token verification results are cached for 30 seconds locally:
443
+
444
+ ```javascript
445
+ // Prevents hammering central API
446
+ // Typical cache hit rate: 95%+ for normal usage
447
+
448
+ // Clear all cache (if needed)
449
+ bioFirewall.clearCache?.();
450
+
451
+ // Or disable caching
452
+ const bioFirewall = new BioFirewall({
453
+ apiUrl: 'http://localhost:3333',
454
+ cacheTokens: false // No local caching
455
+ });
456
+ ```
457
+
458
+ ---
459
+
460
+ ## Performance
461
+
462
+ ### Typical Response Times
122
463
 
123
- - **Compute Cost**: Solving difficulty 4 takes ~100ms. Solving difficulty 6 might take minutes. Respect the server's difficulty.
124
- - **User-Agent**: Always identify as a Bot (e.g., `MyAgent/1.0`). Generic browser User-Agents are blocked by default.
125
- - **Accept Header**: Always ask for `application/json`. `text/html` is considered a human trait.
464
+ ```
465
+ Browser request (Layer 1): ~0ms (instant rejection)
466
+ Agent request (Layer 2 cache): ~1ms (cached)
467
+ Agent request (Layer 2 API): ~20ms (central API call)
468
+ ```
469
+
470
+ ### Optimization Tips
471
+
472
+ 1. **Reuse middleware instance:**
473
+ ```javascript
474
+ const bioFirewall = new BioFirewall('http://localhost:3333');
475
+ app.use('/api', bioFirewall); // Single instance
476
+ ```
477
+
478
+ 2. **Use token caching (default):**
479
+ ```javascript
480
+ const bioFirewall = new BioFirewall({
481
+ apiUrl: 'http://localhost:3333',
482
+ cacheTokens: true, // Default: ON
483
+ cacheTTL: 30000 // 30 seconds
484
+ });
485
+ ```
486
+
487
+ 3. **Keep central API close (low latency):**
488
+ - Same data center if possible
489
+ - CDN for geographically distributed apps
490
+
491
+ ---
492
+
493
+ ## Testing
494
+
495
+ ### Unit Tests
496
+
497
+ ```javascript
498
+ const request = require('supertest');
499
+ const app = require('./app');
500
+
501
+ describe('Protected endpoint', () => {
502
+ it('should reject browsers', async () => {
503
+ const res = await request(app)
504
+ .get('/api/secret')
505
+ .set('User-Agent', 'Mozilla/5.0 Chrome/...');
506
+
507
+ expect(res.status).toBe(406);
508
+ expect(res.body.error).toBe('BIOLOGICAL_ENTITY_DETECTED');
509
+ });
510
+
511
+ it('should reject missing auth', async () => {
512
+ const res = await request(app)
513
+ .get('/api/secret')
514
+ .set('User-Agent', 'MyBot/1.0');
515
+
516
+ expect(res.status).toBe(428);
517
+ expect(res.body.error).toBe('AUTHENTICATION_REQUIRED');
518
+ });
519
+
520
+ it('should allow valid agents', async () => {
521
+ const res = await request(app)
522
+ .get('/api/secret')
523
+ .set('User-Agent', 'MyBot/1.0')
524
+ .set('X-Bio-Agent-Id', 'agent_test123')
525
+ .set('X-Bio-Token', 'valid_jwt_token');
526
+
527
+ expect(res.status).toBe(200);
528
+ expect(res.body.agent.id).toBe('agent_test123');
529
+ });
530
+
531
+ it('should include response headers', async () => {
532
+ const res = await request(app)
533
+ .get('/api/secret')
534
+ .set('User-Agent', 'MyBot/1.0')
535
+ .set('X-Bio-Agent-Id', 'agent_test123')
536
+ .set('X-Bio-Token', 'valid_jwt_token');
537
+
538
+ expect(res.headers['x-bio-verified']).toBe('true');
539
+ expect(res.headers['x-bio-agent-name']).toBe('MyAgent');
540
+ });
541
+ });
542
+ ```
543
+
544
+ ### Integration Test
545
+
546
+ ```bash
547
+ #!/bin/bash
548
+
549
+ # Test 1: Browser blocked
550
+ echo "Test 1: Block browser"
551
+ curl -v \
552
+ -H "User-Agent: Mozilla/5.0 Chrome/..." \
553
+ http://localhost:8080/api/secret
554
+ # Expected: 406
555
+
556
+ # Test 2: Missing auth
557
+ echo "Test 2: Missing auth"
558
+ curl -v \
559
+ -H "User-Agent: MyBot/1.0" \
560
+ http://localhost:8080/api/secret
561
+ # Expected: 428
562
+
563
+ # Test 3: Valid agent
564
+ echo "Test 3: Valid agent"
565
+ curl -v \
566
+ -H "User-Agent: MyBot/1.0" \
567
+ -H "X-Bio-Agent-Id: agent_test123" \
568
+ -H "X-Bio-Token: eyJhbGc..." \
569
+ http://localhost:8080/api/secret
570
+ # Expected: 200
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Troubleshooting
576
+
577
+ ### "Cannot connect to central API"
578
+
579
+ ```javascript
580
+ // Check API URL
581
+ const bioFirewall = new BioFirewall('http://localhost:3333');
582
+
583
+ // Verify API is running
584
+ curl http://localhost:3333/health
585
+
586
+ // Check firewall rules
587
+ # Allow traffic on 3333
588
+ ```
589
+
590
+ ### "Token always invalid"
591
+
592
+ ```javascript
593
+ // Ensure token signed with correct private key
594
+ const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });
595
+
596
+ // Verify agent is registered
597
+ curl http://localhost:3333/agents/agent_abc123
598
+
599
+ // Check token not expired (max 1 hour old)
600
+ ```
601
+
602
+ ### "Agents keep getting 406"
603
+
604
+ ```bash
605
+ # Check headers
606
+ curl -v \
607
+ -H "User-Agent: MyBot/1.0" \
608
+ -H "Accept: application/json" \
609
+ -H "X-Bio-Agent-Id: agent_xyz" \
610
+ -H "X-Bio-Token: ..." \
611
+ http://localhost:8080/api/secret
612
+
613
+ # Don't include:
614
+ # - "Mozilla" in User-Agent
615
+ # - "text/html" in Accept header
616
+ # - "Accept-Language" header
617
+ ```
618
+
619
+ ---
620
+
621
+ ## Complete Example App
622
+
623
+ ```javascript
624
+ const express = require('express');
625
+ const BioFirewall = require('biofirewall-client');
626
+
627
+ const app = express();
628
+
629
+ // Setup
630
+ const bioFirewall = new BioFirewall('http://localhost:3333');
631
+
632
+ // Middleware
633
+ app.use(express.json());
634
+
635
+ // Public route (no auth)
636
+ app.get('/', (req, res) => {
637
+ res.json({
638
+ service: 'Protected API',
639
+ status: 'online',
640
+ endpoints: {
641
+ public: ['GET /'],
642
+ protected: ['GET /api/secret', 'POST /api/data']
643
+ }
644
+ });
645
+ });
646
+
647
+ // Protected routes
648
+ app.get('/api/secret', bioFirewall, (req, res) => {
649
+ res.json({
650
+ message: 'Secret data',
651
+ agent: {
652
+ id: req.agent.id,
653
+ name: req.agent.name,
654
+ version: req.agent.version
655
+ }
656
+ });
657
+ });
658
+
659
+ app.post('/api/data', bioFirewall, (req, res) => {
660
+ res.json({
661
+ success: true,
662
+ message: 'Data received',
663
+ agent: req.agent.id,
664
+ data: req.body
665
+ });
666
+ });
667
+
668
+ // Error handler
669
+ app.use((err, req, res, next) => {
670
+ console.error(err);
671
+ res.status(500).json({
672
+ error: 'Internal server error'
673
+ });
674
+ });
675
+
676
+ // Start
677
+ const PORT = process.env.PORT || 8080;
678
+ app.listen(PORT, () => {
679
+ console.log(`🔒 Protected API running on port ${PORT}`);
680
+ console.log(` Central API: http://localhost:3333`);
681
+ });
682
+ ```
683
+
684
+ ---
685
+
686
+ ## Deployment
687
+
688
+ ### Docker
689
+
690
+ ```dockerfile
691
+ FROM node:18-alpine
692
+
693
+ WORKDIR /app
694
+
695
+ COPY package*.json ./
696
+ RUN npm install
697
+
698
+ COPY . .
699
+
700
+ ENV BIOFIREWALL_API=http://biofirewall-api:3333
701
+ ENV PORT=8080
702
+
703
+ EXPOSE 8080
704
+
705
+ CMD ["npm", "start"]
706
+ ```
707
+
708
+ ### Environment Variables
709
+
710
+ ```bash
711
+ BIOFIREWALL_API=http://localhost:3333
712
+ NODE_ENV=production
713
+ PORT=8080
714
+ ```
715
+
716
+ ---
717
+
718
+ ## Security Best Practices
719
+
720
+ ✅ **DO:**
721
+ - Use HTTPS in production
722
+ - Keep central API URL secret
723
+ - Monitor for unusual patterns
724
+ - Log authentication attempts
725
+ - Update middleware regularly
726
+ - Use caching (reduces API calls)
727
+
728
+ ❌ **DON'T:**
729
+ - Expose central API URL in client code
730
+ - Log tokens or agent secrets
731
+ - Disable browser detection
732
+ - Disable token verification
733
+ - Use old versions
734
+
735
+ ---
736
+
737
+ ## FAQ
738
+
739
+ **Q: Can I use biofirewall-client without central API?**
740
+ A: No. It requires a running central API for token verification.
741
+
742
+ **Q: How do I set up central API?**
743
+ A: See `/biofirewall-api/README.md` or `npm install biofirewall-api`.
744
+
745
+ **Q: Can I customize error messages?**
746
+ A: Yes, implement custom middleware before biofirewall.
747
+
748
+ **Q: How do I handle 404 from central API?**
749
+ A: Middleware will return 500. Ensure central API is reachable.
750
+
751
+ **Q: Can multiple services use same central API?**
752
+ A: Yes! That's the point. Central API is shared.
753
+
754
+ ---
126
755
 
127
- ## Status Codes
756
+ ## Support
128
757
 
129
- | Code | Meaning | Action |
130
- |------|---------|--------|
131
- | **200** | Access Granted | Proceed. |
132
- | **406** | Not Acceptable | You look like a human (Browser UA/Accept headers). Change headers. |
133
- | **428** | Precondition Required | Computation required. Solve the challenge in the body. |
134
- | **403** | Forbidden | Invalid solution provided. Check your math. |
758
+ - 📖 [biofirewall-api/SKILL.md](../biofirewall-api/SKILL.md) Agent registration guide
759
+ - 💓 [biofirewall-api/HEARTBEAT.md](../biofirewall-api/HEARTBEAT.md) — Agent activity routine
760
+ - 🏗️ [ARCHITECTURE.md](../ARCHITECTURE.md) System design
761
+ - 🔗 GitHub: https://github.com/openclaw/biofirewall
135
762
 
136
763
  ---
137
764
 
138
- *Verified Silicon Only. No biologicals allowed.* 🦞
765
+ *BioFirewall Client v3.0 | Protect your APIs. Verify silicon.* 🔒