ai-saas-guard 0.26.0 → 0.26.1
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 +4 -4
- package/README.zh-CN.md +3 -3
- package/dist/hosted/app.js +8 -1
- package/dist/hosted/contracts.js +1 -1
- package/dist/hosted/production-adapters.js +8 -1
- package/dist/scanners/gitDiff.js +14 -3
- package/docs/github-action.md +1 -1
- package/docs/npm-publishing.md +3 -3
- package/docs/project-handoff.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,9 +76,9 @@ The CLI is published on npm as `ai-saas-guard`, and the GitHub Action is availab
|
|
|
76
76
|
| JSON and SARIF output | Available |
|
|
77
77
|
| Composite GitHub Action | Available |
|
|
78
78
|
| Project config | `.ai-saas-guard.json` rule toggles, severity overrides, and fail thresholds |
|
|
79
|
-
| Versioned Action tags | `v0.26.
|
|
80
|
-
| npm package | `ai-saas-guard@0.26.
|
|
81
|
-
| Current release | `0.26.
|
|
79
|
+
| Versioned Action tags | `v0.26.1`, `v0` |
|
|
80
|
+
| npm package | `ai-saas-guard@0.26.1` |
|
|
81
|
+
| Current release | `0.26.1` launch-risk expansion |
|
|
82
82
|
| npm publishing | Trusted Publisher/OIDC, no long-lived publish token |
|
|
83
83
|
| Repository trust hardening | Strict branch protection, Dependabot, CodeQL, fast-check fuzzing, signed release provenance assets, private vulnerability reporting, secret scanning, and push protection |
|
|
84
84
|
| Runtime hardening | Per-file and total text scan caps, escaped markdown evidence, 1 MiB hosted webhook payload cap, stricter hosted deployment blockers |
|
|
@@ -299,7 +299,7 @@ Use `suppressions` for narrower false-positive handling when one rule is noisy o
|
|
|
299
299
|
|
|
300
300
|
## GitHub Action
|
|
301
301
|
|
|
302
|
-
The repo includes a composite Action. Use `v0` for the latest compatible pre-1.0 Action, a specific release tag such as `v0.26.
|
|
302
|
+
The repo includes a composite Action. Use `v0` for the latest compatible pre-1.0 Action, a specific release tag such as `v0.26.1` for controlled upgrades, or pin a reviewed commit SHA for stricter supply-chain control:
|
|
303
303
|
|
|
304
304
|
```yaml
|
|
305
305
|
name: ai-saas-guard
|
package/README.zh-CN.md
CHANGED
|
@@ -65,7 +65,7 @@ AI 能很快把一个 SaaS 从想法做成可运行的产品。真正难的是
|
|
|
65
65
|
|
|
66
66
|
这个仓库是公开 GitHub 仓库。
|
|
67
67
|
|
|
68
|
-
CLI 已发布到 npm:`ai-saas-guard@0.26.
|
|
68
|
+
CLI 已发布到 npm:`ai-saas-guard@0.26.1`。GitHub Action 支持 `v0` 浮动标签,也支持固定版本标签,例如 `v0.26.1`。
|
|
69
69
|
|
|
70
70
|
| 模块 | 状态 |
|
|
71
71
|
| --- | --- |
|
|
@@ -76,8 +76,8 @@ CLI 已发布到 npm:`ai-saas-guard@0.26.0`。GitHub Action 支持 `v0` 浮动
|
|
|
76
76
|
| Markdown PR summary | 已可用 |
|
|
77
77
|
| GitHub Action | 已可用 |
|
|
78
78
|
| 项目配置 | `.ai-saas-guard.json` 支持规则开关、severity 覆盖和 fail threshold |
|
|
79
|
-
| 当前版本 | `0.26.
|
|
80
|
-
| Action 标签 | `v0.26.
|
|
79
|
+
| 当前版本 | `0.26.1` launch-risk expansion |
|
|
80
|
+
| Action 标签 | `v0.26.1`、`v0` |
|
|
81
81
|
| npm 发布 | GitHub Actions Trusted Publisher/OIDC,无需长期 npm token |
|
|
82
82
|
| 仓库可信度加固 | 严格 branch protection、Dependabot、CodeQL、fast-check fuzzing、signed release provenance assets、private vulnerability reporting、secret scanning 和 push protection |
|
|
83
83
|
| 运行时加固 | 单文件和总扫描文本预算、markdown evidence 转义、1 MiB hosted webhook payload 上限、更严格的 hosted deployment 阻断 |
|
package/dist/hosted/app.js
CHANGED
|
@@ -261,7 +261,7 @@ function isValidSecretRef(value) {
|
|
|
261
261
|
return /^secret:[A-Za-z0-9._:/@-]+$/.test(value);
|
|
262
262
|
}
|
|
263
263
|
function normalizePublicBaseUrl(publicBaseUrl) {
|
|
264
|
-
return publicBaseUrl.trim()
|
|
264
|
+
return trimTrailingSlashes(publicBaseUrl.trim());
|
|
265
265
|
}
|
|
266
266
|
function isSafePublicHttpsUrl(value) {
|
|
267
267
|
try {
|
|
@@ -279,6 +279,13 @@ function isUnsafeHostedHostname(hostname) {
|
|
|
279
279
|
isUnsafeIpv4Hostname(normalized) ||
|
|
280
280
|
isUnsafeIpv6Hostname(normalized));
|
|
281
281
|
}
|
|
282
|
+
function trimTrailingSlashes(value) {
|
|
283
|
+
let end = value.length;
|
|
284
|
+
while (end > 0 && value[end - 1] === "/") {
|
|
285
|
+
end -= 1;
|
|
286
|
+
}
|
|
287
|
+
return value.slice(0, end);
|
|
288
|
+
}
|
|
282
289
|
function normalizeHostname(hostname) {
|
|
283
290
|
const lower = hostname.toLowerCase().replace(/\.$/, "");
|
|
284
291
|
return lower.startsWith("[") && lower.endsWith("]") ? lower.slice(1, -1) : lower;
|
package/dist/hosted/contracts.js
CHANGED
|
@@ -1156,7 +1156,7 @@ function getHostedCheckRunFiles(report) {
|
|
|
1156
1156
|
return [...new Set(report.evidence.map((finding) => finding.file))].slice(0, 10);
|
|
1157
1157
|
}
|
|
1158
1158
|
function escapeMarkdownTableCell(value) {
|
|
1159
|
-
return value.
|
|
1159
|
+
return value.replaceAll("\\", "\\\\").replaceAll("|", "\\|").replaceAll("\r", " ").replaceAll("\n", " ");
|
|
1160
1160
|
}
|
|
1161
1161
|
function capitalize(value) {
|
|
1162
1162
|
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
@@ -190,7 +190,14 @@ function safeApiUrlBlockedReasons(apiBaseUrl) {
|
|
|
190
190
|
}
|
|
191
191
|
function normalizeApiBaseUrl(apiBaseUrl) {
|
|
192
192
|
const value = apiBaseUrl?.trim() || "https://api.github.com";
|
|
193
|
-
return value
|
|
193
|
+
return trimTrailingSlashes(value);
|
|
194
|
+
}
|
|
195
|
+
function trimTrailingSlashes(value) {
|
|
196
|
+
let end = value.length;
|
|
197
|
+
while (end > 0 && value[end - 1] === "/") {
|
|
198
|
+
end -= 1;
|
|
199
|
+
}
|
|
200
|
+
return value.slice(0, end);
|
|
194
201
|
}
|
|
195
202
|
function permissionsForPurpose(purpose) {
|
|
196
203
|
if (purpose === "worker_checkout") {
|
package/dist/scanners/gitDiff.js
CHANGED
|
@@ -166,12 +166,12 @@ function parseDiffFiles(diffText) {
|
|
|
166
166
|
const files = [];
|
|
167
167
|
let current;
|
|
168
168
|
for (const line of diffText.split(/\r?\n/)) {
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
169
|
+
const filePath = parseDiffHeaderPath(line);
|
|
170
|
+
if (filePath) {
|
|
171
171
|
if (current)
|
|
172
172
|
files.push(finalizeDiffFile(current));
|
|
173
173
|
current = {
|
|
174
|
-
path:
|
|
174
|
+
path: filePath,
|
|
175
175
|
score: 0,
|
|
176
176
|
categories: [],
|
|
177
177
|
added: 0,
|
|
@@ -192,6 +192,17 @@ function parseDiffFiles(diffText) {
|
|
|
192
192
|
files.push(finalizeDiffFile(current));
|
|
193
193
|
return files;
|
|
194
194
|
}
|
|
195
|
+
function parseDiffHeaderPath(line) {
|
|
196
|
+
const prefix = "diff --git a/";
|
|
197
|
+
if (!line.startsWith(prefix))
|
|
198
|
+
return undefined;
|
|
199
|
+
const separator = " b/";
|
|
200
|
+
const separatorIndex = line.lastIndexOf(separator);
|
|
201
|
+
if (separatorIndex === -1)
|
|
202
|
+
return undefined;
|
|
203
|
+
const path = line.slice(separatorIndex + separator.length);
|
|
204
|
+
return path || undefined;
|
|
205
|
+
}
|
|
195
206
|
function finalizeDiffFile(file) {
|
|
196
207
|
const changedLines = file.lines
|
|
197
208
|
.filter((line) => (line.startsWith("+") && !line.startsWith("+++")) || (line.startsWith("-") && !line.startsWith("---")))
|
package/docs/github-action.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`ai-saas-guard` ships as a composite GitHub Action for pull request and code scanning workflows.
|
|
4
4
|
|
|
5
|
-
Use `zr9959/ai-saas-guard@v0` for the latest compatible pre-1.0 Action. Use a specific tag such as `v0.26.
|
|
5
|
+
Use `zr9959/ai-saas-guard@v0` for the latest compatible pre-1.0 Action. Use a specific tag such as `v0.26.1` or a reviewed commit SHA when reproducibility is more important than automatic minor updates.
|
|
6
6
|
|
|
7
7
|
## PR Summary
|
|
8
8
|
|
package/docs/npm-publishing.md
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
## Current State
|
|
6
6
|
|
|
7
7
|
- Package name: `ai-saas-guard`
|
|
8
|
-
- Current published version: `0.26.
|
|
8
|
+
- Current published version: `0.26.1`
|
|
9
9
|
- Next source candidate: none
|
|
10
10
|
- npm registry state: published at <https://www.npmjs.com/package/ai-saas-guard>
|
|
11
11
|
- First npm-published version: `0.1.1`
|
|
12
|
-
- GitHub Release: `v0.26.
|
|
12
|
+
- GitHub Release: `v0.26.1`
|
|
13
13
|
- Publish workflow: `.github/workflows/npm-publish.yml`
|
|
14
14
|
- Trusted Publisher: GitHub Actions, `zr9959/ai-saas-guard`, workflow `npm-publish.yml`, allowed action `npm publish`
|
|
15
15
|
- Long-lived npm publish token: not required
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
Use GitHub Actions with npm Trusted Publisher/OIDC:
|
|
20
20
|
|
|
21
|
-
1. Create and review a release tag such as `v0.26.
|
|
21
|
+
1. Create and review a release tag such as `v0.26.1`.
|
|
22
22
|
2. Publish from the GitHub Release or run the `Publish npm` workflow manually with `ref` set to that tag.
|
|
23
23
|
3. Keep `permissions.id-token: write` in the workflow so npm can exchange the GitHub Actions OIDC identity for a short-lived publish credential.
|
|
24
24
|
4. Run `npm publish --access public` from the workflow. Trusted publishing automatically generates provenance for this public package from this public repository.
|
package/docs/project-handoff.md
CHANGED
|
@@ -160,7 +160,7 @@ OpenSSF Best Practices:
|
|
|
160
160
|
Publishing:
|
|
161
161
|
|
|
162
162
|
- npm package: `ai-saas-guard`
|
|
163
|
-
- Current published release line: `v0.26.
|
|
163
|
+
- Current published release line: `v0.26.1`
|
|
164
164
|
- Next source candidate: none
|
|
165
165
|
- Publish workflow: `.github/workflows/npm-publish.yml`
|
|
166
166
|
- Trusted Publisher: GitHub Actions for `zr9959/ai-saas-guard`, workflow `npm-publish.yml`
|