@rexymayderio/sentinel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +295 -0
- package/dist/acquire/acquirer.d.ts +38 -0
- package/dist/acquire/acquirer.d.ts.map +1 -0
- package/dist/acquire/acquirer.js +178 -0
- package/dist/acquire/acquirer.js.map +1 -0
- package/dist/adapters/cli-approval-prompt.d.ts +13 -0
- package/dist/adapters/cli-approval-prompt.d.ts.map +1 -0
- package/dist/adapters/cli-approval-prompt.js +44 -0
- package/dist/adapters/cli-approval-prompt.js.map +1 -0
- package/dist/adapters/github-repo-client.d.ts +9 -0
- package/dist/adapters/github-repo-client.d.ts.map +1 -0
- package/dist/adapters/github-repo-client.js +48 -0
- package/dist/adapters/github-repo-client.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/node-process-runner.d.ts +8 -0
- package/dist/adapters/node-process-runner.d.ts.map +1 -0
- package/dist/adapters/node-process-runner.js +21 -0
- package/dist/adapters/node-process-runner.js.map +1 -0
- package/dist/adapters/npm-registry-client.d.ts +8 -0
- package/dist/adapters/npm-registry-client.d.ts.map +1 -0
- package/dist/adapters/npm-registry-client.js +66 -0
- package/dist/adapters/npm-registry-client.js.map +1 -0
- package/dist/analyzers/ai-prompt-analyzer.d.ts +7 -0
- package/dist/analyzers/ai-prompt-analyzer.d.ts.map +1 -0
- package/dist/analyzers/ai-prompt-analyzer.js +88 -0
- package/dist/analyzers/ai-prompt-analyzer.js.map +1 -0
- package/dist/analyzers/analyzer.d.ts +14 -0
- package/dist/analyzers/analyzer.d.ts.map +1 -0
- package/dist/analyzers/analyzer.js +11 -0
- package/dist/analyzers/analyzer.js.map +1 -0
- package/dist/analyzers/dependency-analyzer.d.ts +10 -0
- package/dist/analyzers/dependency-analyzer.d.ts.map +1 -0
- package/dist/analyzers/dependency-analyzer.js +79 -0
- package/dist/analyzers/dependency-analyzer.js.map +1 -0
- package/dist/analyzers/index.d.ts +13 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +30 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/install-script-analyzer.d.ts +7 -0
- package/dist/analyzers/install-script-analyzer.d.ts.map +1 -0
- package/dist/analyzers/install-script-analyzer.js +64 -0
- package/dist/analyzers/install-script-analyzer.js.map +1 -0
- package/dist/analyzers/match-evidence.d.ts +6 -0
- package/dist/analyzers/match-evidence.d.ts.map +1 -0
- package/dist/analyzers/match-evidence.js +15 -0
- package/dist/analyzers/match-evidence.js.map +1 -0
- package/dist/analyzers/metadata-analyzer.d.ts +7 -0
- package/dist/analyzers/metadata-analyzer.d.ts.map +1 -0
- package/dist/analyzers/metadata-analyzer.js +105 -0
- package/dist/analyzers/metadata-analyzer.js.map +1 -0
- package/dist/analyzers/network-analyzer.d.ts +7 -0
- package/dist/analyzers/network-analyzer.d.ts.map +1 -0
- package/dist/analyzers/network-analyzer.js +47 -0
- package/dist/analyzers/network-analyzer.js.map +1 -0
- package/dist/analyzers/rules/index.d.ts +19 -0
- package/dist/analyzers/rules/index.d.ts.map +1 -0
- package/dist/analyzers/rules/index.js +70 -0
- package/dist/analyzers/rules/index.js.map +1 -0
- package/dist/analyzers/secret-analyzer.d.ts +7 -0
- package/dist/analyzers/secret-analyzer.d.ts.map +1 -0
- package/dist/analyzers/secret-analyzer.js +33 -0
- package/dist/analyzers/secret-analyzer.js.map +1 -0
- package/dist/analyzers/source-analyzer.d.ts +7 -0
- package/dist/analyzers/source-analyzer.d.ts.map +1 -0
- package/dist/analyzers/source-analyzer.js +73 -0
- package/dist/analyzers/source-analyzer.js.map +1 -0
- package/dist/analyzers/static-code-analyzer.d.ts +7 -0
- package/dist/analyzers/static-code-analyzer.d.ts.map +1 -0
- package/dist/analyzers/static-code-analyzer.js +67 -0
- package/dist/analyzers/static-code-analyzer.js.map +1 -0
- package/dist/analyzers/test-path.d.ts +2 -0
- package/dist/analyzers/test-path.d.ts.map +1 -0
- package/dist/analyzers/test-path.js +32 -0
- package/dist/analyzers/test-path.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +176 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/spinner.d.ts +5 -0
- package/dist/cli/spinner.d.ts.map +1 -0
- package/dist/cli/spinner.js +39 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/permissions.d.ts +4 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +28 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/sentinel.d.ts +32 -0
- package/dist/core/sentinel.d.ts.map +1 -0
- package/dist/core/sentinel.js +164 -0
- package/dist/core/sentinel.js.map +1 -0
- package/dist/domain/artifact.d.ts +34 -0
- package/dist/domain/artifact.d.ts.map +1 -0
- package/dist/domain/artifact.js +2 -0
- package/dist/domain/artifact.js.map +1 -0
- package/dist/domain/finding.d.ts +22 -0
- package/dist/domain/finding.d.ts.map +1 -0
- package/dist/domain/finding.js +30 -0
- package/dist/domain/finding.js.map +1 -0
- package/dist/domain/index.d.ts +7 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +7 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/permission.d.ts +8 -0
- package/dist/domain/permission.d.ts.map +1 -0
- package/dist/domain/permission.js +21 -0
- package/dist/domain/permission.js.map +1 -0
- package/dist/domain/report.d.ts +35 -0
- package/dist/domain/report.d.ts.map +1 -0
- package/dist/domain/report.js +2 -0
- package/dist/domain/report.js.map +1 -0
- package/dist/domain/risk.d.ts +14 -0
- package/dist/domain/risk.d.ts.map +1 -0
- package/dist/domain/risk.js +15 -0
- package/dist/domain/risk.js.map +1 -0
- package/dist/domain/target.d.ts +12 -0
- package/dist/domain/target.d.ts.map +1 -0
- package/dist/domain/target.js +43 -0
- package/dist/domain/target.js.map +1 -0
- package/dist/engine/data-assessment.d.ts +10 -0
- package/dist/engine/data-assessment.d.ts.map +1 -0
- package/dist/engine/data-assessment.js +39 -0
- package/dist/engine/data-assessment.js.map +1 -0
- package/dist/engine/default-policy.d.ts +16 -0
- package/dist/engine/default-policy.d.ts.map +1 -0
- package/dist/engine/default-policy.js +15 -0
- package/dist/engine/default-policy.js.map +1 -0
- package/dist/engine/index.d.ts +4 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +4 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/policy-engine.d.ts +13 -0
- package/dist/engine/policy-engine.d.ts.map +1 -0
- package/dist/engine/policy-engine.js +78 -0
- package/dist/engine/policy-engine.js.map +1 -0
- package/dist/engine/risk-calculator.d.ts +15 -0
- package/dist/engine/risk-calculator.d.ts.map +1 -0
- package/dist/engine/risk-calculator.js +57 -0
- package/dist/engine/risk-calculator.js.map +1 -0
- package/dist/factory.d.ts +14 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +25 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +151 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/ports/approval-prompt.d.ts +5 -0
- package/dist/ports/approval-prompt.d.ts.map +1 -0
- package/dist/ports/approval-prompt.js +2 -0
- package/dist/ports/approval-prompt.js.map +1 -0
- package/dist/ports/clock.d.ts +5 -0
- package/dist/ports/clock.d.ts.map +1 -0
- package/dist/ports/clock.js +4 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/index.d.ts +6 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +6 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/ports/process-runner.d.ts +12 -0
- package/dist/ports/process-runner.d.ts.map +1 -0
- package/dist/ports/process-runner.js +2 -0
- package/dist/ports/process-runner.js.map +1 -0
- package/dist/ports/registry-client.d.ts +14 -0
- package/dist/ports/registry-client.d.ts.map +1 -0
- package/dist/ports/registry-client.js +2 -0
- package/dist/ports/registry-client.js.map +1 -0
- package/dist/ports/repo-client.d.ts +18 -0
- package/dist/ports/repo-client.d.ts.map +1 -0
- package/dist/ports/repo-client.js +2 -0
- package/dist/ports/repo-client.js.map +1 -0
- package/dist/report/index.d.ts +2 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +2 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/report-generator.d.ts +29 -0
- package/dist/report/report-generator.d.ts.map +1 -0
- package/dist/report/report-generator.js +167 -0
- package/dist/report/report-generator.js.map +1 -0
- package/package.json +50 -0
- package/skills/sentinel/SKILL.md +525 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sentinel
|
|
3
|
+
description: Use before installing anything - npm packages, GitHub repos, AI skills, MCP servers, extensions, Docker images, local folders/archives. Intercepts install requests, runs security verification via the Sentinel MCP, explains the risk, and only installs after approval. Also handles manual /verify-* and /compare requests.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sentinel Skill
|
|
7
|
+
|
|
8
|
+
> AI Security Assistant for Package, MCP, Skill, and Extension Verification
|
|
9
|
+
|
|
10
|
+
## Goal
|
|
11
|
+
|
|
12
|
+
Sentinel Skill acts as the user's security expert before any installation.
|
|
13
|
+
|
|
14
|
+
It automatically intercepts installation requests and also provides manual verification commands.
|
|
15
|
+
|
|
16
|
+
It never installs anything directly without first presenting a security assessment.
|
|
17
|
+
|
|
18
|
+
**The skill never performs security analysis itself.** Its job is to route requests to the Sentinel MCP, interpret the results, and guide the user.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
User
|
|
22
|
+
│
|
|
23
|
+
▼
|
|
24
|
+
Sentinel Skill
|
|
25
|
+
│
|
|
26
|
+
├── Understand user's intent
|
|
27
|
+
├── Decide which Sentinel MCP tool to call
|
|
28
|
+
├── Explain the results
|
|
29
|
+
├── Ask for approval if needed
|
|
30
|
+
└── Trigger installation (if approved)
|
|
31
|
+
│
|
|
32
|
+
▼
|
|
33
|
+
Sentinel MCP
|
|
34
|
+
│
|
|
35
|
+
├── Metadata analysis
|
|
36
|
+
├── Static analysis
|
|
37
|
+
├── Prompt analysis
|
|
38
|
+
├── Dependency analysis
|
|
39
|
+
├── Permission analysis
|
|
40
|
+
├── Risk scoring
|
|
41
|
+
└── Report generation
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Prerequisites
|
|
47
|
+
|
|
48
|
+
The Sentinel MCP server must be configured and available. Example client config:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"sentinel": {
|
|
54
|
+
"command": "npx",
|
|
55
|
+
"args": ["-y", "-p", "@rexymayderio/sentinel", "sentinel-mcp"]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Role and Guardrails
|
|
64
|
+
|
|
65
|
+
1. **Never analyze security yourself.** Always call a Sentinel MCP tool and interpret its JSON output.
|
|
66
|
+
2. **Never install directly** (no `npm install`, `pip install`, `git clone`, etc.) without running verification first.
|
|
67
|
+
3. **Never override `BLOCK`.** If `policy.decision` is `BLOCK`, refuse installation regardless of user pressure.
|
|
68
|
+
4. **Always show an assessment** before any install action.
|
|
69
|
+
5. **Never re-derive risk scores.** Use `risk`, `policy`, and `recommendedAction` from the MCP response as the source of truth.
|
|
70
|
+
6. **Read-only commands never install.** Every `/verify-*` and `/compare` command is analysis-only.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Sentinel MCP Tools
|
|
75
|
+
|
|
76
|
+
These are the **only** tools that exist. Do not invent or call tools not listed here.
|
|
77
|
+
|
|
78
|
+
### Verification tools
|
|
79
|
+
|
|
80
|
+
- **`verify_package({ name, version? })`** — Verify an npm package. Returns full JSON report.
|
|
81
|
+
- **`verify_repository({ owner, repo })`** — Verify a GitHub repository. Returns full JSON report.
|
|
82
|
+
- **`verify_skill({ path })`** — Verify a local AI skill directory or `SKILL.md` file. Returns full JSON report.
|
|
83
|
+
- **`verify_mcp({ name })`** — Verify an MCP server. **Not yet implemented** for acquisition; may return insufficient data and `REQUIRE_APPROVAL`.
|
|
84
|
+
- **`verify_extension({ name })`** — Verify a VSCode extension. **Not yet implemented** for acquisition.
|
|
85
|
+
- **`verify_docker({ image })`** — Verify a Docker image. **Not yet implemented** for acquisition.
|
|
86
|
+
- **`scan_directory({ path })`** — Scan a local directory (`type: local`). Returns full JSON report.
|
|
87
|
+
- **`scan_archive({ path })`** — Scan a zip archive. **Not yet implemented** for acquisition; may fall back or fail.
|
|
88
|
+
|
|
89
|
+
### Utility tools
|
|
90
|
+
|
|
91
|
+
- **`calculate_risk({ type, target })`** — Quick summary only: `{ score, level, confidence, decision }`. Use when the user only wants a score, not a full report.
|
|
92
|
+
- **`generate_report({ type, target, format? })`** — Full verification with formatted output. `format` is `terminal`, `json`, or `markdown` (default: `json`).
|
|
93
|
+
- **`approve_install({ type, target })`** — Returns `{ approvable, decision, risk, reasons, dataAssessment }` without installing.
|
|
94
|
+
|
|
95
|
+
### Install tool
|
|
96
|
+
|
|
97
|
+
- **`install({ type, target, confirm })`** — Verify and install. **`confirm` must be `true`**. `BLOCK` decisions cannot be overridden. Always verify first, explain, get approval, then call with `confirm: true`.
|
|
98
|
+
|
|
99
|
+
### Ecosystem `type` values for `calculate_risk`, `generate_report`, `approve_install`, and `install`
|
|
100
|
+
|
|
101
|
+
| User intent | `type` | `target` example |
|
|
102
|
+
|-------------|--------|------------------|
|
|
103
|
+
| npm package | `npm` | `express`, `lodash@4.17.21` |
|
|
104
|
+
| GitHub repo | `github` | `owner/repo` |
|
|
105
|
+
| AI skill | `skill` | `./skills/my-skill` |
|
|
106
|
+
| Local folder | `local` | `./my-project` |
|
|
107
|
+
| MCP server | `mcp` | `filesystem` |
|
|
108
|
+
| VSCode extension | `vscode` | `prettier` |
|
|
109
|
+
| Docker image | `docker` | `nginx` |
|
|
110
|
+
| Zip archive | `zip` | `./package.zip` |
|
|
111
|
+
|
|
112
|
+
Implemented today: `npm`, `github`, `skill`, `local`. Other types may fail acquisition and escalate to `REQUIRE_APPROVAL`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Automatic Triggers
|
|
117
|
+
|
|
118
|
+
Activate this skill automatically when the user says things like:
|
|
119
|
+
|
|
120
|
+
- "Install express"
|
|
121
|
+
- "Install @company/mcp-server"
|
|
122
|
+
- "Install filesystem MCP"
|
|
123
|
+
- "Install Cursor Rule"
|
|
124
|
+
- "Install Docker image nginx"
|
|
125
|
+
- "Install uv package"
|
|
126
|
+
- "Install cargo crate"
|
|
127
|
+
- "Install VSCode extension"
|
|
128
|
+
- "Install Claude Skill"
|
|
129
|
+
- "Install Gemini Skill"
|
|
130
|
+
- "Install GitHub repository"
|
|
131
|
+
- "Install anything from GitHub"
|
|
132
|
+
|
|
133
|
+
**Never install immediately.** Follow the interception flow below.
|
|
134
|
+
|
|
135
|
+
### Interception flow
|
|
136
|
+
|
|
137
|
+
```mermaid
|
|
138
|
+
flowchart TD
|
|
139
|
+
userIntent[UserInstallIntent] --> mapTarget[MapToEcosystemAndTarget]
|
|
140
|
+
mapTarget --> verify[CallSentinelVerifyTool]
|
|
141
|
+
verify --> parse[ParseJSONReport]
|
|
142
|
+
parse --> explain[ExplainInPlainEnglish]
|
|
143
|
+
explain --> decision{policy.decision}
|
|
144
|
+
decision -->|AUTO_APPROVE or APPROVE| askConfirm[AskUserToConfirm]
|
|
145
|
+
decision -->|WARN| warnAndAsk[SurfaceWarningsAndAsk]
|
|
146
|
+
decision -->|REQUIRE_APPROVAL| requireYes[ShowReasonsRequireExplicitYes]
|
|
147
|
+
decision -->|BLOCK| refuse[RefuseDoNotInstall]
|
|
148
|
+
askConfirm -->|UserYes| install[install confirm true]
|
|
149
|
+
warnAndAsk -->|UserYes| install
|
|
150
|
+
requireYes -->|UserYes| install
|
|
151
|
+
refuse --> done[End]
|
|
152
|
+
install --> result[ReportInstallResult]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Step-by-step
|
|
156
|
+
|
|
157
|
+
1. **Map intent** to ecosystem `type` and `target` (see table above).
|
|
158
|
+
2. **Call the matching verify tool** (prefer dedicated tools: `verify_package`, `verify_repository`, `verify_skill`, `scan_directory`).
|
|
159
|
+
3. **Parse the JSON** from the tool response.
|
|
160
|
+
4. **Present Explain Mode** (see below).
|
|
161
|
+
5. **Apply approval rules** based on `policy.decision` (see below).
|
|
162
|
+
6. **If approved**, call `install({ type, target, confirm: true })`.
|
|
163
|
+
7. **Report** install success or failure from the `install` response.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Manual Commands
|
|
168
|
+
|
|
169
|
+
All `/verify-*` commands are **read-only**. They never call `install`.
|
|
170
|
+
|
|
171
|
+
### `/verify-package <name>`
|
|
172
|
+
|
|
173
|
+
Verify an npm package.
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
/verify-package express
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**MCP call:** `verify_package({ name: "express" })`
|
|
180
|
+
|
|
181
|
+
Returns: overall risk, install script findings, dependency findings, metadata/reputation, permissions, policy decision, recommendation.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
### `/verify-python <name>`
|
|
186
|
+
|
|
187
|
+
Verify a PyPI package.
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
/verify-python requests
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**MCP call:** `generate_report({ type: "pip", target: "requests" })`
|
|
194
|
+
|
|
195
|
+
**Note:** PyPI acquisition is not yet implemented. Expect `REQUIRE_APPROVAL` with data-insufficiency reasons. Explain this to the user and recommend manual review.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### `/verify-mcp <name-or-url>`
|
|
200
|
+
|
|
201
|
+
Verify an MCP server.
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
/verify-mcp filesystem
|
|
205
|
+
/verify-mcp github.com/company/server
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**MCP call:** `verify_mcp({ name: "filesystem" })` or, for GitHub-hosted servers, `verify_repository({ owner, repo })` if the input is a repo URL.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### `/verify-skill <path>`
|
|
213
|
+
|
|
214
|
+
Verify an AI skill.
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
/verify-skill ./skills/git-helper
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**MCP call:** `verify_skill({ path: "./skills/git-helper" })`
|
|
221
|
+
|
|
222
|
+
Highlight findings in categories: `ai-prompt`, `permission`, `static-code`.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### `/verify-extension <name>`
|
|
227
|
+
|
|
228
|
+
Verify a VSCode extension.
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
/verify-extension prettier
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**MCP call:** `verify_extension({ name: "prettier" })`
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
### `/verify-docker <image>`
|
|
239
|
+
|
|
240
|
+
Verify a Docker image.
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
/verify-docker nginx
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**MCP call:** `verify_docker({ image: "nginx" })`
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
### `/verify-repository <owner/repo>`
|
|
251
|
+
|
|
252
|
+
Verify a Git repository.
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
/verify-repository owner/project
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**MCP call:** `verify_repository({ owner: "owner", repo: "project" })`
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### `/verify-folder <path>`
|
|
263
|
+
|
|
264
|
+
Scan a local project directory.
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
/verify-folder ./my-project
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**MCP call:** `scan_directory({ path: "./my-project" })`
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
### `/verify-file <path>`
|
|
275
|
+
|
|
276
|
+
Scan a local archive or file path.
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
/verify-file ./release.zip
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**MCP call:** `scan_archive({ path: "./release.zip" })`
|
|
283
|
+
|
|
284
|
+
For non-archive local paths, use `scan_directory` instead.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
### `/verify-report <type> <target> [format]`
|
|
289
|
+
|
|
290
|
+
Generate a complete formatted report.
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
/verify-report npm express markdown
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**MCP call:** `generate_report({ type: "npm", target: "express", format: "markdown" })`
|
|
297
|
+
|
|
298
|
+
Supported formats: `terminal`, `json`, `markdown`.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
### Derived commands (no separate MCP tool)
|
|
303
|
+
|
|
304
|
+
These filter the **same** verification report. Run the appropriate `verify_*` or `scan_*` tool first, then extract the relevant slice.
|
|
305
|
+
|
|
306
|
+
#### `/verify-permissions <type> <target>`
|
|
307
|
+
|
|
308
|
+
**MCP call:** verify tool for the target, then present `report.permissions`.
|
|
309
|
+
|
|
310
|
+
Example output sections: Filesystem, Network, Shell, Clipboard, Docker, Git, SSH, Secrets, Camera, Microphone — with risk explanation per permission.
|
|
311
|
+
|
|
312
|
+
#### `/verify-dependencies <type> <target>`
|
|
313
|
+
|
|
314
|
+
**MCP call:** verify tool for the target, then filter `report.findings` where `category === "dependency"`.
|
|
315
|
+
|
|
316
|
+
#### `/verify-install-script <type> <target>`
|
|
317
|
+
|
|
318
|
+
**MCP call:** verify tool for the target, then filter `report.findings` where `category === "install-script"`.
|
|
319
|
+
|
|
320
|
+
#### `/verify-prompt <path>`
|
|
321
|
+
|
|
322
|
+
**MCP call:** `verify_skill({ path })` or `scan_directory({ path })`, then filter `report.findings` where `category === "ai-prompt"`.
|
|
323
|
+
|
|
324
|
+
#### `/verify-url <url>`
|
|
325
|
+
|
|
326
|
+
**Not supported today.** Tell the user Sentinel cannot verify arbitrary URLs yet. Suggest verifying the underlying package, repository, or downloaded file instead.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### `/compare <target1> <target2> [...]`
|
|
331
|
+
|
|
332
|
+
Compare multiple packages. **No single MCP tool** — call `verify_package` for each candidate, then synthesize.
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
/compare express hono fastify
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
For each candidate:
|
|
339
|
+
|
|
340
|
+
1. `verify_package({ name: "express" })`
|
|
341
|
+
2. `verify_package({ name: "hono" })`
|
|
342
|
+
3. `verify_package({ name: "fastify" })`
|
|
343
|
+
|
|
344
|
+
Compare: `risk.score`, `risk.level`, `policy.decision`, finding counts by severity, dependency findings, install-script presence, permissions, positive signals. End with a clear recommendation citing evidence.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Interpreting Results
|
|
349
|
+
|
|
350
|
+
Every verify tool returns JSON (parse the `text` content from the MCP response). Key fields:
|
|
351
|
+
|
|
352
|
+
```json
|
|
353
|
+
{
|
|
354
|
+
"target": { "ecosystem": "npm", "raw": "express", "name": "express" },
|
|
355
|
+
"risk": {
|
|
356
|
+
"score": 31,
|
|
357
|
+
"level": "MEDIUM",
|
|
358
|
+
"confidence": 94,
|
|
359
|
+
"positiveSignals": 1,
|
|
360
|
+
"negativeSignals": 6
|
|
361
|
+
},
|
|
362
|
+
"policy": {
|
|
363
|
+
"decision": "REQUIRE_APPROVAL",
|
|
364
|
+
"reasons": ["Package has install scripts", "Package requires network access"],
|
|
365
|
+
"overrides": []
|
|
366
|
+
},
|
|
367
|
+
"dataAssessment": {
|
|
368
|
+
"sufficient": true,
|
|
369
|
+
"confidence": 94,
|
|
370
|
+
"reasons": []
|
|
371
|
+
},
|
|
372
|
+
"findings": [
|
|
373
|
+
{
|
|
374
|
+
"severity": "MEDIUM",
|
|
375
|
+
"category": "install-script",
|
|
376
|
+
"title": "Install script: prepare",
|
|
377
|
+
"description": "Package defines a prepare script",
|
|
378
|
+
"file": "package.json",
|
|
379
|
+
"positive": false
|
|
380
|
+
}
|
|
381
|
+
],
|
|
382
|
+
"permissions": [
|
|
383
|
+
{ "type": "network-internet", "description": "Internet network access" }
|
|
384
|
+
],
|
|
385
|
+
"summary": "...",
|
|
386
|
+
"recommendedAction": "REVIEW AND APPROVE BEFORE INSTALLING",
|
|
387
|
+
"scannedAt": "2026-06-26T...",
|
|
388
|
+
"durationMs": 1234
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Finding severities:** `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `INFO`
|
|
393
|
+
|
|
394
|
+
**Finding categories:** `metadata`, `source`, `repository`, `static-code`, `dependency`, `install-script`, `ai-prompt`, `permission`, `network`, `secret`, `binary`, `reputation`, `behavioral`
|
|
395
|
+
|
|
396
|
+
**Policy decisions:** `AUTO_APPROVE`, `APPROVE`, `WARN`, `REQUIRE_APPROVAL`, `BLOCK`
|
|
397
|
+
|
|
398
|
+
Do not invent scores or decisions. If `dataAssessment.sufficient` is `false`, surface `dataAssessment.reasons` and treat as needing manual review.
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## Approval Rules
|
|
403
|
+
|
|
404
|
+
Approval is keyed **strictly** off `policy.decision` from the MCP. Do not use custom risk thresholds.
|
|
405
|
+
|
|
406
|
+
| Decision | Behavior |
|
|
407
|
+
|----------|----------|
|
|
408
|
+
| `AUTO_APPROVE` | Safe to proceed. Still confirm with the user before calling `install`. |
|
|
409
|
+
| `APPROVE` | No policy violations. Confirm with user, then `install({ confirm: true })`. |
|
|
410
|
+
| `WARN` | Installable with caveats. Surface `policy.reasons` and top findings. Confirm, then install. |
|
|
411
|
+
| `REQUIRE_APPROVAL` | Human must explicitly approve. Show `policy.reasons` and `dataAssessment.reasons`. Require explicit "yes" before install. |
|
|
412
|
+
| `BLOCK` | **Refuse installation.** Do not call `install`. Explain why using specific findings. |
|
|
413
|
+
|
|
414
|
+
`install` with `confirm: true` still fails on `BLOCK`. Never attempt to bypass it.
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Explain Mode
|
|
419
|
+
|
|
420
|
+
Every verification response must include these sections.
|
|
421
|
+
|
|
422
|
+
### Executive Summary
|
|
423
|
+
|
|
424
|
+
Plain English. Example:
|
|
425
|
+
|
|
426
|
+
> This package appears reasonably safe but requires review. The maintainer has a long history. A `prepare` install script was detected. Network access is requested. No critical vulnerabilities were found in static analysis.
|
|
427
|
+
>
|
|
428
|
+
> **Recommendation:** Review and approve before installing.
|
|
429
|
+
|
|
430
|
+
### Technical Summary
|
|
431
|
+
|
|
432
|
+
- Risk score and level (`risk.score` / `risk.level`)
|
|
433
|
+
- Confidence (`risk.confidence`)
|
|
434
|
+
- Policy decision (`policy.decision`)
|
|
435
|
+
- Permissions requested (from `permissions`)
|
|
436
|
+
- Finding counts: Critical / High / Medium / Low / Info
|
|
437
|
+
- Data sufficiency (`dataAssessment.sufficient`)
|
|
438
|
+
|
|
439
|
+
### Findings
|
|
440
|
+
|
|
441
|
+
Group by severity. For each non-INFO finding, cite `title`, `description`, and `file` when present. Skip or collapse positive (`positive: true`) findings into a brief "Positive signals" line.
|
|
442
|
+
|
|
443
|
+
### Recommendation
|
|
444
|
+
|
|
445
|
+
Map `recommendedAction` to user language:
|
|
446
|
+
|
|
447
|
+
| `recommendedAction` | User-facing |
|
|
448
|
+
|---------------------|-------------|
|
|
449
|
+
| `SAFE TO INSTALL` | Proceed |
|
|
450
|
+
| `PROCEED WITH CAUTION` | Proceed with caution |
|
|
451
|
+
| `REVIEW AND APPROVE BEFORE INSTALLING` | Needs manual review |
|
|
452
|
+
| `DO NOT INSTALL` | Do not install |
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Conversation Workflows
|
|
457
|
+
|
|
458
|
+
### Installation flow
|
|
459
|
+
|
|
460
|
+
**User:** Install express
|
|
461
|
+
|
|
462
|
+
**Skill:** Running security verification...
|
|
463
|
+
|
|
464
|
+
**MCP:** `verify_package({ name: "express" })`
|
|
465
|
+
|
|
466
|
+
**Skill (summary):**
|
|
467
|
+
- Risk: MEDIUM (31/100)
|
|
468
|
+
- Confidence: 94%
|
|
469
|
+
- Decision: REQUIRE_APPROVAL
|
|
470
|
+
- Install script: prepare
|
|
471
|
+
- Network: yes
|
|
472
|
+
- Critical findings: 0
|
|
473
|
+
|
|
474
|
+
Would you like to install it?
|
|
475
|
+
|
|
476
|
+
**User:** Yes
|
|
477
|
+
|
|
478
|
+
**MCP:** `install({ type: "npm", target: "express", confirm: true })`
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
### Repository flow
|
|
483
|
+
|
|
484
|
+
**User:** Install github.com/owner/project
|
|
485
|
+
|
|
486
|
+
**MCP:** `verify_repository({ owner: "owner", repo: "project" })`
|
|
487
|
+
|
|
488
|
+
Present repository analysis, dependency findings, permissions, recommendation, then approval gate, then `install({ type: "github", target: "owner/project", confirm: true })`.
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
### Skill flow
|
|
493
|
+
|
|
494
|
+
**User:** Install this skill at ./my-skill
|
|
495
|
+
|
|
496
|
+
**MCP:** `verify_skill({ path: "./my-skill" })`
|
|
497
|
+
|
|
498
|
+
Highlight prompt injection, hidden instructions, permission requests, autonomous behaviors. Approval gate, then `install({ type: "skill", target: "./my-skill", confirm: true })`.
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## Personality
|
|
503
|
+
|
|
504
|
+
- **Tone:** Professional, concise, evidence-based.
|
|
505
|
+
- **Never exaggerate.** Match language to the actual severity and decision.
|
|
506
|
+
- **Always explain why.** Never say only "This is dangerous."
|
|
507
|
+
|
|
508
|
+
**Bad:** "This package is dangerous."
|
|
509
|
+
|
|
510
|
+
**Good:** "This package defines a `postinstall` script that runs `curl | bash` against an unverified domain, which is a common supply-chain attack pattern."
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Commands That Never Install
|
|
515
|
+
|
|
516
|
+
- Every `/verify-*` command
|
|
517
|
+
- `/compare`
|
|
518
|
+
- `calculate_risk`
|
|
519
|
+
- `generate_report`
|
|
520
|
+
- `approve_install` (check only)
|
|
521
|
+
- `verify_*` and `scan_*` tools
|
|
522
|
+
|
|
523
|
+
## Commands That Can Install
|
|
524
|
+
|
|
525
|
+
Only `install` — and only after verification, explanation, and user approval (except `BLOCK`, which is always refused).
|