agent-auth-broker 0.0.8 → 0.0.9
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 +310 -310
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
1
|
# Agent Auth Broker
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
[中文](README-zh.md)
|
|
4
4
|
|
|
5
|
-
AI
|
|
5
|
+
A centralized credential management and authorization proxy for AI Agents. Agents never hold any API keys or OAuth tokens directly. Instead, they call the Broker, which handles permission enforcement, credential injection, execution, and audit logging.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Architecture
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
Agent
|
|
12
|
+
AI Agent (Claude / OpenClaw / etc.)
|
|
13
13
|
|
|
|
14
14
|
| broker_call(connector, action, params)
|
|
15
15
|
v
|
|
16
16
|
MCP Server
|
|
17
17
|
|
|
|
18
|
-
|
|
|
18
|
+
| Validates Agent Token
|
|
19
19
|
v
|
|
20
20
|
Broker Core
|
|
21
|
-
|
|
|
21
|
+
| Permission check -> Credential decryption -> Execution
|
|
22
22
|
v
|
|
23
|
-
|
|
23
|
+
Third-party API (GitHub, etc.)
|
|
24
24
|
|
|
|
25
|
-
| Bearer Token
|
|
25
|
+
| Bearer Token injected by Broker, invisible to Agent
|
|
26
26
|
v
|
|
27
|
-
|
|
27
|
+
Response returned to Agent
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
**Key benefits:**
|
|
31
31
|
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
32
|
+
- Agents never touch real credentials — token leakage risk is eliminated
|
|
33
|
+
- Operation-level fine-grained access control (e.g., allow `github:list_repos`, deny `github:create_issue`)
|
|
34
|
+
- Parameter constraints to scope operations (e.g., restrict access to a specific GitHub organization)
|
|
35
|
+
- Tamper-evident audit log chain (HMAC-SHA256)
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
39
|
-
##
|
|
39
|
+
## Repository Structure
|
|
40
40
|
|
|
41
41
|
```
|
|
42
42
|
agent-auth-broker/
|
|
43
43
|
├── apps/
|
|
44
|
-
│ ├── web/ # Next.js 14 — Admin UI + Broker API
|
|
44
|
+
│ ├── web/ # Next.js 14 — Admin UI + Broker API (PostgreSQL)
|
|
45
45
|
│ │ └── prisma/schema.prisma
|
|
46
|
-
│ ├── mcp-server/ # MCP Server
|
|
47
|
-
│ └── cli/ # CLI
|
|
46
|
+
│ ├── mcp-server/ # MCP Server (stdio + Streamable HTTP transport)
|
|
47
|
+
│ └── cli/ # CLI tool — broker init/serve/validate/ui
|
|
48
48
|
├── packages/
|
|
49
|
-
│ ├── local-runtime/ #
|
|
50
|
-
│ ├── core/ #
|
|
51
|
-
│ ├── connectors/ #
|
|
52
|
-
│ ├── crypto/ # AES-256-GCM
|
|
53
|
-
│ └── shared-types/ #
|
|
54
|
-
├── Dockerfile #
|
|
55
|
-
├── docker-compose.yml # web + postgres
|
|
56
|
-
├── .github/workflows/ # CI/CD
|
|
57
|
-
├── package.json # pnpm monorepo
|
|
49
|
+
│ ├── local-runtime/ # Local runtime (YAML-driven, no database required)
|
|
50
|
+
│ ├── core/ # Core business logic (database schema)
|
|
51
|
+
│ ├── connectors/ # Third-party service adapters (plugin-based dynamic loading)
|
|
52
|
+
│ ├── crypto/ # AES-256-GCM encryption utilities
|
|
53
|
+
│ └── shared-types/ # Shared TypeScript type definitions
|
|
54
|
+
├── Dockerfile # Multi-stage Docker build
|
|
55
|
+
├── docker-compose.yml # One-command web + postgres deployment
|
|
56
|
+
├── .github/workflows/ # CI/CD (build + typecheck + test + npm publish)
|
|
57
|
+
├── package.json # pnpm monorepo root
|
|
58
58
|
└── turbo.json
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
---
|
|
62
62
|
|
|
63
|
-
##
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- AES-256-GCM
|
|
67
|
-
- ReDoS
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
- OAuth State
|
|
71
|
-
- Token SHA-256
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
- Scope
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- pino
|
|
82
|
-
-
|
|
83
|
-
- `/api/health`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- Connector
|
|
87
|
-
- `ConnectorAdapter`
|
|
88
|
-
-
|
|
63
|
+
## Features
|
|
64
|
+
|
|
65
|
+
**Security**
|
|
66
|
+
- AES-256-GCM two-layer encryption (MEK encrypts DEK, DEK encrypts credential data)
|
|
67
|
+
- ReDoS protection via safe-regex2 for all regex pattern validation
|
|
68
|
+
- Tamper-evident audit log chain (HMAC-SHA256 hash chain)
|
|
69
|
+
- Secure HTTP response headers (X-Content-Type-Options, X-Frame-Options, CSP, etc.)
|
|
70
|
+
- OAuth State persisted to database to prevent CSRF attacks
|
|
71
|
+
- Token authentication via SHA-256 hash comparison
|
|
72
|
+
|
|
73
|
+
**Permission Model**
|
|
74
|
+
- Operation-level access control
|
|
75
|
+
- Parameter regex constraints to limit operation scope
|
|
76
|
+
- Rate limiting with sliding window algorithm
|
|
77
|
+
- Policy expiration timestamps
|
|
78
|
+
- Scope groups for simplified permission configuration
|
|
79
|
+
|
|
80
|
+
**Observability**
|
|
81
|
+
- Structured logging via pino (configurable via `BROKER_LOG_LEVEL`)
|
|
82
|
+
- Audit log output to stdout or file
|
|
83
|
+
- `/api/health` endpoint for health checks
|
|
84
|
+
|
|
85
|
+
**Extensibility**
|
|
86
|
+
- Plugin-based Connector system (load from npm packages or local paths dynamically)
|
|
87
|
+
- `ConnectorAdapter` interface with optional `validateCredential` method
|
|
88
|
+
- Built-in GitHub Connector with 10 operations
|
|
89
89
|
|
|
90
90
|
---
|
|
91
91
|
|
|
92
|
-
##
|
|
92
|
+
## Operation Modes
|
|
93
93
|
|
|
94
|
-
|
|
|
95
|
-
|
|
96
|
-
| **File Mode** |
|
|
97
|
-
| **Local Mode** |
|
|
98
|
-
| **Remote Mode** |
|
|
94
|
+
| Mode | Use Case | External Dependencies | Configuration |
|
|
95
|
+
|------|----------|-----------------------|---------------|
|
|
96
|
+
| **File Mode** | Individual developers, single Agent | None | `broker.yaml` + environment variables |
|
|
97
|
+
| **Local Mode** | Small teams, local development | PostgreSQL | `.env` + database |
|
|
98
|
+
| **Remote Mode** | Production, multi-user | PostgreSQL + Web Server | Managed via Web UI |
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
**Mode selection priority (resolved automatically at MCP Server startup):**
|
|
101
101
|
|
|
102
102
|
```
|
|
103
|
-
BROKER_URL
|
|
104
|
-
DATABASE_URL
|
|
105
|
-
BROKER_CONFIG
|
|
103
|
+
BROKER_URL is set -> Remote Mode (highest priority)
|
|
104
|
+
DATABASE_URL is set -> Local Mode
|
|
105
|
+
BROKER_CONFIG is set -> File Mode
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
---
|
|
109
109
|
|
|
110
|
-
##
|
|
110
|
+
## Installation
|
|
111
111
|
|
|
112
|
-
###
|
|
112
|
+
### Option 1: Global npm install (recommended)
|
|
113
113
|
|
|
114
114
|
```bash
|
|
115
115
|
npm install -g agent-auth-broker
|
|
116
116
|
broker --version
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
###
|
|
119
|
+
### Option 2: Run with npx (no installation required)
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
122
|
npx agent-auth-broker init
|
|
123
123
|
npx agent-auth-broker serve
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
###
|
|
126
|
+
### Option 3: Build from source
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
129
|
git clone https://github.com/your-org/agent-auth-broker.git
|
|
@@ -135,18 +135,18 @@ node apps/cli/dist/index.js --version
|
|
|
135
135
|
|
|
136
136
|
---
|
|
137
137
|
|
|
138
|
-
##
|
|
138
|
+
## Quick Start: File Mode
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
The lightest-weight integration — requires only a YAML configuration file and environment variables, with no database or web server.
|
|
141
141
|
|
|
142
|
-
###
|
|
142
|
+
### Step 1: Initialize configuration
|
|
143
143
|
|
|
144
144
|
```bash
|
|
145
145
|
broker init
|
|
146
|
-
#
|
|
146
|
+
# or: npx agent-auth-broker init
|
|
147
147
|
```
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Generated `broker.yaml`:
|
|
150
150
|
|
|
151
151
|
```yaml
|
|
152
152
|
version: "1"
|
|
@@ -158,35 +158,35 @@ agents:
|
|
|
158
158
|
credentials:
|
|
159
159
|
- id: github-main
|
|
160
160
|
connector: github
|
|
161
|
-
token: ${GITHUB_TOKEN} #
|
|
161
|
+
token: ${GITHUB_TOKEN} # References an environment variable — credential never written to disk
|
|
162
162
|
|
|
163
163
|
policies:
|
|
164
164
|
- agent: my-agent
|
|
165
165
|
credential: github-main
|
|
166
166
|
actions:
|
|
167
|
-
- "*" #
|
|
167
|
+
- "*" # Allow all operations
|
|
168
168
|
|
|
169
169
|
audit:
|
|
170
170
|
enabled: true
|
|
171
171
|
output: stdout
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
-
###
|
|
174
|
+
### Step 2: Set environment variables
|
|
175
175
|
|
|
176
176
|
```bash
|
|
177
177
|
export GITHUB_TOKEN="ghp_your_personal_access_token"
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
###
|
|
180
|
+
### Step 3: Validate configuration
|
|
181
181
|
|
|
182
182
|
```bash
|
|
183
|
-
broker validate #
|
|
184
|
-
broker diagnose #
|
|
183
|
+
broker validate # Validate configuration file format
|
|
184
|
+
broker diagnose # Diagnose credential connectivity (calls the GitHub API to verify)
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
###
|
|
187
|
+
### Step 4: Configure the MCP Server
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
Add the following to `claude_desktop_config.json` or `.claude/settings.json`:
|
|
190
190
|
|
|
191
191
|
```json
|
|
192
192
|
{
|
|
@@ -203,7 +203,7 @@ broker diagnose # 诊断凭证连接(实际调用 GitHub API 验证)
|
|
|
203
203
|
}
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
When running from source, replace `"command": "broker"` with:
|
|
207
207
|
|
|
208
208
|
```json
|
|
209
209
|
"command": "node",
|
|
@@ -212,13 +212,13 @@ broker diagnose # 诊断凭证连接(实际调用 GitHub API 验证)
|
|
|
212
212
|
|
|
213
213
|
---
|
|
214
214
|
|
|
215
|
-
## broker.yaml
|
|
215
|
+
## broker.yaml Configuration Reference
|
|
216
216
|
|
|
217
|
-
###
|
|
217
|
+
### Credential Configuration
|
|
218
218
|
|
|
219
|
-
|
|
219
|
+
**Option 1: Environment variable reference (recommended)**
|
|
220
220
|
|
|
221
|
-
|
|
221
|
+
Credentials are referenced via `${ENV_VAR}` syntax. No plaintext credentials are written to disk.
|
|
222
222
|
|
|
223
223
|
```yaml
|
|
224
224
|
credentials:
|
|
@@ -227,13 +227,13 @@ credentials:
|
|
|
227
227
|
token: ${GITHUB_TOKEN}
|
|
228
228
|
```
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
**Option 2: AES-256-GCM encrypted storage**
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
For scenarios requiring credential persistence, configure `encryption_key` and use encrypted storage:
|
|
233
233
|
|
|
234
234
|
```yaml
|
|
235
235
|
version: "1"
|
|
236
|
-
encryption_key: ${BROKER_MASTER_KEY} #
|
|
236
|
+
encryption_key: ${BROKER_MASTER_KEY} # Master encryption key (64-char hex string)
|
|
237
237
|
|
|
238
238
|
credentials:
|
|
239
239
|
- id: github-main
|
|
@@ -241,155 +241,155 @@ credentials:
|
|
|
241
241
|
encrypted: "base64-encrypted-string"
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
-
###
|
|
244
|
+
### Permission Policies
|
|
245
245
|
|
|
246
246
|
```yaml
|
|
247
247
|
policies:
|
|
248
248
|
- agent: my-agent
|
|
249
249
|
credential: github-main
|
|
250
250
|
|
|
251
|
-
#
|
|
251
|
+
# Option 1: Allow all operations
|
|
252
252
|
actions:
|
|
253
253
|
- "*"
|
|
254
254
|
|
|
255
|
-
#
|
|
255
|
+
# Option 2: Use scope groups (auto-expanded)
|
|
256
256
|
# actions:
|
|
257
|
-
# - "github:read" #
|
|
258
|
-
# - "github:write" #
|
|
257
|
+
# - "github:read" # Expands to 7 read-only operations
|
|
258
|
+
# - "github:write" # Expands to 3 write operations
|
|
259
259
|
|
|
260
|
-
#
|
|
260
|
+
# Option 3: Specify operations explicitly
|
|
261
261
|
# actions:
|
|
262
262
|
# - "github:list_repos"
|
|
263
263
|
# - "github:create_issue"
|
|
264
264
|
|
|
265
|
-
#
|
|
265
|
+
# Optional: Parameter constraints (regex matching)
|
|
266
266
|
# param_constraints:
|
|
267
267
|
# repo:
|
|
268
|
-
# pattern: "^myorg/.*" # repo
|
|
268
|
+
# pattern: "^myorg/.*" # repo parameter must start with myorg/
|
|
269
269
|
|
|
270
|
-
#
|
|
270
|
+
# Optional: Rate limiting (sliding window algorithm)
|
|
271
271
|
# rate_limit:
|
|
272
272
|
# max_calls: 100
|
|
273
273
|
# window_seconds: 3600
|
|
274
274
|
|
|
275
|
-
#
|
|
275
|
+
# Optional: Policy expiration
|
|
276
276
|
# expires_at: "2025-12-31T23:59:59Z"
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
-
### Scope
|
|
279
|
+
### Scope Groups
|
|
280
280
|
|
|
281
|
-
| Scope |
|
|
282
|
-
|
|
281
|
+
| Scope | Expands To |
|
|
282
|
+
|-------|------------|
|
|
283
283
|
| `github:read` | `list_repos`, `get_repo`, `list_issues`, `get_issue`, `list_prs`, `get_file`, `search_code` |
|
|
284
284
|
| `github:write` | `create_issue`, `comment_issue`, `create_pr` |
|
|
285
285
|
|
|
286
|
-
###
|
|
286
|
+
### Audit Log Configuration
|
|
287
287
|
|
|
288
288
|
```yaml
|
|
289
289
|
audit:
|
|
290
290
|
enabled: true
|
|
291
|
-
output: stdout #
|
|
291
|
+
output: stdout # Outputs to stderr (appropriate for MCP stdio mode)
|
|
292
292
|
# output: file
|
|
293
293
|
# file: ./broker-audit.log
|
|
294
294
|
```
|
|
295
295
|
|
|
296
296
|
---
|
|
297
297
|
|
|
298
|
-
## CLI
|
|
298
|
+
## CLI Reference
|
|
299
299
|
|
|
300
|
-
|
|
300
|
+
All commands support `-c, --config <path>` to specify the configuration file. By default, the CLI searches upward from the current directory for `broker.yaml`.
|
|
301
301
|
|
|
302
302
|
```bash
|
|
303
|
-
#
|
|
304
|
-
broker init #
|
|
305
|
-
broker init --force #
|
|
303
|
+
# Initialization
|
|
304
|
+
broker init # Generate broker.yaml template
|
|
305
|
+
broker init --force # Overwrite existing configuration
|
|
306
306
|
|
|
307
|
-
#
|
|
308
|
-
broker validate #
|
|
309
|
-
broker diagnose #
|
|
307
|
+
# Validation and diagnostics
|
|
308
|
+
broker validate # Validate configuration file format
|
|
309
|
+
broker diagnose # Check environment variables and credential connectivity
|
|
310
310
|
|
|
311
|
-
# Agent
|
|
312
|
-
broker agent create <id> [-n <name>] #
|
|
313
|
-
broker agent list #
|
|
314
|
-
broker agent remove <id> #
|
|
311
|
+
# Agent management
|
|
312
|
+
broker agent create <id> [-n <name>] # Create an Agent
|
|
313
|
+
broker agent list # List all Agents
|
|
314
|
+
broker agent remove <id> # Remove an Agent
|
|
315
315
|
|
|
316
|
-
# Token
|
|
317
|
-
broker token generate <agent-id> #
|
|
318
|
-
broker token generate <agent-id> --force #
|
|
319
|
-
broker token revoke <agent-id> #
|
|
320
|
-
broker token list #
|
|
316
|
+
# Token management
|
|
317
|
+
broker token generate <agent-id> # Generate an Agent Token (displayed once)
|
|
318
|
+
broker token generate <agent-id> --force # Overwrite existing Token
|
|
319
|
+
broker token revoke <agent-id> # Revoke a Token
|
|
320
|
+
broker token list # List Token status for all Agents
|
|
321
321
|
|
|
322
|
-
#
|
|
323
|
-
broker credential add <connector> --env <VAR> #
|
|
324
|
-
broker credential add <connector> --token <val> #
|
|
325
|
-
broker credential list #
|
|
326
|
-
broker credential remove <id> #
|
|
322
|
+
# Credential management
|
|
323
|
+
broker credential add <connector> --env <VAR> # Add a credential via environment variable reference
|
|
324
|
+
broker credential add <connector> --token <val> # Add a credential with inline token (not recommended)
|
|
325
|
+
broker credential list # List all credentials
|
|
326
|
+
broker credential remove <id> # Remove a credential
|
|
327
327
|
|
|
328
|
-
#
|
|
329
|
-
broker policy set <agent> <credential> [--actions "*"] #
|
|
330
|
-
broker policy list #
|
|
331
|
-
broker policy remove <agent> <credential> #
|
|
328
|
+
# Policy management
|
|
329
|
+
broker policy set <agent> <credential> [--actions "*"] # Set a policy
|
|
330
|
+
broker policy list # List all policies
|
|
331
|
+
broker policy remove <agent> <credential> # Remove a policy
|
|
332
332
|
|
|
333
|
-
#
|
|
334
|
-
broker test <connector> <action> #
|
|
335
|
-
broker test github list_repos #
|
|
336
|
-
broker test github list_issues -p '{"repo":"owner/repo"}' #
|
|
337
|
-
broker test github create_issue --dry-run #
|
|
333
|
+
# Testing operations
|
|
334
|
+
broker test <connector> <action> # Test a Connector operation
|
|
335
|
+
broker test github list_repos # Example: list GitHub repositories
|
|
336
|
+
broker test github list_issues -p '{"repo":"owner/repo"}' # With parameters
|
|
337
|
+
broker test github create_issue --dry-run # Permission check only, no actual API call
|
|
338
338
|
|
|
339
|
-
#
|
|
340
|
-
broker serve # stdio
|
|
341
|
-
broker serve --agent <id> #
|
|
339
|
+
# Start MCP Server
|
|
340
|
+
broker serve # stdio mode (with config hot-reload)
|
|
341
|
+
broker serve --agent <id> # Specify Agent ID
|
|
342
342
|
|
|
343
|
-
# Web UI
|
|
344
|
-
broker ui #
|
|
345
|
-
broker ui --port 8080 #
|
|
343
|
+
# Web UI (File Mode visual management)
|
|
344
|
+
broker ui # Start Web UI (default port 3200)
|
|
345
|
+
broker ui --port 8080 # Custom port
|
|
346
346
|
```
|
|
347
347
|
|
|
348
|
-
### Token
|
|
348
|
+
### Token Authentication Flow
|
|
349
349
|
|
|
350
|
-
1.
|
|
351
|
-
2.
|
|
352
|
-
3.
|
|
353
|
-
4. MCP Server
|
|
350
|
+
1. Generate a Token: `broker token generate my-agent` (Token is displayed once only)
|
|
351
|
+
2. The SHA-256 hash of the Token is automatically written to the `token_hash` field in `broker.yaml`
|
|
352
|
+
3. Pass the Token plaintext via the `BROKER_AGENT_TOKEN` environment variable in your MCP configuration
|
|
353
|
+
4. The MCP Server verifies Agent identity at startup via hash comparison
|
|
354
354
|
|
|
355
|
-
|
|
355
|
+
If `BROKER_AGENT_TOKEN` is not set, the Server falls back to the `--agent` parameter, or defaults to the first Agent in the configuration.
|
|
356
356
|
|
|
357
|
-
###
|
|
357
|
+
### Configuration Hot-Reload
|
|
358
358
|
|
|
359
|
-
`broker serve`
|
|
359
|
+
`broker serve` automatically watches `broker.yaml` for changes. Configuration updates take effect without restarting the MCP Server:
|
|
360
360
|
|
|
361
|
-
-
|
|
362
|
-
-
|
|
363
|
-
-
|
|
361
|
+
- Uses `fs.watch` with 300ms debounce to prevent duplicate triggers
|
|
362
|
+
- On reload failure, the previous configuration is retained and an error is logged
|
|
363
|
+
- The file watcher is cleaned up automatically on process exit
|
|
364
364
|
|
|
365
365
|
### File Mode Web UI
|
|
366
366
|
|
|
367
|
-
`broker ui`
|
|
367
|
+
`broker ui` starts a lightweight web interface (default: `http://localhost:3200`) for managing `broker.yaml` visually:
|
|
368
368
|
|
|
369
|
-
-
|
|
370
|
-
-
|
|
371
|
-
- YAML
|
|
372
|
-
-
|
|
369
|
+
- Built on Node.js built-in `http` module — no external dependencies
|
|
370
|
+
- Supports create and delete operations for Agents, Credentials, and Policies
|
|
371
|
+
- YAML preview with automatic token redaction
|
|
372
|
+
- All changes are written to `broker.yaml` immediately
|
|
373
373
|
|
|
374
374
|
---
|
|
375
375
|
|
|
376
|
-
## MCP Server
|
|
376
|
+
## MCP Server Configuration
|
|
377
377
|
|
|
378
|
-
### Streamable HTTP
|
|
378
|
+
### Streamable HTTP Transport (optional)
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
The default transport is stdio. To expose the MCP Server over HTTP (e.g., for multiple Agents sharing a single MCP Server), enable HTTP transport:
|
|
381
381
|
|
|
382
382
|
```bash
|
|
383
383
|
MCP_TRANSPORT=http MCP_PORT=3200 MCP_AUTH_TOKEN=your-secret broker serve
|
|
384
384
|
```
|
|
385
385
|
|
|
386
|
-
|
|
386
|
+
Clients must include the Bearer Token in requests:
|
|
387
387
|
|
|
388
388
|
```
|
|
389
389
|
Authorization: Bearer your-secret
|
|
390
390
|
```
|
|
391
391
|
|
|
392
|
-
###
|
|
392
|
+
### MCP Configuration by Mode
|
|
393
393
|
|
|
394
394
|
**File Mode**
|
|
395
395
|
|
|
@@ -408,7 +408,7 @@ Authorization: Bearer your-secret
|
|
|
408
408
|
}
|
|
409
409
|
```
|
|
410
410
|
|
|
411
|
-
**Local Mode
|
|
411
|
+
**Local Mode (direct PostgreSQL connection)**
|
|
412
412
|
|
|
413
413
|
```json
|
|
414
414
|
{
|
|
@@ -426,7 +426,7 @@ Authorization: Bearer your-secret
|
|
|
426
426
|
}
|
|
427
427
|
```
|
|
428
428
|
|
|
429
|
-
**Remote Mode
|
|
429
|
+
**Remote Mode (HTTP call to Web Server)**
|
|
430
430
|
|
|
431
431
|
```json
|
|
432
432
|
{
|
|
@@ -445,45 +445,45 @@ Authorization: Bearer your-secret
|
|
|
445
445
|
|
|
446
446
|
---
|
|
447
447
|
|
|
448
|
-
## Docker
|
|
448
|
+
## Docker Deployment
|
|
449
449
|
|
|
450
|
-
|
|
450
|
+
Start the Web Server and PostgreSQL with a single command using docker-compose:
|
|
451
451
|
|
|
452
452
|
```bash
|
|
453
|
-
#
|
|
453
|
+
# Copy and configure environment variables
|
|
454
454
|
cp apps/web/.env.example apps/web/.env
|
|
455
455
|
|
|
456
|
-
#
|
|
456
|
+
# Build and start
|
|
457
457
|
docker-compose up -d
|
|
458
458
|
|
|
459
|
-
#
|
|
459
|
+
# View logs
|
|
460
460
|
docker-compose logs -f web
|
|
461
461
|
```
|
|
462
462
|
|
|
463
|
-
`docker-compose.yml`
|
|
463
|
+
`docker-compose.yml` includes:
|
|
464
464
|
|
|
465
|
-
- `web`
|
|
466
|
-
- `postgres`
|
|
465
|
+
- `web` service: Next.js 14 Admin UI + Broker API, port 3100
|
|
466
|
+
- `postgres` service: PostgreSQL 14, data persisted to a named volume
|
|
467
467
|
|
|
468
|
-
|
|
468
|
+
Multi-stage Docker build — the final image contains only production artifacts.
|
|
469
469
|
|
|
470
470
|
---
|
|
471
471
|
|
|
472
|
-
## Web UI
|
|
472
|
+
## Web UI (Local / Remote Mode)
|
|
473
473
|
|
|
474
|
-
###
|
|
474
|
+
### Requirements
|
|
475
475
|
|
|
476
476
|
- Node.js >= 20
|
|
477
477
|
- pnpm >= 9.15
|
|
478
478
|
- PostgreSQL >= 14
|
|
479
479
|
|
|
480
|
-
###
|
|
480
|
+
### Configuration
|
|
481
481
|
|
|
482
482
|
```bash
|
|
483
483
|
cp apps/web/.env.example apps/web/.env
|
|
484
484
|
```
|
|
485
485
|
|
|
486
|
-
`apps/web/.env
|
|
486
|
+
Required fields in `apps/web/.env`:
|
|
487
487
|
|
|
488
488
|
```env
|
|
489
489
|
DATABASE_URL="postgresql://user:password@localhost:5432/agent_auth_broker"
|
|
@@ -494,283 +494,283 @@ GITHUB_CLIENT_ID="your-github-oauth-app-client-id"
|
|
|
494
494
|
GITHUB_CLIENT_SECRET="your-github-oauth-app-client-secret"
|
|
495
495
|
```
|
|
496
496
|
|
|
497
|
-
###
|
|
497
|
+
### Initialize Database and Start
|
|
498
498
|
|
|
499
499
|
```bash
|
|
500
|
-
pnpm db:generate #
|
|
501
|
-
pnpm db:push #
|
|
502
|
-
# pnpm db:migrate #
|
|
500
|
+
pnpm db:generate # Generate Prisma Client
|
|
501
|
+
pnpm db:push # Push schema (development)
|
|
502
|
+
# pnpm db:migrate # Create migration files (production)
|
|
503
503
|
|
|
504
504
|
pnpm build
|
|
505
|
-
pnpm dev:web #
|
|
505
|
+
pnpm dev:web # Visit http://localhost:3100
|
|
506
506
|
```
|
|
507
507
|
|
|
508
|
-
###
|
|
508
|
+
### Workflow
|
|
509
509
|
|
|
510
|
-
1.
|
|
511
|
-
2.
|
|
512
|
-
3.
|
|
513
|
-
4.
|
|
510
|
+
1. **Register an Agent**: Admin UI -> Agents -> Create Agent -> Copy Token (`agnt_xxxx`, displayed once)
|
|
511
|
+
2. **Connect credentials**: Admin UI -> Credentials -> Connect via OAuth -> Credentials are encrypted automatically
|
|
512
|
+
3. **Configure policies**: Admin UI -> Agent Policies -> Select credential, allowed operations, and parameter constraints
|
|
513
|
+
4. **Configure MCP Server**: Set the Agent Token in the `BROKER_AGENT_TOKEN` environment variable in your MCP configuration
|
|
514
514
|
|
|
515
515
|
---
|
|
516
516
|
|
|
517
|
-
## MCP
|
|
517
|
+
## MCP Tools
|
|
518
518
|
|
|
519
|
-
MCP Server
|
|
519
|
+
The MCP Server exposes the following tools upon startup:
|
|
520
520
|
|
|
521
|
-
###
|
|
521
|
+
### Fixed Tools
|
|
522
522
|
|
|
523
|
-
|
|
|
524
|
-
|
|
525
|
-
| `broker_call` |
|
|
526
|
-
| `broker_list_tools` |
|
|
523
|
+
| Tool | Description |
|
|
524
|
+
|------|-------------|
|
|
525
|
+
| `broker_call` | Universal invocation entry point: specify connector + action + params |
|
|
526
|
+
| `broker_list_tools` | List all tools the current Agent is authorized to use |
|
|
527
527
|
|
|
528
|
-
###
|
|
528
|
+
### Dynamic Named Tools
|
|
529
529
|
|
|
530
|
-
|
|
530
|
+
Generated automatically based on the Agent's permission policies, in the format `{connector}_{action}`:
|
|
531
531
|
|
|
532
|
-
|
|
|
533
|
-
|
|
532
|
+
| Tool | Equivalent Call |
|
|
533
|
+
|------|----------------|
|
|
534
534
|
| `github_list_repos` | `broker_call({ connector: "github", action: "list_repos" })` |
|
|
535
535
|
| `github_create_issue` | `broker_call({ connector: "github", action: "create_issue", ... })` |
|
|
536
536
|
| `github_search_code` | `broker_call({ connector: "github", action: "search_code", ... })` |
|
|
537
537
|
|
|
538
|
-
|
|
538
|
+
Agents only see tools they are authorized to use. Unauthorized tools are not included in the tool list.
|
|
539
539
|
|
|
540
540
|
---
|
|
541
541
|
|
|
542
|
-
## GitHub Connector
|
|
543
|
-
|
|
544
|
-
| action |
|
|
545
|
-
|
|
546
|
-
| `list_repos` |
|
|
547
|
-
| `get_repo` |
|
|
548
|
-
| `list_issues` |
|
|
549
|
-
| `get_issue` |
|
|
550
|
-
| `create_issue` |
|
|
551
|
-
| `comment_issue` |
|
|
552
|
-
| `list_prs` |
|
|
553
|
-
| `create_pr` |
|
|
554
|
-
| `get_file` |
|
|
555
|
-
| `search_code` |
|
|
542
|
+
## GitHub Connector Operations
|
|
543
|
+
|
|
544
|
+
| action | Description | Required Parameters |
|
|
545
|
+
|--------|-------------|---------------------|
|
|
546
|
+
| `list_repos` | List repositories for the authenticated user | — |
|
|
547
|
+
| `get_repo` | Get repository information | `repo` (format: `owner/repo`) |
|
|
548
|
+
| `list_issues` | List issues in a repository | `repo` |
|
|
549
|
+
| `get_issue` | Get details of a single issue | `repo`, `issue_number` |
|
|
550
|
+
| `create_issue` | Create an issue | `repo`, `title` |
|
|
551
|
+
| `comment_issue` | Add a comment to an issue | `repo`, `issue_number`, `body` |
|
|
552
|
+
| `list_prs` | List pull requests | `repo` |
|
|
553
|
+
| `create_pr` | Create a pull request | `repo`, `title`, `head`, `base` |
|
|
554
|
+
| `get_file` | Get file contents (Base64-decoded automatically) | `repo`, `path` |
|
|
555
|
+
| `search_code` | Search code | `q` |
|
|
556
556
|
|
|
557
557
|
---
|
|
558
558
|
|
|
559
|
-
##
|
|
559
|
+
## Permission Model
|
|
560
560
|
|
|
561
|
-
###
|
|
561
|
+
### Permission Check Flow
|
|
562
562
|
|
|
563
563
|
```
|
|
564
|
-
|
|
564
|
+
Request received
|
|
565
565
|
|
|
|
566
|
-
+--> Agent
|
|
566
|
+
+--> Is the Agent active? -> DENIED_AGENT_INACTIVE
|
|
567
567
|
|
|
|
568
|
-
+-->
|
|
568
|
+
+--> Is there a matching policy? -> DENIED_NO_POLICY
|
|
569
569
|
|
|
|
570
|
-
+-->
|
|
570
|
+
+--> Is the action in the allow list? -> DENIED_ACTION_NOT_ALLOWED
|
|
571
571
|
|
|
|
572
|
-
+-->
|
|
572
|
+
+--> Do the parameters satisfy constraints? -> DENIED_PARAM_CONSTRAINT
|
|
573
573
|
|
|
|
574
|
-
+-->
|
|
574
|
+
+--> Has the credential expired? -> DENIED_CREDENTIAL_EXPIRED
|
|
575
575
|
|
|
|
576
|
-
+-->
|
|
576
|
+
+--> Has the rate limit been exceeded? -> DENIED_RATE_LIMIT
|
|
577
577
|
|
|
|
578
578
|
v
|
|
579
|
-
|
|
579
|
+
Execute operation
|
|
580
580
|
```
|
|
581
581
|
|
|
582
|
-
###
|
|
582
|
+
### Denial Reason Codes
|
|
583
583
|
|
|
584
|
-
|
|
|
585
|
-
|
|
586
|
-
| `DENIED_AGENT_INACTIVE` | Agent
|
|
587
|
-
| `DENIED_NO_POLICY` |
|
|
588
|
-
| `DENIED_ACTION_NOT_ALLOWED` |
|
|
589
|
-
| `DENIED_PARAM_CONSTRAINT` |
|
|
590
|
-
| `DENIED_CREDENTIAL_EXPIRED` |
|
|
591
|
-
| `DENIED_RATE_LIMIT` |
|
|
584
|
+
| Code | Meaning |
|
|
585
|
+
|------|---------|
|
|
586
|
+
| `DENIED_AGENT_INACTIVE` | The Agent has been deactivated |
|
|
587
|
+
| `DENIED_NO_POLICY` | No policy matches this Agent and connector |
|
|
588
|
+
| `DENIED_ACTION_NOT_ALLOWED` | The operation is not in the allow list |
|
|
589
|
+
| `DENIED_PARAM_CONSTRAINT` | A parameter does not satisfy the configured constraint |
|
|
590
|
+
| `DENIED_CREDENTIAL_EXPIRED` | The credential has expired or been revoked |
|
|
591
|
+
| `DENIED_RATE_LIMIT` | The rate limit has been exceeded |
|
|
592
592
|
|
|
593
|
-
###
|
|
593
|
+
### Parameter Constraint Example
|
|
594
594
|
|
|
595
595
|
```yaml
|
|
596
596
|
param_constraints:
|
|
597
597
|
repo:
|
|
598
|
-
pattern: "^myorg/.*" # repo
|
|
598
|
+
pattern: "^myorg/.*" # repo parameter must start with myorg/
|
|
599
599
|
```
|
|
600
600
|
|
|
601
|
-
|
|
601
|
+
All regex patterns are validated with safe-regex2 on load to prevent ReDoS attacks.
|
|
602
602
|
|
|
603
603
|
---
|
|
604
604
|
|
|
605
|
-
##
|
|
605
|
+
## Encryption
|
|
606
606
|
|
|
607
|
-
|
|
607
|
+
Credentials are protected with **two-layer AES-256-GCM encryption**:
|
|
608
608
|
|
|
609
609
|
```
|
|
610
|
-
BROKER_MASTER_KEY
|
|
610
|
+
BROKER_MASTER_KEY (environment variable, never written to disk)
|
|
611
611
|
|
|
|
612
|
-
+-->
|
|
612
|
+
+--> Encrypts DEK (Data Encryption Key, unique per credential)
|
|
613
613
|
|
|
|
614
|
-
+-->
|
|
614
|
+
+--> Encrypts credential JSON (access_token and other sensitive fields)
|
|
615
615
|
|
|
|
616
|
-
+-->
|
|
616
|
+
+--> Ciphertext stored in database
|
|
617
617
|
```
|
|
618
618
|
|
|
619
|
-
- MEK
|
|
620
|
-
- DEK
|
|
621
|
-
-
|
|
622
|
-
- File Mode
|
|
619
|
+
- The MEK (Master Encryption Key) exists only as an environment variable and is never persisted
|
|
620
|
+
- The DEK is stored in the database (encrypted) in the `encryptionKeyId` field
|
|
621
|
+
- Credential plaintext never appears in logs or HTTP response bodies
|
|
622
|
+
- File Mode encrypted storage uses the same `BROKER_MASTER_KEY`
|
|
623
623
|
|
|
624
624
|
---
|
|
625
625
|
|
|
626
|
-
##
|
|
626
|
+
## Audit Logging
|
|
627
627
|
|
|
628
|
-
|
|
628
|
+
All operations — including denied requests — are recorded in the audit log.
|
|
629
629
|
|
|
630
|
-
|
|
630
|
+
**Log fields:**
|
|
631
631
|
|
|
632
|
-
- Agent ID
|
|
633
|
-
-
|
|
634
|
-
-
|
|
635
|
-
- HTTP
|
|
636
|
-
- IP
|
|
637
|
-
-
|
|
632
|
+
- Agent ID, Connector, Action
|
|
633
|
+
- Permission check result (`permissionResult`)
|
|
634
|
+
- Redacted request summary (sensitive fields replaced with `[REDACTED]`)
|
|
635
|
+
- HTTP status code and error message
|
|
636
|
+
- IP address and User-Agent
|
|
637
|
+
- Timestamp and hash chain value
|
|
638
638
|
|
|
639
|
-
|
|
639
|
+
**Tamper-evidence:**
|
|
640
640
|
|
|
641
|
-
|
|
641
|
+
Audit logs use an HMAC-SHA256 hash chain. Each record includes the hash of the previous record, forming a chain that cannot be altered without detection. The application layer enforces INSERT-only access — UPDATE and DELETE operations on audit records are not permitted.
|
|
642
642
|
|
|
643
|
-
|
|
643
|
+
**Output configuration:**
|
|
644
644
|
|
|
645
645
|
```yaml
|
|
646
646
|
audit:
|
|
647
647
|
enabled: true
|
|
648
|
-
output: stdout # MCP stdio
|
|
648
|
+
output: stdout # Outputs to stderr in MCP stdio mode
|
|
649
649
|
# output: file
|
|
650
650
|
# file: ./broker-audit.log
|
|
651
651
|
```
|
|
652
652
|
|
|
653
653
|
---
|
|
654
654
|
|
|
655
|
-
##
|
|
655
|
+
## Extending Connectors
|
|
656
656
|
|
|
657
|
-
###
|
|
657
|
+
### Built-in Integration
|
|
658
658
|
|
|
659
|
-
|
|
659
|
+
Create a new directory under `packages/connectors/src/`, implement the `ConnectorAdapter` interface, and register it in `registry.ts`:
|
|
660
660
|
|
|
661
661
|
```typescript
|
|
662
|
-
// packages/connectors/src/
|
|
663
|
-
export const
|
|
664
|
-
info: { id: '
|
|
662
|
+
// packages/connectors/src/slack/index.ts
|
|
663
|
+
export const slackConnector: ConnectorAdapter = {
|
|
664
|
+
info: { id: 'slack', name: 'Slack', version: '1.0.0' },
|
|
665
665
|
getActions() {
|
|
666
666
|
return [
|
|
667
|
-
{ id: '
|
|
667
|
+
{ id: 'post_message', name: 'Post Message', params: [...] },
|
|
668
668
|
]
|
|
669
669
|
},
|
|
670
670
|
async execute(action, params, credential) {
|
|
671
|
-
//
|
|
671
|
+
// Implementation
|
|
672
672
|
},
|
|
673
673
|
async validateCredential(credential) {
|
|
674
|
-
//
|
|
674
|
+
// Optional: validate credential on load
|
|
675
675
|
},
|
|
676
676
|
}
|
|
677
677
|
|
|
678
678
|
// packages/connectors/src/registry.ts
|
|
679
|
-
import {
|
|
679
|
+
import { slackConnector } from './slack/index'
|
|
680
680
|
|
|
681
681
|
const connectors = new Map([
|
|
682
682
|
['github', githubConnector],
|
|
683
|
-
['
|
|
683
|
+
['slack', slackConnector], // Register new Connector
|
|
684
684
|
])
|
|
685
685
|
```
|
|
686
686
|
|
|
687
|
-
###
|
|
687
|
+
### Plugin-based Dynamic Loading
|
|
688
688
|
|
|
689
|
-
|
|
689
|
+
Connectors can be loaded from npm packages or local paths at runtime, without modifying core code:
|
|
690
690
|
|
|
691
691
|
```typescript
|
|
692
692
|
import { loadConnectorPlugin } from '@agent-auth-broker/connectors'
|
|
693
693
|
|
|
694
|
-
//
|
|
695
|
-
await loadConnectorPlugin('my-broker-connector-
|
|
694
|
+
// Load from npm package
|
|
695
|
+
await loadConnectorPlugin('my-broker-connector-slack')
|
|
696
696
|
|
|
697
|
-
//
|
|
697
|
+
// Load from local path
|
|
698
698
|
await loadConnectorPlugin('./plugins/my-connector')
|
|
699
699
|
```
|
|
700
700
|
|
|
701
|
-
|
|
701
|
+
Plugins must export a `ConnectorAdapter`-conforming object as their default export.
|
|
702
702
|
|
|
703
703
|
---
|
|
704
704
|
|
|
705
|
-
##
|
|
705
|
+
## Environment Variables
|
|
706
706
|
|
|
707
|
-
|
|
|
708
|
-
|
|
709
|
-
| `BROKER_CONFIG` | broker.yaml
|
|
710
|
-
| `DATABASE_URL` | PostgreSQL
|
|
711
|
-
| `BROKER_MASTER_KEY` |
|
|
712
|
-
| `BROKER_AGENT_TOKEN` | Agent
|
|
713
|
-
| `BROKER_AGENT_ID` |
|
|
707
|
+
| Variable | Purpose | Mode |
|
|
708
|
+
|----------|---------|------|
|
|
709
|
+
| `BROKER_CONFIG` | Path to broker.yaml | File Mode |
|
|
710
|
+
| `DATABASE_URL` | PostgreSQL connection string | Local / Remote |
|
|
711
|
+
| `BROKER_MASTER_KEY` | Master encryption key (64-char hex string) | Local / Remote / File (encrypted storage) |
|
|
712
|
+
| `BROKER_AGENT_TOKEN` | Agent authentication token | All modes |
|
|
713
|
+
| `BROKER_AGENT_ID` | Specify Agent ID (used when no token is set) | File Mode |
|
|
714
714
|
| `BROKER_URL` | Web Server URL | Remote Mode |
|
|
715
|
-
| `MCP_TRANSPORT` |
|
|
716
|
-
| `MCP_PORT` | HTTP
|
|
717
|
-
| `MCP_AUTH_TOKEN` | HTTP Bearer Token | MCP Server HTTP
|
|
718
|
-
| `BROKER_LOG_LEVEL` |
|
|
715
|
+
| `MCP_TRANSPORT` | Transport type: `stdio` (default) or `http` | MCP Server |
|
|
716
|
+
| `MCP_PORT` | HTTP transport port (default: 3200) | MCP Server HTTP mode |
|
|
717
|
+
| `MCP_AUTH_TOKEN` | HTTP Bearer Token | MCP Server HTTP mode |
|
|
718
|
+
| `BROKER_LOG_LEVEL` | Log level (default: `info`) | All modes |
|
|
719
719
|
| `GITHUB_TOKEN` | GitHub Personal Access Token | File Mode |
|
|
720
|
-
| `NEXTAUTH_SECRET` | NextAuth.js
|
|
721
|
-
| `NEXTAUTH_URL` | Web
|
|
720
|
+
| `NEXTAUTH_SECRET` | NextAuth.js secret | Web |
|
|
721
|
+
| `NEXTAUTH_URL` | Web application URL | Web |
|
|
722
722
|
| `GITHUB_CLIENT_ID` | GitHub OAuth App Client ID | Web |
|
|
723
723
|
| `GITHUB_CLIENT_SECRET` | GitHub OAuth App Client Secret | Web |
|
|
724
724
|
|
|
725
725
|
---
|
|
726
726
|
|
|
727
|
-
##
|
|
727
|
+
## Development Commands
|
|
728
728
|
|
|
729
729
|
```bash
|
|
730
|
-
#
|
|
730
|
+
# Install dependencies
|
|
731
731
|
pnpm install
|
|
732
732
|
|
|
733
|
-
#
|
|
733
|
+
# Build all packages
|
|
734
734
|
pnpm build
|
|
735
735
|
|
|
736
|
-
#
|
|
736
|
+
# Build individual packages
|
|
737
737
|
pnpm build:web
|
|
738
738
|
pnpm build:mcp
|
|
739
739
|
pnpm --filter=agent-auth-broker build
|
|
740
740
|
|
|
741
|
-
#
|
|
741
|
+
# Development mode (with hot reload)
|
|
742
742
|
pnpm dev
|
|
743
743
|
pnpm dev:web
|
|
744
744
|
|
|
745
|
-
#
|
|
746
|
-
pnpm db:generate #
|
|
747
|
-
pnpm db:push #
|
|
748
|
-
pnpm db:migrate #
|
|
745
|
+
# Database operations (Local / Remote Mode)
|
|
746
|
+
pnpm db:generate # Generate Prisma Client
|
|
747
|
+
pnpm db:push # Push schema (development)
|
|
748
|
+
pnpm db:migrate # Create migration files (production)
|
|
749
749
|
|
|
750
|
-
#
|
|
750
|
+
# Linting
|
|
751
751
|
pnpm lint
|
|
752
752
|
|
|
753
|
-
#
|
|
753
|
+
# Run tests
|
|
754
754
|
pnpm test
|
|
755
755
|
```
|
|
756
756
|
|
|
757
757
|
---
|
|
758
758
|
|
|
759
|
-
##
|
|
759
|
+
## Testing
|
|
760
760
|
|
|
761
|
-
|
|
761
|
+
The project uses Vitest with 70+ test cases covering the following modules:
|
|
762
762
|
|
|
763
|
-
-
|
|
764
|
-
- Scope
|
|
765
|
-
-
|
|
766
|
-
-
|
|
767
|
-
-
|
|
768
|
-
-
|
|
763
|
+
- Encryption and decryption (AES-256-GCM, including edge cases)
|
|
764
|
+
- Scope expansion logic (scope group parsing and deduplication)
|
|
765
|
+
- Configuration loading (environment variable substitution, format validation)
|
|
766
|
+
- Permission checking (all denial scenarios)
|
|
767
|
+
- Rate limiting (sliding window algorithm)
|
|
768
|
+
- Audit log hash chain (tamper-evidence verification)
|
|
769
769
|
|
|
770
770
|
```bash
|
|
771
|
-
pnpm test #
|
|
772
|
-
pnpm test --watch #
|
|
773
|
-
pnpm test --coverage #
|
|
771
|
+
pnpm test # Run all tests
|
|
772
|
+
pnpm test --watch # Watch mode
|
|
773
|
+
pnpm test --coverage # Generate coverage report
|
|
774
774
|
```
|
|
775
775
|
|
|
776
776
|
---
|
package/dist/index.js
CHANGED
|
@@ -7386,7 +7386,7 @@ var testCommand = new Command10("test").description("\u6D4B\u8BD5\u8C03\u7528 co
|
|
|
7386
7386
|
|
|
7387
7387
|
// src/index.ts
|
|
7388
7388
|
var program = new Command11();
|
|
7389
|
-
program.name("broker").description("Agent Auth Broker CLI \u2014 AI Agent \u51ED\u8BC1\u7BA1\u7406\u4E0E\u6388\u6743\u4EE3\u7406").version("0.0.
|
|
7389
|
+
program.name("broker").description("Agent Auth Broker CLI \u2014 AI Agent \u51ED\u8BC1\u7BA1\u7406\u4E0E\u6388\u6743\u4EE3\u7406").version("0.0.9");
|
|
7390
7390
|
program.addCommand(initCommand);
|
|
7391
7391
|
program.addCommand(validateCommand);
|
|
7392
7392
|
program.addCommand(diagnoseCommand);
|