awguard 1.1.1 → 1.5.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/CHANGELOG.md +24 -0
- package/README.md +86 -3
- package/action.yml +4 -4
- package/docs/awguard-badge.json +7 -0
- package/docs/launch-plan.md +31 -0
- package/docs/market-analysis.md +87 -0
- package/docs/roadmap.md +71 -0
- package/examples/.github/copilot-instructions.md +4 -0
- package/examples/.mcp.json +15 -0
- package/examples/README.md +7 -0
- package/package.json +5 -3
- package/src/cli.js +34 -3
- package/src/graph.js +18 -4
- package/src/inventory.js +148 -0
- package/src/migration.js +60 -6
- package/src/presets.js +6 -3
- package/src/remediation.js +78 -11
- package/src/reporters.js +20 -6
- package/src/scanner.js +629 -8
- package/src/score.js +125 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.0
|
|
4
|
+
|
|
5
|
+
- Add `--format inventory` to map agentic repository surfaces by workflows, agent context files, and MCP configs.
|
|
6
|
+
- Scan GitHub Copilot custom agents, reusable prompts, and repository skills under `.github/agents`, `.github/prompts`, and `.github/skills`.
|
|
7
|
+
- Add a scope expansion roadmap for policy mode, agent capability SBOMs, trend reports, and adoption tooling.
|
|
8
|
+
|
|
9
|
+
## 1.4.0
|
|
10
|
+
|
|
11
|
+
- Add `AWG013` for project MCP configs that start mutable packages, unpinned containers, or shell wrappers.
|
|
12
|
+
- Add `AWG014` for MCP configs that hardcode tokens, API keys, passwords, or authorization headers.
|
|
13
|
+
- Scan `.mcp.json`, `.vscode/mcp.json`, `.cursor/mcp.json`, Windsurf, Cline, Roo, and related MCP config files without executing configured servers.
|
|
14
|
+
|
|
15
|
+
## 1.3.0
|
|
16
|
+
|
|
17
|
+
- Add `AWG012` for risky persistent agent instruction files.
|
|
18
|
+
- Scan `AGENTS.md`, `CLAUDE.md`, `CODEX.md`, `GEMINI.md`, Copilot instructions, Cursor rules, and related instruction files.
|
|
19
|
+
- Flag instructions that bypass approvals, treat untrusted GitHub text as commands, or expose secrets.
|
|
20
|
+
|
|
21
|
+
## 1.2.0
|
|
22
|
+
|
|
23
|
+
- Add `--format score` for an Agentic Workflow Injection scorecard.
|
|
24
|
+
- Add `--format badge` for Shields.io endpoint badge JSON.
|
|
25
|
+
- Add a checked-in AWI risk badge for the project README.
|
|
26
|
+
|
|
3
27
|
## 1.1.1
|
|
4
28
|
|
|
5
29
|
- Add npm package metadata for the public `awguard` package.
|
package/README.md
CHANGED
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
[](https://github.com/Mughal-Baig/agentic-workflow-guard/actions/workflows/test.yml)
|
|
4
4
|
[](https://github.com/Mughal-Baig/agentic-workflow-guard/actions/workflows/code-scanning.yml)
|
|
5
5
|
[](https://github.com/Mughal-Baig/agentic-workflow-guard/releases)
|
|
6
|
+
[](https://www.npmjs.com/package/awguard)
|
|
7
|
+
[](docs/awguard-badge.json)
|
|
6
8
|
[](LICENSE)
|
|
7
9
|
|
|
8
|
-
`agentic-workflow-guard` is a small, zero-dependency scanner for GitHub Actions workflows
|
|
10
|
+
`agentic-workflow-guard` is a small, zero-dependency scanner for GitHub Actions workflows, persistent agent instruction files, and MCP configs used by AI coding agents, LLMs, or automated review bots.
|
|
9
11
|
|
|
10
|
-
It looks for a new class of CI/CD risk: untrusted issue, pull request, comment, or branch text flowing into an AI agent prompt, then into write-capable tools, secrets, or
|
|
12
|
+
It looks for a new class of CI/CD risk: untrusted issue, pull request, comment, or branch text flowing into an AI agent prompt, then into write-capable tools, secrets, shell scripts, persistent instructions that weaken review boundaries, or MCP servers that expand agent authority.
|
|
11
13
|
|
|
12
14
|
Its unique output is an **Agentic Workflow Injection attack graph**:
|
|
13
15
|
|
|
@@ -111,7 +113,7 @@ jobs:
|
|
|
111
113
|
## CLI
|
|
112
114
|
|
|
113
115
|
```bash
|
|
114
|
-
awguard [path] [--config file] [--preset name] [--format text|json|markdown|github|sarif|graph|html|migration] [--output file] [--baseline file] [--write-baseline file] [--fix-dry-run] [--fail-on none|low|medium|high|critical]
|
|
116
|
+
awguard [path] [--config file] [--preset name] [--format text|json|markdown|github|sarif|graph|html|migration|score|badge|inventory] [--output file] [--baseline file] [--write-baseline file] [--fix-dry-run] [--fail-on none|low|medium|high|critical]
|
|
115
117
|
```
|
|
116
118
|
|
|
117
119
|
Examples:
|
|
@@ -122,6 +124,9 @@ node ./bin/awguard.js . --config awguard.config.json
|
|
|
122
124
|
node ./bin/awguard.js . --preset strict --format graph
|
|
123
125
|
node ./bin/awguard.js . --format html --output awguard-report.html
|
|
124
126
|
node ./bin/awguard.js . --format migration --output awguard-migration.md
|
|
127
|
+
node ./bin/awguard.js . --format inventory
|
|
128
|
+
node ./bin/awguard.js . --format score
|
|
129
|
+
node ./bin/awguard.js . --format badge --output awguard-badge.json
|
|
125
130
|
node ./bin/awguard.js . --fix-dry-run
|
|
126
131
|
node ./bin/awguard.js . --format markdown --fail-on medium
|
|
127
132
|
node ./bin/awguard.js . --format sarif --output awguard.sarif --fail-on none
|
|
@@ -215,6 +220,74 @@ untrusted GitHub event text
|
|
|
215
220
|
-> safe outputs or approved apply job
|
|
216
221
|
```
|
|
217
222
|
|
|
223
|
+
## AWI Score And Badge
|
|
224
|
+
|
|
225
|
+
Generate a shareable Agentic Workflow Injection scorecard:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
node ./bin/awguard.js . --format score
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Generate a Shields.io endpoint badge JSON:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
node ./bin/awguard.js . --format badge --output docs/awguard-badge.json
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Then add a badge to your README:
|
|
238
|
+
|
|
239
|
+
```markdown
|
|
240
|
+
[](docs/awguard-badge.json)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The score starts at 100 and subtracts risk for critical, high, medium, and low findings. This makes AWGuard easy to show in a README without hiding the detailed SARIF, graph, and migration reports.
|
|
244
|
+
|
|
245
|
+
## Agentic Surface Inventory
|
|
246
|
+
|
|
247
|
+
Generate a repository map of agent-related surfaces:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
node ./bin/awguard.js . --format inventory
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The inventory groups scanned files into GitHub Actions workflows, persistent agent context files, and MCP configs. It shows which surfaces exist, which rules fired, and what to review next. This is useful before a team enables new coding agents because it answers: "Where can agents read instructions, get tools, or act in CI?"
|
|
254
|
+
|
|
255
|
+
## Agent Context Guard
|
|
256
|
+
|
|
257
|
+
AWGuard also scans persistent agent instruction files:
|
|
258
|
+
|
|
259
|
+
- `AGENTS.md`
|
|
260
|
+
- `CLAUDE.md`
|
|
261
|
+
- `CODEX.md`
|
|
262
|
+
- `GEMINI.md`
|
|
263
|
+
- `.github/copilot-instructions.md`
|
|
264
|
+
- `.github/instructions/*.instructions.md`
|
|
265
|
+
- `.github/agents/*.md`
|
|
266
|
+
- `.github/prompts/*.prompt.md`
|
|
267
|
+
- `.github/skills/**/SKILL.md`
|
|
268
|
+
- `.cursor/rules/*.{md,mdc,txt}`
|
|
269
|
+
- `.cursorrules`, `.windsurfrules`, and `.clinerules`
|
|
270
|
+
|
|
271
|
+
It flags instruction files that tell agents to bypass approvals, skip permission prompts, obey issue or PR text as commands, or expose secrets.
|
|
272
|
+
|
|
273
|
+
## MCP Trust Boundary Guard
|
|
274
|
+
|
|
275
|
+
AWGuard also scans project-scoped MCP config files without starting the configured servers:
|
|
276
|
+
|
|
277
|
+
- `.mcp.json`
|
|
278
|
+
- `mcp.json`
|
|
279
|
+
- `.vscode/mcp.json`
|
|
280
|
+
- `.cursor/mcp.json`
|
|
281
|
+
- `.windsurf/mcp_config.json`
|
|
282
|
+
- `.codeium/windsurf/mcp_config.json`
|
|
283
|
+
- `cline_mcp_settings.json`
|
|
284
|
+
- `.cline/mcp_settings.json`
|
|
285
|
+
- `.roo/mcp.json`
|
|
286
|
+
- `.kilocode/mcp.json`
|
|
287
|
+
- `claude_desktop_config.json`
|
|
288
|
+
|
|
289
|
+
It flags MCP configs that start mutable packages such as `npx package`, `uvx package@latest`, or unpinned Docker images, and configs that commit tokens, API keys, passwords, or authorization headers.
|
|
290
|
+
|
|
218
291
|
## Fix Dry Run
|
|
219
292
|
|
|
220
293
|
Print remediation guidance without editing files:
|
|
@@ -251,6 +324,9 @@ If you omit rule ids, the suppression applies to all findings on the target line
|
|
|
251
324
|
| AWG009 | Medium | `workflow_run` consuming artifacts before scripts |
|
|
252
325
|
| AWG010 | Low | Third-party actions in agent workflows not pinned to a SHA |
|
|
253
326
|
| AWG011 | Medium | Invalid suppression comments |
|
|
327
|
+
| AWG012 | High/Critical | Agent instruction files that weaken approval, permission, or secret boundaries |
|
|
328
|
+
| AWG013 | High | MCP configs that start mutable packages, unpinned containers, or shell wrappers |
|
|
329
|
+
| AWG014 | Critical | MCP configs that hardcode secrets, tokens, passwords, or auth headers |
|
|
254
330
|
|
|
255
331
|
## Example Finding
|
|
256
332
|
|
|
@@ -265,6 +341,12 @@ If you omit rule ids, the suppression applies to all findings on the target line
|
|
|
265
341
|
|
|
266
342
|
- Safe autofix for low-risk permission changes.
|
|
267
343
|
- Safe-output migration patch previews for common triage and review bots.
|
|
344
|
+
- Hosted AWI score API for dynamic cross-repository badges.
|
|
345
|
+
- Agent instruction file rule packs for Copilot, Claude Code, Codex, Gemini, Cursor, and Windsurf.
|
|
346
|
+
- MCP config rule packs for Claude Code, Copilot, VS Code, Cursor, Windsurf, Cline, and Roo.
|
|
347
|
+
- Policy mode for approved MCP packages, actions, token scopes, and agent context files.
|
|
348
|
+
- Agent capability SBOM for prompts, tools, MCP servers, permissions, and write paths.
|
|
349
|
+
- Trend reports that show newly added agent surfaces and newly introduced findings.
|
|
268
350
|
- GitHub App integration for always-on repository monitoring.
|
|
269
351
|
- Rule packs for Claude Code, Codex, Gemini, Copilot, Aider, and custom agents.
|
|
270
352
|
- Public vulnerable workflow lab with attack and fix walkthroughs.
|
|
@@ -272,3 +354,4 @@ If you omit rule ids, the suppression applies to all findings on the target line
|
|
|
272
354
|
## Research Backing
|
|
273
355
|
|
|
274
356
|
See [docs/market-analysis.md](docs/market-analysis.md) for the demand analysis, gap, audience, and launch plan.
|
|
357
|
+
See [docs/roadmap.md](docs/roadmap.md) for the scope expansion roadmap.
|
package/action.yml
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
name: Agentic Workflow Guard
|
|
2
|
-
description: Scan GitHub Actions workflows for AI-agent injection and unsafe
|
|
2
|
+
description: Scan GitHub Actions workflows, agent instruction files, and MCP configs for AI-agent injection and unsafe tool boundaries.
|
|
3
3
|
author: agentic-workflow-guard
|
|
4
4
|
inputs:
|
|
5
5
|
path:
|
|
6
|
-
description: Repository path or
|
|
6
|
+
description: Repository path, workflow file, agent instruction file, or MCP config file to scan.
|
|
7
7
|
required: false
|
|
8
8
|
default: .
|
|
9
9
|
format:
|
|
10
|
-
description: Output format: github, text, json, markdown, sarif, graph, html, or
|
|
10
|
+
description: Output format: github, text, json, markdown, sarif, graph, html, migration, score, badge, or inventory.
|
|
11
11
|
required: false
|
|
12
12
|
default: github
|
|
13
13
|
fail-on:
|
|
@@ -15,7 +15,7 @@ inputs:
|
|
|
15
15
|
required: false
|
|
16
16
|
default: high
|
|
17
17
|
output:
|
|
18
|
-
description: Optional file path for json, markdown, sarif, graph, html, or
|
|
18
|
+
description: Optional file path for json, markdown, sarif, graph, html, migration, score, or badge output.
|
|
19
19
|
required: false
|
|
20
20
|
default: ''
|
|
21
21
|
baseline:
|
package/docs/launch-plan.md
CHANGED
|
@@ -32,6 +32,34 @@ Short pitch:
|
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
7. Show the migration from unsafe agent job to read-only proposal job plus safe outputs or an approved apply job.
|
|
35
|
+
8. Run:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
node ./bin/awguard.js . --format score
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
9. Show the README badge and say: "Add an AWI risk badge to your repo before adding AI agents to CI."
|
|
42
|
+
10. Run:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
node ./bin/awguard.js . --format inventory
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
11. Show the surface map and say: "Before you secure agent workflows, find every place the repository gives agents instructions or tools."
|
|
49
|
+
12. Show an unsafe `AGENTS.md` or `.github/copilot-instructions.md` line and run:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
node ./bin/awguard.js . --format text
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
13. Explain that AWGuard scans both the workflow and the persistent agent instructions that shape agent behavior.
|
|
56
|
+
14. Show an unsafe `.mcp.json` with `npx @modelcontextprotocol/server-github` and a committed token, then run:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
node ./bin/awguard.js examples/.mcp.json --format text
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
15. Explain the new hook: "This scanner checks repo-provided MCP tool wiring without executing the MCP server."
|
|
35
63
|
|
|
36
64
|
## Release Checklist
|
|
37
65
|
|
|
@@ -42,6 +70,9 @@ Short pitch:
|
|
|
42
70
|
- Post with the headline: "I built a scanner that maps and migrates Agentic Workflow Injection in GitHub Actions."
|
|
43
71
|
- Include the AWI attack chain screenshot in social posts.
|
|
44
72
|
- Include the migration report screenshot after the graph screenshot.
|
|
73
|
+
- Include the AWI risk badge as the final screenshot because it is the easiest artifact for other maintainers to copy.
|
|
74
|
+
- Include a short "workflow looked safe, AGENTS.md made it unsafe" example because it is the most surprising hook.
|
|
75
|
+
- Include a short "MCP config looked like developer tooling, but it gave the agent a mutable tool server and a token" example because MCP is the hottest adjacent security topic.
|
|
45
76
|
|
|
46
77
|
## Distribution Targets
|
|
47
78
|
|
package/docs/market-analysis.md
CHANGED
|
@@ -139,6 +139,82 @@ The unscoped npm package name `agentic-workflow-guard` is already published by a
|
|
|
139
139
|
|
|
140
140
|
The v1.1 package target is now `awguard`, matching the existing CLI binary and leaving the GitHub Action name unchanged.
|
|
141
141
|
|
|
142
|
+
## Deep Research Refresh: Badge And Scorecard Hook
|
|
143
|
+
|
|
144
|
+
The next reach improvement is a shareable AWI score and README badge. OpenSSF Scorecard has more than 5,000 GitHub stars and explicitly uses badges as a way for maintainers to show security posture. Shields.io is the common README-badge layer across GitHub projects. That pattern matters because a scanner hidden in CI logs does not travel; a badge travels with every repository that adopts it.
|
|
145
|
+
|
|
146
|
+
Recent GitHub and web research suggests this gap is still open:
|
|
147
|
+
|
|
148
|
+
- General GitHub Actions tools such as `zizmorcore/zizmor` and `rhysd/actionlint` are established, but they are not focused on Agentic Workflow Injection scoring.
|
|
149
|
+
- Broad AI-agent scanners such as AgentShield and agentic-radar cover MCP, skills, and agent configuration, but they do not own a GitHub Actions AWI score badge.
|
|
150
|
+
- GitHub search for `agentic workflow injection` shows only small early projects, which means the term is still young enough for a focused tool to become the reference implementation.
|
|
151
|
+
- Shields.io endpoint badges are easy to adopt because they only need a small JSON document.
|
|
152
|
+
|
|
153
|
+
Agentic Workflow Guard now supports:
|
|
154
|
+
|
|
155
|
+
- `--format score` for a Markdown AWI scorecard.
|
|
156
|
+
- `--format badge` for Shields.io endpoint JSON.
|
|
157
|
+
- A checked-in project badge at `docs/awguard-badge.json`.
|
|
158
|
+
|
|
159
|
+
The scorecard is intentionally simple: start at 100, subtract weighted penalties for critical, high, medium, and low findings, then show an A-F grade. This gives maintainers a quick public signal while keeping SARIF, attack graphs, and migration reports available for detailed review.
|
|
160
|
+
|
|
161
|
+
## Deep Research Refresh: Agent Context Guard
|
|
162
|
+
|
|
163
|
+
The next uniqueness gap is persistent agent instruction files. GitHub documents repository custom instructions through `.github/copilot-instructions.md`, OpenAI Codex documents `AGENTS.md`, and the public `agents.md` project positions `AGENTS.md` as a predictable place for coding-agent guidance. Claude Code also documents permission modes and warns that bypassing permissions is a special, dangerous mode.
|
|
164
|
+
|
|
165
|
+
That means agent safety is no longer only in workflow YAML. A repository can have conservative GitHub Actions permissions while `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, Cursor rules, or Copilot instructions tell the agent to skip approval, obey issue comments, or expose credentials. General GitHub Actions linters do not inspect these files, and broad AI security scanners do not own the GitHub Actions plus persistent-instructions intersection.
|
|
166
|
+
|
|
167
|
+
Agentic Workflow Guard now supports `AWG012` to scan common instruction files for risky persistent guidance:
|
|
168
|
+
|
|
169
|
+
- bypassing approvals, confirmations, or permission prompts;
|
|
170
|
+
- treating issue, PR, comment, branch, or artifact text as commands;
|
|
171
|
+
- allowing secrets, tokens, API keys, or credentials to be printed, returned, or sent.
|
|
172
|
+
|
|
173
|
+
This strengthens the project's position as an Agentic Workflow Injection guardrail instead of only another YAML scanner.
|
|
174
|
+
|
|
175
|
+
## Deep Research Refresh: MCP Trust Boundary Guard
|
|
176
|
+
|
|
177
|
+
The next gap is project-scoped MCP configuration. Claude Code documents `.mcp.json` as a project-root file designed to be checked into version control, VS Code documents workspace MCP config at `.vscode/mcp.json`, and GitHub Copilot documents MCP servers as additional tools for CLI agents. That means a repository can now ship the tool wiring an agent will trust, not only the workflow that starts the agent.
|
|
178
|
+
|
|
179
|
+
GitHub and web research show that MCP security is popular but crowded at the live-server/tool-description layer:
|
|
180
|
+
|
|
181
|
+
- `snyk/agent-scan` has roughly 2.5k GitHub stars and scans MCP servers, tools, resources, and skills, but its README warns that scanning MCP configurations executes the configured commands.
|
|
182
|
+
- `cisco-ai-defense/mcp-scanner` has roughly 900+ GitHub stars and focuses on MCP server threats.
|
|
183
|
+
- Other GitHub search results for `mcp scanner` are smaller server scanners, while searches for `agentic workflow injection` still show only tiny early projects.
|
|
184
|
+
|
|
185
|
+
The opening for Agentic Workflow Guard is a zero-execution repository scan:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
checked-in MCP config -> mutable package or shell startup -> agent gains unexpected tools
|
|
189
|
+
checked-in MCP config -> committed token/header -> agent gains credentialed external access
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Agentic Workflow Guard now supports:
|
|
193
|
+
|
|
194
|
+
- `AWG013` for project MCP configs that start mutable packages, `@latest` specs, unpinned containers, or shell wrappers.
|
|
195
|
+
- `AWG014` for committed tokens, API keys, passwords, bearer headers, and other MCP auth material.
|
|
196
|
+
- Discovery for `.mcp.json`, `.vscode/mcp.json`, `.cursor/mcp.json`, Windsurf, Cline, Roo, and related MCP config files.
|
|
197
|
+
|
|
198
|
+
This keeps the project focused: AWGuard does not try to replace MCP runtime scanners. It gives maintainers a GitHub-native, zero-dependency first check before an agent or scanner executes repo-provided MCP server commands.
|
|
199
|
+
|
|
200
|
+
## Deep Research Refresh: Agentic Surface Inventory
|
|
201
|
+
|
|
202
|
+
The next scope expansion is an inventory view. GitHub now documents repository-level custom agents in `.github/agents`, Copilot MCP configuration, and custom instructions. VS Code documents workspace MCP config. This means the repository itself can contain multiple agent-control surfaces before a single workflow runs.
|
|
203
|
+
|
|
204
|
+
The useful maintainer question is no longer only "is this workflow unsafe?" It is:
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
what agent surfaces does this repository expose, and which ones changed?
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Agentic Workflow Guard now supports:
|
|
211
|
+
|
|
212
|
+
- `--format inventory` for a surface map grouped by workflows, agent context files, and MCP configs.
|
|
213
|
+
- scanning `.github/agents/*.md`, `.github/prompts/*.prompt.md`, and `.github/skills/**/SKILL.md` as persistent agent context.
|
|
214
|
+
- a roadmap that moves toward policy mode, agent capability SBOMs, trend reports, and adoption generators.
|
|
215
|
+
|
|
216
|
+
This widens the project while preserving its niche: AWGuard remains a zero-execution repository scanner for agentic risk, not a broad runtime agent firewall.
|
|
217
|
+
|
|
142
218
|
## Distribution Plan
|
|
143
219
|
|
|
144
220
|
1. Publish the repo with a short demo GIF or screenshot.
|
|
@@ -155,6 +231,17 @@ The v1.1 package target is now `awguard`, matching the existing CLI binary and l
|
|
|
155
231
|
- GitHub SARIF upload docs: https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/integrate-with-existing-tools/uploading-a-sarif-file-to-github
|
|
156
232
|
- GitHub Actions secure use reference: https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use
|
|
157
233
|
- GitHub Agentic Workflows security architecture: https://github.github.com/gh-aw/
|
|
234
|
+
- GitHub Copilot repository custom instructions: https://docs.github.com/en/copilot/how-tos/custom-instructions/adding-repository-custom-instructions-for-github-copilot
|
|
235
|
+
- GitHub Copilot CLI MCP command reference: https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference#mcp-server-configuration
|
|
236
|
+
- GitHub Copilot MCP in VS Code: https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp-in-your-ide/extend-copilot-chat-with-mcp
|
|
237
|
+
- VS Code MCP configuration reference: https://code.visualstudio.com/docs/copilot/reference/mcp-configuration
|
|
238
|
+
- Claude Code MCP documentation: https://code.claude.com/docs/en/mcp
|
|
239
|
+
- Snyk Agent Scan / MCP Scan: https://github.com/snyk/agent-scan
|
|
240
|
+
- Cisco AI Defense MCP Scanner: https://github.com/cisco-ai-defense/mcp-scanner
|
|
241
|
+
- MCP threat modeling and tool poisoning research: https://arxiv.org/abs/2603.22489
|
|
242
|
+
- OpenAI Codex AGENTS.md documentation: https://github.com/openai/codex/blob/main/docs/agents_md.md
|
|
243
|
+
- AGENTS.md project: https://github.com/openai/agents.md
|
|
244
|
+
- Claude Code permission modes: https://code.claude.com/docs/en/permission-modes
|
|
158
245
|
- OpenSSF Scorecard dangerous workflow check: https://github.com/ossf/scorecard/blob/main/docs/checks.md#dangerous-workflow
|
|
159
246
|
- Semgrep inline ignore docs: https://semgrep.dev/docs/ignoring-files-folders-code
|
|
160
247
|
- ESLint configuration comment descriptions: https://eslint.org/docs/latest/use/configure/rules#configuration-comment-descriptions
|
package/docs/roadmap.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Scope Expansion Roadmap
|
|
2
|
+
|
|
3
|
+
## Research Signal
|
|
4
|
+
|
|
5
|
+
AWGuard should widen from "workflow scanner" into an agentic repository safety map while staying small and zero-dependency.
|
|
6
|
+
|
|
7
|
+
Current research points:
|
|
8
|
+
|
|
9
|
+
- GitHub Copilot now documents repository-level custom agents in `.github/agents`, repository MCP configuration, and repo-scoped agent behavior.
|
|
10
|
+
- VS Code and Copilot document MCP configuration in repository or workspace files such as `.vscode/mcp.json`.
|
|
11
|
+
- GitHub Actions security docs still warn that attacker-controlled GitHub context must be treated as untrusted input.
|
|
12
|
+
- OpenSSF Scorecard shows that security tools travel further when they produce a simple public score, badge, and clear adoption path.
|
|
13
|
+
- Existing MCP scanners focus on live server/tool inspection; AWGuard's lane is zero-execution repository scanning before those tools start.
|
|
14
|
+
|
|
15
|
+
## Feature List
|
|
16
|
+
|
|
17
|
+
1. Agentic Surface Inventory
|
|
18
|
+
- Add `--format inventory`.
|
|
19
|
+
- Group scanned files into GitHub Actions workflows, agent context files, and MCP configs.
|
|
20
|
+
- Show findings, highest severity, and recommended next steps per surface.
|
|
21
|
+
|
|
22
|
+
2. Wider Agent Context Coverage
|
|
23
|
+
- Scan `.github/agents/*.md` for Copilot custom agents.
|
|
24
|
+
- Scan `.github/prompts/*.prompt.md` for reusable prompts.
|
|
25
|
+
- Scan `.github/skills/**/SKILL.md` for repository skills.
|
|
26
|
+
- Keep using `AWG012` for risky persistent instructions.
|
|
27
|
+
|
|
28
|
+
3. Policy Mode
|
|
29
|
+
- Add an `awguard.policy.json` format for explicit allowlists.
|
|
30
|
+
- Allow approved MCP commands, package pins, Docker digests, action owners, and workflow write scopes.
|
|
31
|
+
- Report drift when the repository adds a new agent surface without policy.
|
|
32
|
+
|
|
33
|
+
4. Setup And Adoption Generator
|
|
34
|
+
- Add a command that prints a starter GitHub Action, strict config, baseline command, and badge snippet.
|
|
35
|
+
- Keep it as a print-only generator first so it remains safe.
|
|
36
|
+
|
|
37
|
+
5. Agent Capability SBOM
|
|
38
|
+
- Export a machine-readable inventory of agent prompts, tools, MCP servers, permissions, secrets exposure, and write capabilities.
|
|
39
|
+
- Make it useful for security reviews and audits.
|
|
40
|
+
|
|
41
|
+
6. Trend Reports
|
|
42
|
+
- Compare current scan output with a previous JSON report.
|
|
43
|
+
- Show newly added agent surfaces and newly introduced rules.
|
|
44
|
+
|
|
45
|
+
7. Vulnerable Lab
|
|
46
|
+
- Add a set of intentionally unsafe mini-repositories under examples or a separate demo repo.
|
|
47
|
+
- Each lab should include exploit explanation, AWGuard output, and fixed pattern.
|
|
48
|
+
|
|
49
|
+
8. GitHub App Or Scheduled Monitor
|
|
50
|
+
- Long-term: run continuously across repositories.
|
|
51
|
+
- Open issues when new agent surfaces appear or risk score drops.
|
|
52
|
+
|
|
53
|
+
## Work Plan
|
|
54
|
+
|
|
55
|
+
### Now
|
|
56
|
+
|
|
57
|
+
- Ship `--format inventory`.
|
|
58
|
+
- Expand `AWG012` coverage to Copilot custom agents, prompts, and skills.
|
|
59
|
+
- Document the widened project roadmap.
|
|
60
|
+
|
|
61
|
+
### Next
|
|
62
|
+
|
|
63
|
+
- Add policy mode for MCP server allowlists and approved agent context files.
|
|
64
|
+
- Add a setup generator for the GitHub Action, config, baseline, and README badge.
|
|
65
|
+
- Add JSON inventory output for downstream dashboards.
|
|
66
|
+
|
|
67
|
+
### Later
|
|
68
|
+
|
|
69
|
+
- Add trend reports for "new agent surface introduced" diffs.
|
|
70
|
+
- Build the vulnerable lab and screenshot-friendly walkthroughs.
|
|
71
|
+
- Explore a GitHub App after the CLI and Action adoption path is stable.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"github": {
|
|
4
|
+
"command": "npx",
|
|
5
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
6
|
+
"env": {
|
|
7
|
+
"GITHUB_TOKEN": "ghp_exampletokenexampletokenexampletoken"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"browser": {
|
|
11
|
+
"command": "docker",
|
|
12
|
+
"args": ["run", "--rm", "example/mcp-browser:latest"]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/examples/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
- `safe-agent.yml`: quieter workflow with read-only permissions and bounded prompt file.
|
|
5
5
|
- `suppressed-agent.yml`: demonstrates audited inline suppressions.
|
|
6
6
|
- `pull-request-target.yml`: demonstrates privileged PR checkout risk.
|
|
7
|
+
- `.github/copilot-instructions.md`: demonstrates risky persistent agent instruction guidance.
|
|
8
|
+
- `.mcp.json`: demonstrates mutable MCP server packages and committed MCP credentials.
|
|
7
9
|
- `awguard.config.example.json`: sample config with a strict preset and overrides.
|
|
8
10
|
|
|
9
11
|
Try:
|
|
@@ -12,5 +14,10 @@ Try:
|
|
|
12
14
|
node ../bin/awguard.js unsafe-agent.yml --format graph
|
|
13
15
|
node ../bin/awguard.js unsafe-agent.yml --format html --output awguard-report.html
|
|
14
16
|
node ../bin/awguard.js unsafe-agent.yml --format migration
|
|
17
|
+
node ../bin/awguard.js . --format inventory
|
|
18
|
+
node ../bin/awguard.js unsafe-agent.yml --format score
|
|
19
|
+
node ../bin/awguard.js safe-agent.yml --format badge
|
|
20
|
+
node ../bin/awguard.js .mcp.json --format text
|
|
21
|
+
node ../bin/awguard.js . --format text
|
|
15
22
|
node ../bin/awguard.js unsafe-agent.yml --fix-dry-run
|
|
16
23
|
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "awguard",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Scan GitHub Actions workflows for AI-agent injection
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "Scan GitHub Actions workflows, agent instructions, and MCP configs for AI-agent injection and unsafe tool boundaries.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/Mughal-Baig/agentic-workflow-guard#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
"devsecops",
|
|
28
28
|
"llm",
|
|
29
29
|
"agentic-workflow-injection",
|
|
30
|
-
"safe-outputs"
|
|
30
|
+
"safe-outputs",
|
|
31
|
+
"mcp",
|
|
32
|
+
"model-context-protocol"
|
|
31
33
|
],
|
|
32
34
|
"license": "MIT",
|
|
33
35
|
"engines": {
|
package/src/cli.js
CHANGED
|
@@ -5,20 +5,36 @@ import { applyBaseline, createBaseline, loadBaseline, writeBaseline } from './ba
|
|
|
5
5
|
import { loadConfig } from './config.js';
|
|
6
6
|
import { renderFixDryRun } from './remediation.js';
|
|
7
7
|
import { scanWorkflows, severityRank } from './scanner.js';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
renderBadge,
|
|
10
|
+
renderGithubAnnotations,
|
|
11
|
+
renderGraph,
|
|
12
|
+
renderHtml,
|
|
13
|
+
renderJson,
|
|
14
|
+
renderMarkdown,
|
|
15
|
+
renderMigration,
|
|
16
|
+
renderSarif,
|
|
17
|
+
renderScore,
|
|
18
|
+
renderSurfaceInventory,
|
|
19
|
+
renderText
|
|
20
|
+
} from './reporters.js';
|
|
9
21
|
|
|
10
22
|
const HELP = `Agentic Workflow Guard
|
|
11
23
|
|
|
12
24
|
Usage:
|
|
13
|
-
awguard [path] [--config file] [--preset name] [--format text|json|markdown|github|sarif|graph|html|migration] [--output file] [--baseline file] [--write-baseline file] [--fix-dry-run] [--fail-on none|low|medium|high|critical]
|
|
25
|
+
awguard [path] [--config file] [--preset name] [--format text|json|markdown|github|sarif|graph|html|migration|score|badge|inventory] [--output file] [--baseline file] [--write-baseline file] [--fix-dry-run] [--fail-on none|low|medium|high|critical]
|
|
14
26
|
|
|
15
27
|
Examples:
|
|
16
28
|
awguard .
|
|
29
|
+
awguard .mcp.json
|
|
17
30
|
awguard . --config awguard.config.json
|
|
18
31
|
awguard . --preset strict --format graph
|
|
19
32
|
awguard .github/workflows/agent.yml --format markdown --fail-on high
|
|
20
33
|
awguard . --format html --output awguard-report.html
|
|
21
34
|
awguard . --format migration --output awguard-migration.md
|
|
35
|
+
awguard . --format inventory
|
|
36
|
+
awguard . --format score
|
|
37
|
+
awguard . --format badge --output awguard-badge.json
|
|
22
38
|
awguard . --fix-dry-run
|
|
23
39
|
awguard . --format sarif --output awguard.sarif --fail-on none
|
|
24
40
|
awguard . --write-baseline awguard.baseline.json
|
|
@@ -118,7 +134,19 @@ export function parseArgs(args, env = {}) {
|
|
|
118
134
|
}
|
|
119
135
|
}
|
|
120
136
|
|
|
121
|
-
validateEnum('format', options.format, [
|
|
137
|
+
validateEnum('format', options.format, [
|
|
138
|
+
'text',
|
|
139
|
+
'json',
|
|
140
|
+
'markdown',
|
|
141
|
+
'github',
|
|
142
|
+
'sarif',
|
|
143
|
+
'graph',
|
|
144
|
+
'html',
|
|
145
|
+
'migration',
|
|
146
|
+
'score',
|
|
147
|
+
'badge',
|
|
148
|
+
'inventory'
|
|
149
|
+
]);
|
|
122
150
|
validateEnum('fail-on', options.failOn, ['none', 'low', 'medium', 'high', 'critical']);
|
|
123
151
|
|
|
124
152
|
return options;
|
|
@@ -136,6 +164,9 @@ function render(result, format) {
|
|
|
136
164
|
if (format === 'graph') return renderGraph(result);
|
|
137
165
|
if (format === 'html') return renderHtml(result);
|
|
138
166
|
if (format === 'migration') return renderMigration(result);
|
|
167
|
+
if (format === 'score') return renderScore(result);
|
|
168
|
+
if (format === 'badge') return renderBadge(result);
|
|
169
|
+
if (format === 'inventory') return renderSurfaceInventory(result);
|
|
139
170
|
if (format === 'github') return renderGithubAnnotations(result);
|
|
140
171
|
return renderText(result);
|
|
141
172
|
}
|
package/src/graph.js
CHANGED
|
@@ -11,7 +11,10 @@ const impactByRule = {
|
|
|
11
11
|
AWG008: 'Default token permissions may be broader than intended',
|
|
12
12
|
AWG009: 'Untrusted artifacts can influence privileged jobs',
|
|
13
13
|
AWG010: 'Mutable third-party action can change behavior',
|
|
14
|
-
AWG011: 'Suppression policy can hide real risk'
|
|
14
|
+
AWG011: 'Suppression policy can hide real risk',
|
|
15
|
+
AWG012: 'Persistent agent instructions can weaken CI guardrails',
|
|
16
|
+
AWG013: 'Mutable MCP tool server can change agent capabilities',
|
|
17
|
+
AWG014: 'Committed MCP credential can expose external tools or data'
|
|
15
18
|
};
|
|
16
19
|
|
|
17
20
|
export function buildAttackGraphs(result) {
|
|
@@ -42,7 +45,7 @@ export function renderGraphMarkdown(result) {
|
|
|
42
45
|
const lines = [
|
|
43
46
|
'# Agentic Workflow Guard Attack Graph',
|
|
44
47
|
'',
|
|
45
|
-
`Scanned
|
|
48
|
+
`Scanned files: **${result.scannedFiles.length}**`,
|
|
46
49
|
`Findings: **${result.summary.total}**`,
|
|
47
50
|
`Attack chains: **${attackGraph.summary.chains}**`,
|
|
48
51
|
''
|
|
@@ -159,11 +162,11 @@ export function renderHtmlReport(result) {
|
|
|
159
162
|
<body>
|
|
160
163
|
<header>
|
|
161
164
|
<h1>Agentic Workflow Guard</h1>
|
|
162
|
-
<p class="subtitle">Attack graph report for AI-agent
|
|
165
|
+
<p class="subtitle">Attack graph report for AI-agent workflows, instruction files, and MCP configs. It maps untrusted context and tool wiring to agent capabilities, permissions, and possible impact.</p>
|
|
163
166
|
</header>
|
|
164
167
|
<main>
|
|
165
168
|
<section class="metrics">
|
|
166
|
-
<div class="metric"><span>
|
|
169
|
+
<div class="metric"><span>Scanned files</span><strong>${result.scannedFiles.length}</strong></div>
|
|
167
170
|
<div class="metric"><span>Findings</span><strong>${result.summary.total}</strong></div>
|
|
168
171
|
<div class="metric"><span>Highest severity</span><strong>${escapeHtml(result.summary.highest)}</strong></div>
|
|
169
172
|
<div class="metric"><span>Attack chains</span><strong>${attackGraph.summary.chains}</strong></div>
|
|
@@ -212,6 +215,9 @@ function inferSource(finding) {
|
|
|
212
215
|
if (match) return `GitHub event field: ${match[1] || match[2] || 'github context'}`;
|
|
213
216
|
if (finding.ruleId === 'AWG009') return 'workflow_run artifact';
|
|
214
217
|
if (finding.ruleId === 'AWG010') return 'third-party action ref';
|
|
218
|
+
if (finding.ruleId === 'AWG012') return 'persistent agent instruction file';
|
|
219
|
+
if (finding.ruleId === 'AWG013') return 'project-scoped MCP server config';
|
|
220
|
+
if (finding.ruleId === 'AWG014') return 'committed MCP credential material';
|
|
215
221
|
return 'workflow configuration';
|
|
216
222
|
}
|
|
217
223
|
|
|
@@ -220,6 +226,8 @@ function inferBoundary(finding) {
|
|
|
220
226
|
if (finding.ruleId === 'AWG002') return 'run script interpolation';
|
|
221
227
|
if (finding.ruleId === 'AWG003') return 'checkout of untrusted PR code';
|
|
222
228
|
if (finding.ruleId === 'AWG007') return 'command execution sink';
|
|
229
|
+
if (finding.ruleId === 'AWG012') return 'agent instruction context';
|
|
230
|
+
if (finding.ruleId === 'AWG013' || finding.ruleId === 'AWG014') return 'MCP tool boundary';
|
|
223
231
|
return 'workflow execution';
|
|
224
232
|
}
|
|
225
233
|
|
|
@@ -227,6 +235,9 @@ function inferCapability(finding) {
|
|
|
227
235
|
if (finding.ruleId === 'AWG006') return 'autonomous agent tool use';
|
|
228
236
|
if (finding.ruleId === 'AWG007' || finding.ruleId === 'AWG002') return 'shell command execution';
|
|
229
237
|
if (finding.ruleId === 'AWG010') return 'third-party action execution';
|
|
238
|
+
if (finding.ruleId === 'AWG012') return 'persistent prompt steering';
|
|
239
|
+
if (finding.ruleId === 'AWG013') return 'MCP server startup';
|
|
240
|
+
if (finding.ruleId === 'AWG014') return 'credentialed MCP tool access';
|
|
230
241
|
return 'CI runner and agent tools';
|
|
231
242
|
}
|
|
232
243
|
|
|
@@ -234,6 +245,9 @@ function inferAuthority(finding) {
|
|
|
234
245
|
if (finding.ruleId === 'AWG004') return 'write-capable token';
|
|
235
246
|
if (finding.ruleId === 'AWG005') return 'secret environment values';
|
|
236
247
|
if (finding.ruleId === 'AWG008') return 'implicit token permissions';
|
|
248
|
+
if (finding.ruleId === 'AWG012') return 'agent policy context';
|
|
249
|
+
if (finding.ruleId === 'AWG013') return 'developer machine or CI tool process';
|
|
250
|
+
if (finding.ruleId === 'AWG014') return 'MCP server secrets';
|
|
237
251
|
return 'workflow permissions';
|
|
238
252
|
}
|
|
239
253
|
|