@dupecom/botcha 0.20.0 → 0.20.2
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
|
@@ -58,34 +58,45 @@ pip install botcha
|
|
|
58
58
|
|
|
59
59
|
## Quick Start
|
|
60
60
|
|
|
61
|
-
###
|
|
61
|
+
### Protect Your API (Server-Side)
|
|
62
62
|
|
|
63
63
|
```typescript
|
|
64
64
|
import express from 'express';
|
|
65
|
-
import {
|
|
65
|
+
import { botchaVerify } from '@dupecom/botcha-verify/express';
|
|
66
66
|
|
|
67
67
|
const app = express();
|
|
68
68
|
|
|
69
|
-
//
|
|
70
|
-
app.
|
|
71
|
-
|
|
69
|
+
// Verify tokens via JWKS - no shared secret needed!
|
|
70
|
+
app.use('/api', botchaVerify({
|
|
71
|
+
jwksUrl: 'https://botcha.ai/.well-known/jwks',
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
app.get('/api/data', (req, res) => {
|
|
75
|
+
res.json({ message: 'Welcome, verified AI agent! 🤖' });
|
|
72
76
|
});
|
|
73
77
|
|
|
74
78
|
app.listen(3000);
|
|
75
79
|
```
|
|
76
80
|
|
|
77
|
-
###
|
|
81
|
+
### Access Protected APIs (Agent-Side)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { BotchaClient } from '@dupecom/botcha/client';
|
|
78
85
|
|
|
86
|
+
const client = new BotchaClient();
|
|
87
|
+
|
|
88
|
+
// Automatically solves challenges and includes tokens
|
|
89
|
+
const response = await client.fetch('https://api.example.com/api/data');
|
|
90
|
+
const data = await response.json();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Python:**
|
|
79
94
|
```python
|
|
80
|
-
from botcha import BotchaClient
|
|
95
|
+
from botcha import BotchaClient
|
|
81
96
|
|
|
82
|
-
# Client SDK for AI agents
|
|
83
97
|
async with BotchaClient() as client:
|
|
84
|
-
#
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# Or auto-solve and fetch protected endpoints
|
|
88
|
-
response = await client.fetch("https://api.example.com/agent-only")
|
|
98
|
+
# Automatically solves challenges and includes tokens
|
|
99
|
+
response = await client.fetch("https://api.example.com/api/data")
|
|
89
100
|
data = await response.json()
|
|
90
101
|
```
|
|
91
102
|
|
|
@@ -925,7 +936,7 @@ You can use the library freely, report issues, and discuss features. To contribu
|
|
|
925
936
|
|
|
926
937
|
## Server-Side Verification (for API Providers)
|
|
927
938
|
|
|
928
|
-
If you're building an API that accepts BOTCHA tokens from agents, use the verification SDKs. **BOTCHA
|
|
939
|
+
If you're building an API that accepts BOTCHA tokens from agents, use the verification SDKs. **BOTCHA signs tokens with ES256 (asymmetric)** — verify them using the public JWKS endpoint. No shared secret needed.
|
|
929
940
|
|
|
930
941
|
### JWKS Verification (Recommended)
|
|
931
942
|
|
package/dist/lib/client/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
// SDK version - hardcoded since npm_package_version is unreliable when used as a library
|
|
3
|
-
const SDK_VERSION = '0.20.
|
|
3
|
+
const SDK_VERSION = '0.20.2';
|
|
4
4
|
// Export stream client
|
|
5
5
|
export { BotchaStreamClient } from './stream.js';
|
|
6
6
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tap-enhanced-verify.d.ts","sourceRoot":"","sources":["../../../src/middleware/tap-enhanced-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAoB1D,MAAM,WAAW,gBAAgB;IAE/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAGlD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAG/B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,UAAU,CAAC,EAAE,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"tap-enhanced-verify.d.ts","sourceRoot":"","sources":["../../../src/middleware/tap-enhanced-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAoB1D,MAAM,WAAW,gBAAgB;IAE/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAGlD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAG/B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAsBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,gBAAqB,IAGhD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,wDAqE9D;AAgTD,eAAO,MAAM,cAAc;IACzB;;OAEG;uBACe,OAAO,CAAC,gBAAgB,CAAC,WAzXxB,OAAO,OAAO,QAAQ,QAAQ,YAAY;IAgY7D;;OAEG;yBACiB,OAAO,CAAC,gBAAgB,CAAC,WAnY1B,OAAO,OAAO,QAAQ,QAAQ,YAAY;IA0Y7D;;OAEG;8BACsB,OAAO,CAAC,gBAAgB,CAAC,WA7Y/B,OAAO,OAAO,QAAQ,QAAQ,YAAY;IAoZ7D;;OAEG;4BACoB,OAAO,CAAC,gBAAgB,CAAC,WAvZ7B,OAAO,OAAO,QAAQ,QAAQ,YAAY;CA8Z9D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,0BAAoB,CAAC;AAE3D,eAAe,iBAAiB,CAAC"}
|
|
@@ -122,7 +122,7 @@ async function performFullTAPVerification(req, opts) {
|
|
|
122
122
|
}
|
|
123
123
|
const agent = agentResult.agent;
|
|
124
124
|
// Verify cryptographic signature
|
|
125
|
-
const cryptoResult = await verifyCryptographicSignature(req, agent);
|
|
125
|
+
const cryptoResult = await verifyCryptographicSignature(req, agent, opts);
|
|
126
126
|
// Verify computational challenge
|
|
127
127
|
const challengeResult = await verifyComputationalChallenge(req);
|
|
128
128
|
// Both must pass for full TAP
|
|
@@ -183,7 +183,7 @@ async function performSignatureOnlyVerification(req, opts) {
|
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
185
|
// Verify signature
|
|
186
|
-
const cryptoResult = await verifyCryptographicSignature(req, agentResult.agent);
|
|
186
|
+
const cryptoResult = await verifyCryptographicSignature(req, agentResult.agent, opts);
|
|
187
187
|
return {
|
|
188
188
|
verified: cryptoResult.valid,
|
|
189
189
|
agent_id: agentResult.agent.agent_id,
|
|
@@ -240,7 +240,7 @@ async function handleVerificationFallback(req, opts, mode) {
|
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
242
|
// ============ HELPER FUNCTIONS ============
|
|
243
|
-
async function verifyCryptographicSignature(req, agent) {
|
|
243
|
+
async function verifyCryptographicSignature(req, agent, opts) {
|
|
244
244
|
if (!agent.public_key || !agent.signature_algorithm) {
|
|
245
245
|
return { valid: false, error: 'Agent has no cryptographic key configured' };
|
|
246
246
|
}
|
|
@@ -250,7 +250,7 @@ async function verifyCryptographicSignature(req, agent) {
|
|
|
250
250
|
headers: req.headers,
|
|
251
251
|
body: typeof req.body === 'string' ? req.body : JSON.stringify(req.body)
|
|
252
252
|
};
|
|
253
|
-
return await verifyHTTPMessageSignature(verificationRequest, agent.public_key, agent.signature_algorithm);
|
|
253
|
+
return await verifyHTTPMessageSignature(verificationRequest, agent.public_key, agent.signature_algorithm, opts.noncesKV || null);
|
|
254
254
|
}
|
|
255
255
|
async function verifyComputationalChallenge(req) {
|
|
256
256
|
const challengeId = req.headers['x-botcha-challenge-id'];
|