agentsentinel-cli 0.7.0__tar.gz → 0.7.2__tar.gz
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.
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/.gitignore +3 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/PKG-INFO +62 -6
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/README.md +61 -5
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/cli.py +31 -23
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/discover.py +147 -230
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/discover_report.py +13 -5
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/fingerprint.py +42 -12
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/inspect.py +11 -2
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/inspect_report.py +12 -7
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/mcp_client.py +136 -12
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/pyproject.toml +1 -1
- agentsentinel_cli-0.7.2/tmp/test-mcp-agent/README.md +134 -0
- agentsentinel_cli-0.7.2/tmp/test-mcp-agent/langchain_agent.py +178 -0
- agentsentinel_cli-0.7.2/tmp/test-mcp-agent/mcp_server.py +245 -0
- agentsentinel_cli-0.7.2/tmp/test-mcp-agent/requirements.txt +16 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/DOCUMENTATION.md +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/LICENSE +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/__init__.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/a2a_report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/a2a_rules.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/a2a_scanner.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/agent_mode.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/agent_mode_report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/ai_probe.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/attacks/__init__.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/attacks/library.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/frameworks.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/mcp_report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/mcp_rules.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/probe.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/probe_report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/rules.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/scanner.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/secrets.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/secrets_report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/secrets_rules.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/supply_chain_ai.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/supply_chain_report.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/supply_chain_rules.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/suppress.py +0 -0
- {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/target.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentsentinel-cli
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: Agentic security CLI — AI analyst with memory, supply chain audit, MCP audit, red-team probing, and agent discovery
|
|
5
5
|
Project-URL: Homepage, https://github.com/jaydenaung/agentsentinel-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/jaydenaung/agentsentinel-cli
|
|
@@ -51,7 +51,7 @@ Description-Content-Type: text/markdown
|
|
|
51
51
|
[](LICENSE)
|
|
52
52
|
[](https://pypi.org/project/agentsentinel-cli/)
|
|
53
53
|
|
|
54
|
-
**AI agent security — analyst mode, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
|
|
54
|
+
**AI agent security — analyst mode, multi-agent trust analysis, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
57
|
pipx install "agentsentinel-cli[all]"
|
|
@@ -61,7 +61,7 @@ pipx install "agentsentinel-cli[all]"
|
|
|
61
61
|
|
|
62
62
|
## What it does
|
|
63
63
|
|
|
64
|
-
`sentinel` covers
|
|
64
|
+
`sentinel` covers 9 of the 10 risks in the [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/).
|
|
65
65
|
|
|
66
66
|
It operates at two levels:
|
|
67
67
|
|
|
@@ -83,6 +83,10 @@ sentinel agentic ./my-agent/
|
|
|
83
83
|
sentinel supply-chain http://localhost:3001
|
|
84
84
|
sentinel supply-chain http://localhost:3001 --ai # + Claude semantic analysis
|
|
85
85
|
|
|
86
|
+
# Multi-agent trust analysis — detect A2A trust violations in your codebase
|
|
87
|
+
sentinel a2a ./agents/
|
|
88
|
+
sentinel a2a multi_agent.py --fail-on HIGH
|
|
89
|
+
|
|
86
90
|
# Static posture scan
|
|
87
91
|
sentinel scan my_agent.py
|
|
88
92
|
sentinel secrets .
|
|
@@ -300,6 +304,54 @@ sentinel discover --format json
|
|
|
300
304
|
|
|
301
305
|
---
|
|
302
306
|
|
|
307
|
+
### `sentinel a2a` — multi-agent trust analysis
|
|
308
|
+
|
|
309
|
+
Scans Python agent source files and builds a call graph showing which agents call which, then audits the trust boundaries between them. Detects the attack paths that single-agent tools miss entirely: injection that propagates across agent boundaries, unbounded agent spawning, and code-execution agents that accept delegated instructions without verification.
|
|
310
|
+
|
|
311
|
+
Supports **LangChain / LangGraph**, **AutoGen**, and **CrewAI**. No API key required.
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
sentinel a2a ./agents/
|
|
315
|
+
sentinel a2a multi_agent.py
|
|
316
|
+
sentinel a2a . --fail-on HIGH
|
|
317
|
+
sentinel a2a . --format json
|
|
318
|
+
sentinel a2a . --ignore-rule A2A01_UNVERIFIED_ORCHESTRATOR # suppress if handled at infra layer
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Rules:**
|
|
322
|
+
|
|
323
|
+
| Rule | Severity | What it catches |
|
|
324
|
+
|------|----------|-----------------|
|
|
325
|
+
| `A2A03_IMPLICIT_TRUST` | CRITICAL | Code-execution agent accepts calls from other agents with no caller verification |
|
|
326
|
+
| `A2A04_PROMPT_PASSTHROUGH` | HIGH | User input flows directly across an agent boundary without sanitization |
|
|
327
|
+
| `A2A02_UNBOUNDED_SPAWNING` | HIGH | Agent is instantiated inside a loop — unbounded agent creation risk |
|
|
328
|
+
| `A2A06_CIRCULAR_DELEGATION` | HIGH | Cycle in the call graph — agents can loop indefinitely under injection |
|
|
329
|
+
| `A2A05_UNSCOPED_DELEGATION` | MEDIUM | Orchestrator delegates its full tool set to a sub-agent instead of a restricted subset |
|
|
330
|
+
| `A2A01_UNVERIFIED_ORCHESTRATOR` | LOW | Agents receive instructions from other agents with no visible trust verification |
|
|
331
|
+
|
|
332
|
+
**Example output:**
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
2 agents 1 edges 1 max depth acyclic
|
|
336
|
+
|
|
337
|
+
Agent Framework Role Tools
|
|
338
|
+
planner autogen worker —
|
|
339
|
+
executor autogen orchestrator — ⚠ code exec
|
|
340
|
+
|
|
341
|
+
Call graph:
|
|
342
|
+
executor ──► planner initiate_chat passes input
|
|
343
|
+
|
|
344
|
+
● HIGH A2A04_PROMPT_PASSTHROUGH ASI01
|
|
345
|
+
User input flows directly from 'executor' to 'planner'
|
|
346
|
+
without sanitization at the agent boundary.
|
|
347
|
+
|
|
348
|
+
Trust Score 75/100 ███████████████░░░░░ WATCH
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Covers **ASI07** (Insecure Inter-Agent Communication) from OWASP Top 10 for Agentic Applications 2026.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
303
355
|
## Finding suppression
|
|
304
356
|
|
|
305
357
|
Use `--ignore-rule` to suppress specific findings by rule ID. Suppressed findings are excluded from `--fail-on` evaluation and output — they don't break CI gates.
|
|
@@ -325,7 +377,7 @@ SC03_HIDDEN_NETWORK_FIELDS # webhook field verified safe — used for audit log
|
|
|
325
377
|
NO_AUTH # server is behind an authenticated reverse proxy
|
|
326
378
|
```
|
|
327
379
|
|
|
328
|
-
Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
|
|
380
|
+
Supported on: `sentinel scan`, `sentinel a2a`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
|
|
329
381
|
|
|
330
382
|
---
|
|
331
383
|
|
|
@@ -339,7 +391,7 @@ Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `se
|
|
|
339
391
|
| **Agentic Supply Chain Compromise** | **ASI04** | **`sentinel supply-chain`** (static + AI), **`sentinel agentic`** |
|
|
340
392
|
| Unexpected Code Execution | ASI05 | `sentinel scan` (CODE_EXECUTION_GRANT), `sentinel mcp scan` |
|
|
341
393
|
| **Memory & Context Poisoning** | **ASI06** | **`sentinel secrets`** (memory contamination), **`sentinel agentic`** |
|
|
342
|
-
| Insecure Inter-Agent Communication | ASI07 | `sentinel agentic` (reasoning
|
|
394
|
+
| **Insecure Inter-Agent Communication** | **ASI07** | **`sentinel a2a`** (call graph + trust rules), `sentinel agentic` (semantic reasoning) |
|
|
343
395
|
| Cascading Agent Failures | ASI08 | `sentinel agentic` (cross-finding chain analysis) |
|
|
344
396
|
| Human-Agent Trust Exploitation | ASI09 | `sentinel agentic` (narrative + evidence standard) |
|
|
345
397
|
| Rogue Agents | ASI10 | `sentinel agentic` (drift detection across sessions) |
|
|
@@ -373,6 +425,9 @@ jobs:
|
|
|
373
425
|
|
|
374
426
|
- name: MCP security audit
|
|
375
427
|
run: sentinel mcp scan http://localhost:3001 --fail-on CRITICAL
|
|
428
|
+
|
|
429
|
+
- name: Multi-agent trust analysis
|
|
430
|
+
run: sentinel a2a ./agents/ --fail-on HIGH
|
|
376
431
|
```
|
|
377
432
|
|
|
378
433
|
Use a `.sentinelignore` file at the repo root to suppress known-accepted findings without weakening the gate threshold:
|
|
@@ -393,6 +448,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
|
|
|
393
448
|
| Investigating a specific server or codebase | `sentinel agentic` |
|
|
394
449
|
| First assessment of a new MCP server | `sentinel agentic` |
|
|
395
450
|
| Scheduled nightly security check | `sentinel agentic` (memory tracks drift) |
|
|
451
|
+
| Auditing a multi-agent codebase | `sentinel a2a` (call graph + trust rules) |
|
|
396
452
|
| Quick local sanity check | `sentinel mcp scan`, `sentinel scan` |
|
|
397
453
|
| Red-teaming a live agent endpoint | `sentinel ai-probe` |
|
|
398
454
|
|
|
@@ -402,7 +458,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
|
|
|
402
458
|
|
|
403
459
|
- Python 3.10+
|
|
404
460
|
- `ANTHROPIC_API_KEY` required for: `sentinel agentic`, `sentinel ai-probe`, `sentinel supply-chain --ai`, `sentinel inspect` (AI summary)
|
|
405
|
-
- No API key required for: `sentinel scan`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
|
|
461
|
+
- No API key required for: `sentinel scan`, `sentinel a2a`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
|
|
406
462
|
|
|
407
463
|
---
|
|
408
464
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://pypi.org/project/agentsentinel-cli/)
|
|
6
6
|
|
|
7
|
-
**AI agent security — analyst mode, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
|
|
7
|
+
**AI agent security — analyst mode, multi-agent trust analysis, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
pipx install "agentsentinel-cli[all]"
|
|
@@ -14,7 +14,7 @@ pipx install "agentsentinel-cli[all]"
|
|
|
14
14
|
|
|
15
15
|
## What it does
|
|
16
16
|
|
|
17
|
-
`sentinel` covers
|
|
17
|
+
`sentinel` covers 9 of the 10 risks in the [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/).
|
|
18
18
|
|
|
19
19
|
It operates at two levels:
|
|
20
20
|
|
|
@@ -36,6 +36,10 @@ sentinel agentic ./my-agent/
|
|
|
36
36
|
sentinel supply-chain http://localhost:3001
|
|
37
37
|
sentinel supply-chain http://localhost:3001 --ai # + Claude semantic analysis
|
|
38
38
|
|
|
39
|
+
# Multi-agent trust analysis — detect A2A trust violations in your codebase
|
|
40
|
+
sentinel a2a ./agents/
|
|
41
|
+
sentinel a2a multi_agent.py --fail-on HIGH
|
|
42
|
+
|
|
39
43
|
# Static posture scan
|
|
40
44
|
sentinel scan my_agent.py
|
|
41
45
|
sentinel secrets .
|
|
@@ -253,6 +257,54 @@ sentinel discover --format json
|
|
|
253
257
|
|
|
254
258
|
---
|
|
255
259
|
|
|
260
|
+
### `sentinel a2a` — multi-agent trust analysis
|
|
261
|
+
|
|
262
|
+
Scans Python agent source files and builds a call graph showing which agents call which, then audits the trust boundaries between them. Detects the attack paths that single-agent tools miss entirely: injection that propagates across agent boundaries, unbounded agent spawning, and code-execution agents that accept delegated instructions without verification.
|
|
263
|
+
|
|
264
|
+
Supports **LangChain / LangGraph**, **AutoGen**, and **CrewAI**. No API key required.
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
sentinel a2a ./agents/
|
|
268
|
+
sentinel a2a multi_agent.py
|
|
269
|
+
sentinel a2a . --fail-on HIGH
|
|
270
|
+
sentinel a2a . --format json
|
|
271
|
+
sentinel a2a . --ignore-rule A2A01_UNVERIFIED_ORCHESTRATOR # suppress if handled at infra layer
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**Rules:**
|
|
275
|
+
|
|
276
|
+
| Rule | Severity | What it catches |
|
|
277
|
+
|------|----------|-----------------|
|
|
278
|
+
| `A2A03_IMPLICIT_TRUST` | CRITICAL | Code-execution agent accepts calls from other agents with no caller verification |
|
|
279
|
+
| `A2A04_PROMPT_PASSTHROUGH` | HIGH | User input flows directly across an agent boundary without sanitization |
|
|
280
|
+
| `A2A02_UNBOUNDED_SPAWNING` | HIGH | Agent is instantiated inside a loop — unbounded agent creation risk |
|
|
281
|
+
| `A2A06_CIRCULAR_DELEGATION` | HIGH | Cycle in the call graph — agents can loop indefinitely under injection |
|
|
282
|
+
| `A2A05_UNSCOPED_DELEGATION` | MEDIUM | Orchestrator delegates its full tool set to a sub-agent instead of a restricted subset |
|
|
283
|
+
| `A2A01_UNVERIFIED_ORCHESTRATOR` | LOW | Agents receive instructions from other agents with no visible trust verification |
|
|
284
|
+
|
|
285
|
+
**Example output:**
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
2 agents 1 edges 1 max depth acyclic
|
|
289
|
+
|
|
290
|
+
Agent Framework Role Tools
|
|
291
|
+
planner autogen worker —
|
|
292
|
+
executor autogen orchestrator — ⚠ code exec
|
|
293
|
+
|
|
294
|
+
Call graph:
|
|
295
|
+
executor ──► planner initiate_chat passes input
|
|
296
|
+
|
|
297
|
+
● HIGH A2A04_PROMPT_PASSTHROUGH ASI01
|
|
298
|
+
User input flows directly from 'executor' to 'planner'
|
|
299
|
+
without sanitization at the agent boundary.
|
|
300
|
+
|
|
301
|
+
Trust Score 75/100 ███████████████░░░░░ WATCH
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Covers **ASI07** (Insecure Inter-Agent Communication) from OWASP Top 10 for Agentic Applications 2026.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
256
308
|
## Finding suppression
|
|
257
309
|
|
|
258
310
|
Use `--ignore-rule` to suppress specific findings by rule ID. Suppressed findings are excluded from `--fail-on` evaluation and output — they don't break CI gates.
|
|
@@ -278,7 +330,7 @@ SC03_HIDDEN_NETWORK_FIELDS # webhook field verified safe — used for audit log
|
|
|
278
330
|
NO_AUTH # server is behind an authenticated reverse proxy
|
|
279
331
|
```
|
|
280
332
|
|
|
281
|
-
Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
|
|
333
|
+
Supported on: `sentinel scan`, `sentinel a2a`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
|
|
282
334
|
|
|
283
335
|
---
|
|
284
336
|
|
|
@@ -292,7 +344,7 @@ Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `se
|
|
|
292
344
|
| **Agentic Supply Chain Compromise** | **ASI04** | **`sentinel supply-chain`** (static + AI), **`sentinel agentic`** |
|
|
293
345
|
| Unexpected Code Execution | ASI05 | `sentinel scan` (CODE_EXECUTION_GRANT), `sentinel mcp scan` |
|
|
294
346
|
| **Memory & Context Poisoning** | **ASI06** | **`sentinel secrets`** (memory contamination), **`sentinel agentic`** |
|
|
295
|
-
| Insecure Inter-Agent Communication | ASI07 | `sentinel agentic` (reasoning
|
|
347
|
+
| **Insecure Inter-Agent Communication** | **ASI07** | **`sentinel a2a`** (call graph + trust rules), `sentinel agentic` (semantic reasoning) |
|
|
296
348
|
| Cascading Agent Failures | ASI08 | `sentinel agentic` (cross-finding chain analysis) |
|
|
297
349
|
| Human-Agent Trust Exploitation | ASI09 | `sentinel agentic` (narrative + evidence standard) |
|
|
298
350
|
| Rogue Agents | ASI10 | `sentinel agentic` (drift detection across sessions) |
|
|
@@ -326,6 +378,9 @@ jobs:
|
|
|
326
378
|
|
|
327
379
|
- name: MCP security audit
|
|
328
380
|
run: sentinel mcp scan http://localhost:3001 --fail-on CRITICAL
|
|
381
|
+
|
|
382
|
+
- name: Multi-agent trust analysis
|
|
383
|
+
run: sentinel a2a ./agents/ --fail-on HIGH
|
|
329
384
|
```
|
|
330
385
|
|
|
331
386
|
Use a `.sentinelignore` file at the repo root to suppress known-accepted findings without weakening the gate threshold:
|
|
@@ -346,6 +401,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
|
|
|
346
401
|
| Investigating a specific server or codebase | `sentinel agentic` |
|
|
347
402
|
| First assessment of a new MCP server | `sentinel agentic` |
|
|
348
403
|
| Scheduled nightly security check | `sentinel agentic` (memory tracks drift) |
|
|
404
|
+
| Auditing a multi-agent codebase | `sentinel a2a` (call graph + trust rules) |
|
|
349
405
|
| Quick local sanity check | `sentinel mcp scan`, `sentinel scan` |
|
|
350
406
|
| Red-teaming a live agent endpoint | `sentinel ai-probe` |
|
|
351
407
|
|
|
@@ -355,7 +411,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
|
|
|
355
411
|
|
|
356
412
|
- Python 3.10+
|
|
357
413
|
- `ANTHROPIC_API_KEY` required for: `sentinel agentic`, `sentinel ai-probe`, `sentinel supply-chain --ai`, `sentinel inspect` (AI summary)
|
|
358
|
-
- No API key required for: `sentinel scan`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
|
|
414
|
+
- No API key required for: `sentinel scan`, `sentinel a2a`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
|
|
359
415
|
|
|
360
416
|
---
|
|
361
417
|
|
|
@@ -123,45 +123,46 @@ def _enrich_from_platform(agents, scores_map, connect_url, api_key):
|
|
|
123
123
|
|
|
124
124
|
@main.command()
|
|
125
125
|
@click.option("--process/--no-process", default=True, show_default=True,
|
|
126
|
-
help="Scan running processes for
|
|
126
|
+
help="Scan running processes for MCP servers and agent signals.")
|
|
127
127
|
@click.option("--network/--no-network", default=True, show_default=True,
|
|
128
|
-
help="Probe local ports
|
|
128
|
+
help="Probe local ports — confirmed via MCP protocol handshake.")
|
|
129
129
|
@click.option("--docker/--no-docker", default=False, show_default=True,
|
|
130
|
-
help="Inspect running Docker containers.")
|
|
131
|
-
@click.option("--path", "scan_path", default=None, type=click.Path(exists=True, path_type=Path),
|
|
132
|
-
metavar="DIR", help="Scan a directory for agent source files.")
|
|
130
|
+
help="Inspect running Docker containers for MCP/agent patterns.")
|
|
133
131
|
@click.option("--subnet", default=None, metavar="CIDR",
|
|
134
|
-
help="Scan a CIDR subnet for
|
|
132
|
+
help="Scan a CIDR subnet for MCP servers, e.g. 10.0.0.0/24.")
|
|
135
133
|
@click.option("--ports", default=None, metavar="RANGE",
|
|
136
|
-
help="Custom port range
|
|
134
|
+
help="Custom port range, e.g. 8000-9001. Defaults to common MCP/agent ports.")
|
|
135
|
+
@click.option("--auth-header", "auth_header", default=None, metavar="HEADER",
|
|
136
|
+
help="HTTP auth header for MCP handshakes, e.g. 'Authorization: Bearer token'.")
|
|
137
137
|
@click.option("--format", "fmt", type=click.Choice(["text", "json"]), default="text",
|
|
138
138
|
help="Output format.")
|
|
139
139
|
@click.option("--verbose", "-v", is_flag=True, default=False,
|
|
140
|
-
help="Show full details per discovered
|
|
140
|
+
help="Show full details per discovered server.")
|
|
141
141
|
def discover(
|
|
142
142
|
process: bool,
|
|
143
143
|
network: bool,
|
|
144
144
|
docker: bool,
|
|
145
|
-
scan_path: Path | None,
|
|
146
145
|
subnet: str | None,
|
|
147
146
|
ports: str | None,
|
|
147
|
+
auth_header: str | None,
|
|
148
148
|
fmt: str,
|
|
149
149
|
verbose: bool,
|
|
150
150
|
) -> None:
|
|
151
|
-
"""Find AI
|
|
151
|
+
"""Find MCP servers and AI agent processes in your environment.
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
Confirms MCP servers via protocol handshake — not just open ports.
|
|
154
|
+
Use --subnet to scan across a network range.
|
|
155
155
|
|
|
156
156
|
\b
|
|
157
157
|
Examples:
|
|
158
|
-
sentinel discover
|
|
159
|
-
sentinel discover --
|
|
160
|
-
sentinel discover --
|
|
161
|
-
|
|
162
|
-
sentinel discover --no-process
|
|
163
|
-
sentinel discover --
|
|
164
|
-
sentinel discover --
|
|
158
|
+
sentinel discover local processes + ports
|
|
159
|
+
sentinel discover --subnet 10.0.0.0/24 scan internal network
|
|
160
|
+
sentinel discover --subnet 10.0.0.0/24 \\
|
|
161
|
+
--auth-header 'Authorization: Bearer token' scan with credentials
|
|
162
|
+
sentinel discover --no-process network only
|
|
163
|
+
sentinel discover --docker include containers
|
|
164
|
+
sentinel discover --ports 8000-9001 custom port range
|
|
165
|
+
sentinel discover --format json machine-readable output
|
|
165
166
|
"""
|
|
166
167
|
from agentsentinel_cli.discover import run_discovery, as_json as discover_json
|
|
167
168
|
from agentsentinel_cli.discover_report import print_discover_result, print_subnet_progress
|
|
@@ -169,6 +170,15 @@ def discover(
|
|
|
169
170
|
# Parse port range
|
|
170
171
|
port_list = _parse_ports(ports) if ports else None
|
|
171
172
|
|
|
173
|
+
# Parse auth header
|
|
174
|
+
extra_headers: dict[str, str] = {}
|
|
175
|
+
if auth_header:
|
|
176
|
+
if ":" not in auth_header:
|
|
177
|
+
console.print("[red]Error:[/red] --auth-header must be 'Header-Name: value' format.")
|
|
178
|
+
sys.exit(1)
|
|
179
|
+
key, _, val = auth_header.partition(":")
|
|
180
|
+
extra_headers[key.strip()] = val.strip()
|
|
181
|
+
|
|
172
182
|
# Collect active scan vectors for the header
|
|
173
183
|
vectors = []
|
|
174
184
|
if process:
|
|
@@ -177,14 +187,12 @@ def discover(
|
|
|
177
187
|
vectors.append("network")
|
|
178
188
|
if subnet:
|
|
179
189
|
vectors.append(f"subnet ({subnet})")
|
|
180
|
-
if scan_path:
|
|
181
|
-
vectors.append(f"files ({scan_path})")
|
|
182
190
|
if docker:
|
|
183
191
|
vectors.append("docker")
|
|
184
192
|
|
|
185
193
|
if not vectors:
|
|
186
194
|
console.print("[yellow]No scan vectors selected — use at least one of: "
|
|
187
|
-
"--process, --network, --subnet, --
|
|
195
|
+
"--process, --network, --subnet, --docker[/yellow]")
|
|
188
196
|
sys.exit(1)
|
|
189
197
|
|
|
190
198
|
if fmt == "text":
|
|
@@ -197,9 +205,9 @@ def discover(
|
|
|
197
205
|
do_process=process,
|
|
198
206
|
do_network=network,
|
|
199
207
|
do_docker=docker,
|
|
200
|
-
scan_path=scan_path,
|
|
201
208
|
ports=port_list,
|
|
202
209
|
subnet=subnet,
|
|
210
|
+
extra_headers=extra_headers or None,
|
|
203
211
|
subnet_progress_cb=progress_cb,
|
|
204
212
|
)
|
|
205
213
|
|