agentci-guard 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 David Wu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # AgentCI Guard
2
+
3
+ AgentCI Guard is a CLI and GitHub Action that detects unsafe AI coding-agent usage in CI/CD workflows.
4
+
5
+ It focuses on one high-risk pattern: untrusted GitHub event content reaching an AI agent that has secrets, write permissions, shell access, or unsafe checkout behavior.
6
+
7
+ ![AgentCI Guard scanning a vulnerable workflow](docs/demo.svg)
8
+
9
+ > The animated terminal demo is generated from [`docs/demo.tape`](docs/demo.tape) — run `vhs docs/demo.tape` to produce `docs/demo.gif`.
10
+
11
+ ## What It Detects
12
+
13
+ - AI-agent usage in `.github/workflows/*.yml`
14
+ - `pull_request_target` combined with AI agents
15
+ - PR/issue/comment/review/branch/commit content passed into prompts or shell commands
16
+ - `contents: write`, `pull-requests: write`, or other broad write scopes near AI usage
17
+ - `secrets.*`, `GITHUB_TOKEN`, and token-like environment variables in agent jobs
18
+ - shell access combined with AI usage
19
+ - unpinned third-party AI actions
20
+ - checkout of untrusted PR head code in privileged contexts
21
+
22
+ ## CLI Quickstart
23
+
24
+ ```bash
25
+ # Run without installing
26
+ npx agentci-guard scan .
27
+
28
+ # Or install globally
29
+ npm install -g agentci-guard
30
+
31
+ agentci scan .
32
+ agentci scan . --json
33
+ agentci scan . --sarif agentci-results.sarif
34
+ agentci explain agentci/untrusted-ai-write-token
35
+ ```
36
+
37
+ Exit codes:
38
+
39
+ - `0`: no findings at or above `--fail-on`
40
+ - `2`: at least one finding at or above `--fail-on`
41
+ - `1`: scanner error
42
+
43
+ Default fail threshold is `high`.
44
+
45
+ ## GitHub Action
46
+
47
+ ```yaml
48
+ name: agentci-guard
49
+ on: [pull_request, push]
50
+
51
+ permissions:
52
+ contents: read
53
+ security-events: write
54
+
55
+ jobs:
56
+ scan:
57
+ runs-on: ubuntu-latest
58
+ steps:
59
+ - uses: actions/checkout@v4
60
+ - uses: David-Wu1119/agentci-guard@v0
61
+ with:
62
+ path: .
63
+ sarif: agentci-results.sarif
64
+ fail-on: high
65
+ - uses: github/codeql-action/upload-sarif@v3
66
+ if: always()
67
+ with:
68
+ sarif_file: agentci-results.sarif
69
+ ```
70
+
71
+ ### Outputs
72
+
73
+ The action sets `findings`, `critical`, `high`, `medium`, `low`, and `sarif-path` so later steps can react:
74
+
75
+ ```yaml
76
+ - uses: David-Wu1119/agentci-guard@v0
77
+ id: agentci
78
+ with:
79
+ fail-on: none
80
+ - if: steps.agentci.outputs.critical != '0'
81
+ run: echo "::warning::${{ steps.agentci.outputs.critical }} critical finding(s)"
82
+ ```
83
+
84
+ If `agentci.config.json` exists in the scanned path it is picked up automatically (see [Suppressing Findings](#suppressing-findings)).
85
+
86
+ ## Example Finding
87
+
88
+ ```text
89
+ CRITICAL agentci/untrusted-ai-write-token
90
+ File: .github/workflows/ai-agent.yml / job: claude
91
+ Evidence: untrusted trigger + AI usage + write permissions + untrusted GitHub event context
92
+
93
+ Why:
94
+ An attacker can place prompt-injection text in a PR, issue, or comment. If that text reaches an AI agent with repository write permissions, the agent can be induced to modify code, comments, workflows, or releases.
95
+
96
+ Fix:
97
+ - Do not run privileged AI agents on untrusted triggers.
98
+ - Use read-only GITHUB_TOKEN permissions for untrusted events.
99
+ - Require maintainer approval before running the agent.
100
+ - Sanitize and summarize untrusted content before passing it to an agent.
101
+ ```
102
+
103
+ ## Suppressing Findings
104
+
105
+ Real workflows sometimes have a finding you've reviewed and accepted. Two ways to silence one without disabling the whole scan:
106
+
107
+ **Inline (per file)** — add a comment anywhere in the workflow:
108
+
109
+ ```yaml
110
+ # agentci-ignore agentci/unpinned-ai-action -- mirrored internally, reviewed 2026-06
111
+ # agentci-ignore-all -- silence every rule in this file
112
+ ```
113
+
114
+ **Config file** — `agentci.config.json` in the scanned path (or pass `--config <path>`):
115
+
116
+ ```json
117
+ {
118
+ "ignore": ["agentci/unpinned-ai-action"],
119
+ "ignorePaths": ["**/generated-*.yml"]
120
+ }
121
+ ```
122
+
123
+ `ignore` suppresses a rule everywhere; `ignorePaths` excludes matching workflow files (`*` within a path segment, `**` across segments). Ignored files are still parsed — they just don't report findings.
124
+
125
+ ## Development
126
+
127
+ ```bash
128
+ corepack enable
129
+ pnpm install
130
+ pnpm typecheck
131
+ pnpm test
132
+ pnpm build
133
+ npm pack --dry-run
134
+ ```
135
+
136
+ ## Security Boundary
137
+
138
+ AgentCI Guard is a static scanner. It does not sandbox workflows or prove that an agent is safe. It identifies high-risk patterns that should receive human review before AI agents are allowed to run with privileged CI/CD context.
139
+
140
+ See [Threat Model](docs/threat-model.md) and [Real-World Findings](docs/real-world-findings.md) (a scan of 75 public repos that run AI agents in CI).
141
+
142
+ ## License
143
+
144
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,23 @@
1
+ # Security Policy
2
+
3
+ AgentCI Guard is security-sensitive CI/CD tooling. Do not publish exploit details for unfixed vulnerabilities in public issues.
4
+
5
+ ## Supported Versions
6
+
7
+ During the `0.x` phase, only the latest `main` branch and latest published package are supported.
8
+
9
+ ## Reporting a Vulnerability
10
+
11
+ Use GitHub Security Advisories when available. If private reporting is unavailable, open a minimal public issue asking for a disclosure channel without including exploit details.
12
+
13
+ A useful report includes:
14
+
15
+ - AgentCI Guard version or commit
16
+ - Workflow YAML that reproduces the issue, with secrets removed
17
+ - Expected finding
18
+ - Actual finding
19
+ - Whether the issue is false negative, false positive, crash, or SARIF/report problem
20
+
21
+ ## Non-Goals
22
+
23
+ AgentCI Guard does not execute or sandbox workflows. A static scan passing does not certify an AI-agent workflow as safe.
package/action.yml ADDED
@@ -0,0 +1,42 @@
1
+ name: AgentCI Guard
2
+ description: Scan GitHub Actions workflows for unsafe AI coding-agent usage.
3
+ author: David Wu
4
+ branding:
5
+ icon: shield
6
+ color: red
7
+ inputs:
8
+ path:
9
+ description: Repository path to scan.
10
+ required: false
11
+ default: "."
12
+ sarif:
13
+ description: SARIF output path.
14
+ required: false
15
+ default: "agentci-results.sarif"
16
+ fail-on:
17
+ description: Minimum severity that fails the action. One of none, low, medium, high, critical.
18
+ required: false
19
+ default: "high"
20
+ outputs:
21
+ findings:
22
+ description: Total number of findings.
23
+ critical:
24
+ description: Number of critical-severity findings.
25
+ high:
26
+ description: Number of high-severity findings.
27
+ medium:
28
+ description: Number of medium-severity findings.
29
+ low:
30
+ description: Number of low-severity findings.
31
+ sarif-path:
32
+ description: Path to the written SARIF file.
33
+ runs:
34
+ using: node24
35
+ main: dist/cli.js
36
+ args:
37
+ - scan
38
+ - ${{ inputs.path }}
39
+ - --sarif
40
+ - ${{ inputs.sarif }}
41
+ - --fail-on
42
+ - ${{ inputs.fail-on }}
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node