@nordsym/apiclaw 1.5.16 ā 1.5.18
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/convex/http.js +196 -0
- package/convex/http.js.map +1 -1
- package/convex/http.ts +201 -0
- package/convex/http.ts.bak +934 -0
- package/dist/analytics.d.ts +0 -4
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +0 -1
- package/dist/analytics.js.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/cli/commands/mcp-install.d.ts.map +1 -1
- package/dist/cli/commands/mcp-install.js +8 -87
- package/dist/cli/commands/mcp-install.js.map +1 -1
- package/dist/cli/index.js +0 -7
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +0 -128
- package/dist/credentials.js.map +1 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +82 -191
- package/dist/discovery.js.map +1 -1
- package/dist/http-api.d.ts.map +1 -1
- package/dist/http-api.js +33 -17
- package/dist/http-api.js.map +1 -1
- package/dist/proxy.js +1 -1
- package/dist/proxy.js.map +1 -1
- package/landing/next-env.d.ts +0 -1
- package/landing/src/app/api/auth/magic-link/route.ts +1 -1
- package/landing/src/app/auth/verify/page.tsx +0 -6
- package/landing/src/app/dashboard/verify/page.tsx +0 -6
- package/landing/src/app/join/page.tsx +0 -6
- package/landing/src/app/layout.tsx +2 -2
- package/landing/src/app/login/page.tsx +1 -1
- package/landing/src/app/mou/[partnerId]/page.tsx +0 -6
- package/landing/src/app/page.tsx +18 -39
- package/landing/src/app/providers/dashboard/[apiId]/actions/[actionId]/edit/page.tsx +0 -6
- package/landing/src/app/providers/dashboard/[apiId]/actions/new/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/[apiId]/actions/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/[apiId]/direct-call/page.tsx +1 -6
- package/landing/src/app/providers/dashboard/[apiId]/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/[apiId]/test/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/layout.tsx +6 -6
- package/landing/src/app/providers/dashboard/login/page.tsx +1 -1
- package/landing/src/app/providers/dashboard/page.tsx +1 -1
- package/landing/src/app/providers/dashboard/verify/page.tsx +0 -6
- package/landing/src/app/providers/layout.tsx +1 -1
- package/landing/src/app/upgrade/page.tsx +0 -6
- package/landing/src/app/workspace/page.tsx +0 -6
- package/landing/src/components/HeroTabs.tsx +2 -2
- package/landing/src/components/{Workspace.tsx ā ProviderDashboard.tsx} +2 -2
- package/landing/src/components/VideoDemo.tsx +10 -21
- package/landing/src/lib/mock-data.ts +1 -1
- package/landing/src/lib/stats.json +1 -1
- package/package.json +4 -6
- package/src/analytics.ts +0 -5
- package/src/bin.ts +1 -1
- package/src/cli/commands/mcp-install.ts +8 -90
- package/src/cli/index.ts +0 -8
- package/src/credentials.ts +0 -136
- package/src/discovery.ts +82 -191
- package/src/http-api.ts +34 -18
- package/src/proxy.ts +1 -1
- package/APILAYER_STATUS_2026-03-24.md +0 -38
- package/CHANGELOG-WHITELIST-V2.md +0 -269
- package/HIVR-WHITELIST-STATUS.md +0 -205
- package/HIVR-WHITELIST.md +0 -148
- package/TERMINOLOGY-AUDIT.md +0 -99
- package/TERMINOLOGY-FIXED.md +0 -74
- package/VIDEO-DEMO-GUIDE.md +0 -82
- package/WHITELIST-ARCHITECTURE.md +0 -379
- package/api/discover.ts +0 -71
- package/api/health.ts +0 -20
- package/direct-test.mjs +0 -51
- package/dist/access-control.d.ts +0 -45
- package/dist/access-control.d.ts.map +0 -1
- package/dist/access-control.js +0 -142
- package/dist/access-control.js.map +0 -1
- package/dist/chain-types.d.ts +0 -187
- package/dist/chain-types.d.ts.map +0 -1
- package/dist/chain-types.js +0 -33
- package/dist/chain-types.js.map +0 -1
- package/dist/convex/adminActivate.js +0 -46
- package/dist/convex/adminStats.js +0 -41
- package/dist/convex/agents.js +0 -498
- package/dist/convex/analytics.js +0 -165
- package/dist/convex/billing.js +0 -654
- package/dist/convex/capabilities.js +0 -144
- package/dist/convex/chains.js +0 -1041
- package/dist/convex/credits.js +0 -185
- package/dist/convex/crons.js +0 -16
- package/dist/convex/directCall.js +0 -626
- package/dist/convex/earnProgress.js +0 -648
- package/dist/convex/email.js +0 -299
- package/dist/convex/feedback.js +0 -226
- package/dist/convex/http.js +0 -909
- package/dist/convex/logs.js +0 -486
- package/dist/convex/mou.js +0 -81
- package/dist/convex/providerKeys.js +0 -256
- package/dist/convex/providers.js +0 -755
- package/dist/convex/purchases.js +0 -156
- package/dist/convex/ratelimit.js +0 -90
- package/dist/convex/schema.js +0 -709
- package/dist/convex/searchLogs.js +0 -128
- package/dist/convex/spendAlerts.js +0 -379
- package/dist/convex/stripeActions.js +0 -410
- package/dist/convex/teams.js +0 -214
- package/dist/convex/telemetry.js +0 -73
- package/dist/convex/usage.js +0 -228
- package/dist/convex/waitlist.js +0 -48
- package/dist/convex/webhooks.js +0 -409
- package/dist/convex/workspaces.js +0 -879
- package/dist/hivr-whitelist.d.ts +0 -18
- package/dist/hivr-whitelist.d.ts.map +0 -1
- package/dist/hivr-whitelist.js +0 -95
- package/dist/hivr-whitelist.js.map +0 -1
- package/dist/http-server-minimal.d.ts +0 -7
- package/dist/http-server-minimal.d.ts.map +0 -1
- package/dist/http-server-minimal.js +0 -126
- package/dist/http-server-minimal.js.map +0 -1
- package/dist/product-whitelist.d.ts +0 -37
- package/dist/product-whitelist.d.ts.map +0 -1
- package/dist/product-whitelist.js +0 -203
- package/dist/product-whitelist.js.map +0 -1
- package/dist/src/analytics.js +0 -129
- package/dist/src/bin.js +0 -17
- package/dist/src/capability-router.js +0 -240
- package/dist/src/chainExecutor.js +0 -451
- package/dist/src/chainResolver.js +0 -518
- package/dist/src/cli/commands/doctor.js +0 -324
- package/dist/src/cli/commands/mcp-install.js +0 -255
- package/dist/src/cli/commands/restore.js +0 -259
- package/dist/src/cli/commands/setup.js +0 -205
- package/dist/src/cli/commands/uninstall.js +0 -188
- package/dist/src/cli/index.js +0 -111
- package/dist/src/cli.js +0 -302
- package/dist/src/confirmation.js +0 -240
- package/dist/src/credentials.js +0 -357
- package/dist/src/credits.js +0 -260
- package/dist/src/crypto.js +0 -66
- package/dist/src/discovery.js +0 -504
- package/dist/src/enterprise/env.js +0 -123
- package/dist/src/enterprise/script-generator.js +0 -460
- package/dist/src/execute-dynamic.js +0 -473
- package/dist/src/execute.js +0 -1727
- package/dist/src/index.js +0 -2062
- package/dist/src/metered.js +0 -80
- package/dist/src/open-apis.js +0 -276
- package/dist/src/proxy.js +0 -28
- package/dist/src/session.js +0 -86
- package/dist/src/stripe.js +0 -407
- package/dist/src/telemetry.js +0 -49
- package/dist/src/types.js +0 -2
- package/dist/src/utils/backup.js +0 -181
- package/dist/src/utils/config.js +0 -220
- package/dist/src/utils/os.js +0 -105
- package/dist/src/utils/paths.js +0 -159
- package/landing/pages/api/discover.ts +0 -43
- package/landing/pages/api/health.ts +0 -20
- package/scripts/test-whitelist-v2.sh +0 -128
- package/src/access-control.ts +0 -174
- package/src/hivr-whitelist.ts +0 -110
- package/src/http-server-minimal.ts +0 -154
- package/src/product-whitelist.ts +0 -246
- package/test-actual-handlers.ts +0 -92
- package/test-apilayer-all-14.ts +0 -249
- package/test-apilayer-fixed.ts +0 -248
- package/test-direct-endpoints.ts +0 -174
- package/test-exact-endpoints.ts +0 -144
- package/test-final.ts +0 -83
- package/test-full-routing.ts +0 -100
- package/test-handlers-correct.ts +0 -217
- package/test-numverify-key.ts +0 -41
- package/test-via-handlers.ts +0 -92
- package/test-worldnews.mjs +0 -26
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
# APIClaw Multi-Product Whitelist Architecture
|
|
2
|
-
|
|
3
|
-
**Version:** 2.0
|
|
4
|
-
**Date:** 2026-03-18
|
|
5
|
-
**Status:** Production Ready
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
APIClaw supports multiple products (Hivr, NordSym, partners) accessing Direct Call APIs via HTTP endpoints with:
|
|
12
|
-
- **Product-namespaced agentIds** (`product:agentName`)
|
|
13
|
-
- **Per-provider access control** (some products get certain APIs only)
|
|
14
|
-
- **Dynamic whitelist syncing** from product Convex deployments
|
|
15
|
-
- **Per-product analytics** tracking
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Architecture
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
23
|
-
ā Products ā
|
|
24
|
-
ā āāāāāāāāāāāā āāāāāāāāāāāā āāāāāāāāāāāā ā
|
|
25
|
-
ā ā Hivr ā ā NordSym ā āPartner X ā ā
|
|
26
|
-
ā ā Convex ā ā Convex ā ā Convex ā ā
|
|
27
|
-
ā āāāāāāā¬āāāāā āāāāāāā¬āāāāā āāāāāāā¬āāāāā ā
|
|
28
|
-
āāāāāāāāāā¼āāāāāāāāāāāāāā¼āāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāā
|
|
29
|
-
ā ā ā
|
|
30
|
-
ā agents:list ā team:list ā agents:list
|
|
31
|
-
ā ā ā
|
|
32
|
-
āāāāāāāāāāāāāāā“āāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāā
|
|
33
|
-
ā
|
|
34
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
|
|
35
|
-
ā APIClaw Product Whitelist ā
|
|
36
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
|
|
37
|
-
ā ā product-whitelist.ts ā ā
|
|
38
|
-
ā ā - Fetch from multiple Convex sources ā ā
|
|
39
|
-
ā ā - Cache per product (5 min TTL) ā ā
|
|
40
|
-
ā ā - Namespace: product:agentId ā ā
|
|
41
|
-
ā ā - Fallback to static whitelist ā ā
|
|
42
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
|
|
43
|
-
ā ā
|
|
44
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
|
|
45
|
-
ā ā access-control.ts ā ā
|
|
46
|
-
ā ā - Per-provider permissions ā ā
|
|
47
|
-
ā ā - Pattern matching (hivr:*, nordsym:*) ā ā
|
|
48
|
-
ā ā - Deny by default ā ā
|
|
49
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
|
|
50
|
-
ā ā
|
|
51
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
|
|
52
|
-
ā ā http-api.ts ā ā
|
|
53
|
-
ā ā - /api/discover?agentId=hivr:bytebee ā ā
|
|
54
|
-
ā ā - POST /api/call_api { agentId, provider, ... } ā ā
|
|
55
|
-
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
|
|
56
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
57
|
-
ā
|
|
58
|
-
ā Logs usage
|
|
59
|
-
ā¼
|
|
60
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
61
|
-
ā Analytics ā
|
|
62
|
-
ā - Product-level tracking ā
|
|
63
|
-
ā - Per-agent usage ā
|
|
64
|
-
ā - Provider access logs ā
|
|
65
|
-
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Product Configuration
|
|
71
|
-
|
|
72
|
-
**File:** `src/product-whitelist.ts`
|
|
73
|
-
|
|
74
|
-
### Adding a New Product
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
const PRODUCT_SOURCES: ProductSource[] = [
|
|
78
|
-
{
|
|
79
|
-
name: 'hivr',
|
|
80
|
-
convexUrl: 'https://sensible-quail-275.convex.cloud',
|
|
81
|
-
queryPath: 'agents:list',
|
|
82
|
-
agentIdField: 'agentId',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'nordsym',
|
|
86
|
-
convexUrl: 'https://nordsym-deployment.convex.cloud',
|
|
87
|
-
queryPath: 'team:listAgents',
|
|
88
|
-
agentIdField: 'memberId',
|
|
89
|
-
authToken: process.env.NORDSYM_API_TOKEN, // Optional
|
|
90
|
-
},
|
|
91
|
-
];
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Fields:**
|
|
95
|
-
- `name` ā Product identifier (used in namespace)
|
|
96
|
-
- `convexUrl` ā Convex deployment URL
|
|
97
|
-
- `queryPath` ā Convex query function path
|
|
98
|
-
- `agentIdField` ā Field name for agent identifier
|
|
99
|
-
- `authToken` ā Optional Bearer token for auth
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Access Control Rules
|
|
104
|
-
|
|
105
|
-
**File:** `src/access-control.ts`
|
|
106
|
-
|
|
107
|
-
### Rule Format
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
interface AccessRule {
|
|
111
|
-
agentPattern: string; // e.g., "hivr:*", "nordsym:mollebot"
|
|
112
|
-
allowedProviders: string[]; // e.g., ["*"], ["brave_search", "groq"]
|
|
113
|
-
description?: string;
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Default Rules
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
const DEFAULT_RULES: AccessRule[] = [
|
|
121
|
-
{
|
|
122
|
-
agentPattern: 'hivr:*',
|
|
123
|
-
allowedProviders: ['*'], // All providers
|
|
124
|
-
description: 'Hivr bees get full access',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
agentPattern: 'nordsym:*',
|
|
128
|
-
allowedProviders: ['brave_search', 'groq', 'replicate'],
|
|
129
|
-
description: 'NordSym team gets selected providers',
|
|
130
|
-
},
|
|
131
|
-
];
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Pattern Matching
|
|
135
|
-
|
|
136
|
-
- `hivr:*` ā All Hivr agents
|
|
137
|
-
- `hivr:bytebee` ā Specific agent
|
|
138
|
-
- `nordsym:molle*` ā Prefix match
|
|
139
|
-
|
|
140
|
-
### Provider Wildcards
|
|
141
|
-
|
|
142
|
-
- `*` ā All providers
|
|
143
|
-
- `brave_*` ā All Brave providers
|
|
144
|
-
- `["brave_search", "groq"]` ā Specific list
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Usage Examples
|
|
149
|
-
|
|
150
|
-
### HTTP API Request (Namespaced)
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
curl -X POST "https://apiclaw.com/api/call_api" \
|
|
154
|
-
-H "Content-Type: application/json" \
|
|
155
|
-
-d '{
|
|
156
|
-
"agentId": "hivr:bytebee",
|
|
157
|
-
"provider": "brave_search",
|
|
158
|
-
"action": "search",
|
|
159
|
-
"params": {"query": "AI news"}
|
|
160
|
-
}'
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### HTTP API Request (Legacy)
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
# Legacy format (no namespace) still works
|
|
167
|
-
curl -X POST "https://apiclaw.com/api/call_api" \
|
|
168
|
-
-H "Content-Type: application/json" \
|
|
169
|
-
-d '{
|
|
170
|
-
"agentId": "bytebee",
|
|
171
|
-
"provider": "brave_search",
|
|
172
|
-
"action": "search",
|
|
173
|
-
"params": {"query": "AI news"}
|
|
174
|
-
}'
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Discovery Endpoint
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
curl "https://apiclaw.com/api/discover?query=web+search&agentId=hivr:bytebee"
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Security Model
|
|
186
|
-
|
|
187
|
-
### 1. Whitelist Check
|
|
188
|
-
- Agent must exist in product's Convex deployment
|
|
189
|
-
- Fetched dynamically (cached 5 min)
|
|
190
|
-
- Fallback to static list if all sources fail
|
|
191
|
-
|
|
192
|
-
### 2. Access Control
|
|
193
|
-
- Per-provider permissions checked
|
|
194
|
-
- Pattern-based rules (`hivr:*`, `nordsym:mollebot`)
|
|
195
|
-
- Deny by default
|
|
196
|
-
|
|
197
|
-
### 3. Response on Denial
|
|
198
|
-
|
|
199
|
-
```json
|
|
200
|
-
{
|
|
201
|
-
"error": "Access Denied",
|
|
202
|
-
"message": "Provider not in access list",
|
|
203
|
-
"hint": "Contact admin@nordsym.com for access"
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## Analytics Tracking
|
|
210
|
-
|
|
211
|
-
**Product-level metrics tracked:**
|
|
212
|
-
- Total calls per product
|
|
213
|
-
- Per-agent usage within product
|
|
214
|
-
- Provider access patterns
|
|
215
|
-
- Success/error rates
|
|
216
|
-
- Latency per product
|
|
217
|
-
|
|
218
|
-
**Log format:**
|
|
219
|
-
```jsonl
|
|
220
|
-
{
|
|
221
|
-
"timestamp": "2026-03-18T16:00:00.000Z",
|
|
222
|
-
"provider": "brave_search",
|
|
223
|
-
"action": "search",
|
|
224
|
-
"type": "direct",
|
|
225
|
-
"userId": "hivr:bytebee",
|
|
226
|
-
"success": true,
|
|
227
|
-
"latencyMs": 150,
|
|
228
|
-
"metadata": {
|
|
229
|
-
"product": "hivr"
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Cache Management
|
|
237
|
-
|
|
238
|
-
### Per-Product Caching
|
|
239
|
-
- Each product cached separately
|
|
240
|
-
- TTL: 5 minutes
|
|
241
|
-
- Parallel fetches from all sources
|
|
242
|
-
|
|
243
|
-
### Manual Invalidation
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
import { invalidateCache } from './product-whitelist.js';
|
|
247
|
-
|
|
248
|
-
// Invalidate specific product
|
|
249
|
-
invalidateCache('hivr');
|
|
250
|
-
|
|
251
|
-
// Invalidate all
|
|
252
|
-
invalidateCache();
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Error Handling
|
|
258
|
-
|
|
259
|
-
### Product Source Down
|
|
260
|
-
|
|
261
|
-
- Other products continue working
|
|
262
|
-
- Falls back to static whitelist if ALL sources fail
|
|
263
|
-
- Logs warning, no crash
|
|
264
|
-
|
|
265
|
-
### Partial Failures
|
|
266
|
-
|
|
267
|
-
```
|
|
268
|
-
[Whitelist] hivr: Fetched 12 agents
|
|
269
|
-
[Whitelist] nordsym: HTTP 500
|
|
270
|
-
[Whitelist] Total agents: 12 (1 source failed)
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Migration Guide
|
|
276
|
-
|
|
277
|
-
### From v1 (Hivr-only) to v2 (Multi-product)
|
|
278
|
-
|
|
279
|
-
**Old code:**
|
|
280
|
-
```typescript
|
|
281
|
-
const authorized = await isAuthorized('bytebee');
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
**New code:**
|
|
285
|
-
```typescript
|
|
286
|
-
const authorized = await isAuthorized('hivr:bytebee');
|
|
287
|
-
// OR legacy format still works
|
|
288
|
-
const authorized = await isAuthorized('bytebee');
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Breaking changes:** None (backward compatible)
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
## Testing
|
|
296
|
-
|
|
297
|
-
### Local Test
|
|
298
|
-
|
|
299
|
-
```bash
|
|
300
|
-
# Start HTTP API
|
|
301
|
-
npm run start:http
|
|
302
|
-
|
|
303
|
-
# Test whitelisted agent
|
|
304
|
-
curl "http://localhost:3000/api/discover?query=web&agentId=hivr:bytebee"
|
|
305
|
-
# ā 200 OK
|
|
306
|
-
|
|
307
|
-
# Test unauthorized agent
|
|
308
|
-
curl "http://localhost:3000/api/discover?query=web&agentId=hacker:evil"
|
|
309
|
-
# ā 403 Access Denied
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Test Access Control
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
# Hivr bee accessing allowed provider
|
|
316
|
-
curl -X POST "http://localhost:3000/api/call_api" \
|
|
317
|
-
-d '{"agentId":"hivr:bytebee","provider":"brave_search","action":"search","params":{}}'
|
|
318
|
-
# ā 200 OK
|
|
319
|
-
|
|
320
|
-
# NordSym accessing restricted provider (if not in allowlist)
|
|
321
|
-
curl -X POST "http://localhost:3000/api/call_api" \
|
|
322
|
-
-d '{"agentId":"nordsym:bot","provider":"restricted_api","action":"call","params":{}}'
|
|
323
|
-
# ā 403 Provider not in access list
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Future Enhancements
|
|
329
|
-
|
|
330
|
-
### Planned
|
|
331
|
-
- [ ] Convex table for access rules (dynamic updates)
|
|
332
|
-
- [ ] Webhook triggers when new agent added (instant sync)
|
|
333
|
-
- [ ] Per-agent rate limits
|
|
334
|
-
- [ ] Usage quotas per product
|
|
335
|
-
- [ ] Admin UI for whitelist management
|
|
336
|
-
|
|
337
|
-
### Possible
|
|
338
|
-
- [ ] Geographic restrictions
|
|
339
|
-
- [ ] Time-based access windows
|
|
340
|
-
- [ ] Cost allocation per product
|
|
341
|
-
- [ ] Audit logs
|
|
342
|
-
|
|
343
|
-
---
|
|
344
|
-
|
|
345
|
-
## Troubleshooting
|
|
346
|
-
|
|
347
|
-
### New agent not authorized immediately
|
|
348
|
-
**Solution:** Wait 5 minutes (cache TTL) or restart APIClaw HTTP server
|
|
349
|
-
|
|
350
|
-
### All agents unauthorized
|
|
351
|
-
**Check:**
|
|
352
|
-
1. Product source Convex URL correct?
|
|
353
|
-
2. Query path returns array?
|
|
354
|
-
3. agentIdField matches response structure?
|
|
355
|
-
|
|
356
|
-
**Debug:**
|
|
357
|
-
```bash
|
|
358
|
-
# Check logs
|
|
359
|
-
tail -f ~/.apiclaw/logs/api-calls.jsonl | grep whitelist
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
### Access denied despite whitelist
|
|
363
|
-
**Check:**
|
|
364
|
-
1. Is provider in access rules?
|
|
365
|
-
2. Does pattern match agentId?
|
|
366
|
-
3. Check logs for reason
|
|
367
|
-
|
|
368
|
-
---
|
|
369
|
-
|
|
370
|
-
## Contact
|
|
371
|
-
|
|
372
|
-
**Questions:** admin@nordsym.com
|
|
373
|
-
**Issues:** GitHub issues (APIClaw repo)
|
|
374
|
-
**Docs:** https://apiclaw.com/docs/whitelist
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
**Last updated:** 2026-03-18
|
|
379
|
-
**Architecture version:** 2.0
|
package/api/discover.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* APIClaw Discovery API - Vercel Serverless Function
|
|
3
|
-
* GET /api/discover?query=...&agentId=...
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|
7
|
-
import { isAuthorized, getProduct } from '../dist/product-whitelist.js';
|
|
8
|
-
import { discoverAPIs } from '../dist/discovery.js';
|
|
9
|
-
import { logAPICall } from '../dist/analytics.js';
|
|
10
|
-
|
|
11
|
-
export default async function handler(
|
|
12
|
-
req: VercelRequest,
|
|
13
|
-
res: VercelResponse
|
|
14
|
-
) {
|
|
15
|
-
// CORS
|
|
16
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
17
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
|
18
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Agent-Id');
|
|
19
|
-
|
|
20
|
-
if (req.method === 'OPTIONS') {
|
|
21
|
-
return res.status(200).end();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (req.method !== 'GET') {
|
|
25
|
-
return res.status(405).json({ error: 'Method not allowed' });
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const { query, agentId, category, maxResults } = req.query;
|
|
29
|
-
|
|
30
|
-
if (!query || typeof query !== 'string') {
|
|
31
|
-
return res.status(400).json({ error: 'Missing query parameter' });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const agentIdStr = typeof agentId === 'string' ? agentId : undefined;
|
|
35
|
-
|
|
36
|
-
if (!(await isAuthorized(agentIdStr))) {
|
|
37
|
-
return res.status(403).json({
|
|
38
|
-
error: 'Unauthorized',
|
|
39
|
-
message: 'This endpoint is restricted. Contact admin@nordsym.com',
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const startTime = Date.now();
|
|
44
|
-
const results = discoverAPIs(query, {
|
|
45
|
-
category: typeof category === 'string' ? category : undefined,
|
|
46
|
-
maxResults: typeof maxResults === 'string' ? parseInt(maxResults) : 5,
|
|
47
|
-
});
|
|
48
|
-
const responseTimeMs = Date.now() - startTime;
|
|
49
|
-
|
|
50
|
-
// Log to analytics
|
|
51
|
-
const product = agentIdStr ? getProduct(agentIdStr) : null;
|
|
52
|
-
logAPICall({
|
|
53
|
-
timestamp: new Date().toISOString(),
|
|
54
|
-
provider: 'apiclaw_discovery',
|
|
55
|
-
action: 'discover',
|
|
56
|
-
type: 'open',
|
|
57
|
-
userId: agentIdStr || 'unknown',
|
|
58
|
-
success: true,
|
|
59
|
-
latencyMs: responseTimeMs,
|
|
60
|
-
metadata: product ? { product } : undefined,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
return res.status(200).json({
|
|
64
|
-
success: true,
|
|
65
|
-
query,
|
|
66
|
-
agentId: agentIdStr,
|
|
67
|
-
product,
|
|
68
|
-
results,
|
|
69
|
-
responseTimeMs,
|
|
70
|
-
});
|
|
71
|
-
}
|
package/api/health.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* APIClaw Health Check - Vercel Serverless Function
|
|
3
|
-
* GET /api/health
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|
7
|
-
|
|
8
|
-
export default async function handler(
|
|
9
|
-
req: VercelRequest,
|
|
10
|
-
res: VercelResponse
|
|
11
|
-
) {
|
|
12
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
13
|
-
|
|
14
|
-
return res.status(200).json({
|
|
15
|
-
status: 'ok',
|
|
16
|
-
service: 'apiclaw-http-api',
|
|
17
|
-
version: '2.0.0',
|
|
18
|
-
timestamp: new Date().toISOString(),
|
|
19
|
-
});
|
|
20
|
-
}
|
package/direct-test.mjs
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { executeAPICall } from './dist/execute.js';
|
|
2
|
-
|
|
3
|
-
const tests = [
|
|
4
|
-
'exchange_rates', 'market_data', 'aviation', 'pdf_generate',
|
|
5
|
-
'screenshot', 'verify_email', 'verify_number', 'vat_check',
|
|
6
|
-
'world_news', 'finance_news', 'scrape', 'image_crop',
|
|
7
|
-
'skills', 'form_submit'
|
|
8
|
-
];
|
|
9
|
-
|
|
10
|
-
const params = {
|
|
11
|
-
exchange_rates: { base: 'USD', symbols: 'EUR' },
|
|
12
|
-
market_data: { symbols: 'AAPL' },
|
|
13
|
-
aviation: { flight_iata: 'AA100' },
|
|
14
|
-
pdf_generate: { document_url: 'https://example.com' },
|
|
15
|
-
screenshot: { url: 'https://example.com' },
|
|
16
|
-
verify_email: { email: 'test@example.com' },
|
|
17
|
-
verify_number: { number: '+14158586273' },
|
|
18
|
-
vat_check: { vat_number: 'LU26375245' },
|
|
19
|
-
world_news: { url: 'https://example.com/news' },
|
|
20
|
-
finance_news: { tickers: 'AAPL' },
|
|
21
|
-
scrape: { url: 'https://example.com' },
|
|
22
|
-
image_crop: { url: 'https://example.com/img.jpg', width: '200' },
|
|
23
|
-
skills: { q: 'javascript' },
|
|
24
|
-
form_submit: { endpoint: 'test', data: {} }
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
let working = 0, blocked = 0;
|
|
28
|
-
|
|
29
|
-
console.log('š¬ Testing all 14 APILayer services...\n');
|
|
30
|
-
|
|
31
|
-
for (const action of tests) {
|
|
32
|
-
try {
|
|
33
|
-
const result = await executeAPICall('apilayer', action, params[action]);
|
|
34
|
-
|
|
35
|
-
if (result.success) {
|
|
36
|
-
console.log(`ā
${action}`);
|
|
37
|
-
working++;
|
|
38
|
-
} else {
|
|
39
|
-
const errMsg = result.error || result.message || 'Failed';
|
|
40
|
-
console.log(`ā ${action}: ${errMsg.substring(0, 60)}`);
|
|
41
|
-
blocked++;
|
|
42
|
-
}
|
|
43
|
-
} catch (e) {
|
|
44
|
-
console.log(`ā ${action}: ${e.message.substring(0, 60)}`);
|
|
45
|
-
blocked++;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
console.log(`\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);
|
|
50
|
-
console.log(`š FAKTISKA SIFFROR: ${working}/14 working, ${blocked}/14 blocked`);
|
|
51
|
-
console.log(`āāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n`);
|
package/dist/access-control.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Access Control System
|
|
3
|
-
* Controls which products/agents can access which providers
|
|
4
|
-
*
|
|
5
|
-
* Rules format:
|
|
6
|
-
* - Wildcard: "hivr:*" = all Hivr agents
|
|
7
|
-
* - Specific: "hivr:bytebee" = only ByteBee
|
|
8
|
-
* - Product-level: "nordsym:*" = all NordSym agents
|
|
9
|
-
*
|
|
10
|
-
* Provider wildcards:
|
|
11
|
-
* - "*" = all providers
|
|
12
|
-
* - "brave_*" = all Brave providers
|
|
13
|
-
* - Specific: ["brave_search", "groq"]
|
|
14
|
-
*/
|
|
15
|
-
interface AccessRule {
|
|
16
|
-
agentPattern: string;
|
|
17
|
-
allowedProviders: string[];
|
|
18
|
-
description?: string;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Check if agentId is allowed to access provider
|
|
22
|
-
*/
|
|
23
|
-
export declare function canAccessProvider(agentId: string, provider: string): boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Get allowed providers for agentId
|
|
26
|
-
*/
|
|
27
|
-
export declare function getAllowedProviders(agentId: string): string[];
|
|
28
|
-
/**
|
|
29
|
-
* Add new access rule (runtime)
|
|
30
|
-
*/
|
|
31
|
-
export declare function addAccessRule(rule: AccessRule): void;
|
|
32
|
-
/**
|
|
33
|
-
* Get all access rules (for debugging/admin)
|
|
34
|
-
*/
|
|
35
|
-
export declare function getAccessRules(): AccessRule[];
|
|
36
|
-
/**
|
|
37
|
-
* Check if agentId + provider combination is allowed
|
|
38
|
-
* Combines whitelist check + access control
|
|
39
|
-
*/
|
|
40
|
-
export declare function isAllowed(agentId: string | undefined, provider: string): Promise<{
|
|
41
|
-
allowed: boolean;
|
|
42
|
-
reason?: string;
|
|
43
|
-
}>;
|
|
44
|
-
export {};
|
|
45
|
-
//# sourceMappingURL=access-control.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"access-control.d.ts","sourceRoot":"","sources":["../src/access-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,UAAU,UAAU;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4DD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAyB5E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAe7D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAIpD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAE7C;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBhD"}
|