Skip to content

Commit a3aa399

Browse files
Merge pull request #4 from Contrast-Security-OSS/PRODSEC-462
PRODDSEC-462 - Add support to policies hosted in private Github repositories
2 parents 6312d27 + 51df757 commit a3aa399

File tree

5 files changed

+106
-27
lines changed

5 files changed

+106
-27
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
### Changelog
2+
3+
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4+
5+
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6+
7+
#### [v1.0.1](https://github.com/Contrast-Security-OSS/actionbot/commit/fa95c969a50f6c331ec8ef19580fb9b8521851ca...https://github.com/Contrast-Security-OSS/actionbot/pull/4/commits/5f6c36987c9e39b866fd3b7aeed4203aeedb6265)
8+
9+
- Bump eslint-plugin-github from 5.1.8 to 6.0.0 [`#1`](https://github.com/Contrast-Security-OSS/actionbot/pull/1)
10+
- Migration build [`#3`](https://github.com/Contrast-Security-OSS/actionbot/pull/3)
11+
- Migrate @actions/github from 4.0.0 to 6.0.0 [`#2`](https://github.com/Contrast-Security-OSS/actionbot/pull/2)
12+
- main.ts lint changes [`3182d32`](https://github.com/Contrast-Security-OSS/actionbot/commit/3182d3203c5c7dbc9edb7b96289aeddd38c62954)
13+
- Lint changes [`8235327`](https://github.com/Contrast-Security-OSS/actionbot/commit/823532706c187506bcb5f71d6bb00f8727390037)
14+
- Build [`4882543`](https://github.com/Contrast-Security-OSS/actionbot/commit/48825436495029524a627038ad1dcfb1999eb3c4)
15+
16+
#### v1.0.0
17+
18+
> 18 March 2025
19+
20+
- Add files via upload [`fa95c96`](https://github.com/Contrast-Security-OSS/actionbot/commit/fa95c969a50f6c331ec8ef19580fb9b8521851ca)
21+
- adding main source [`8abd978`](https://github.com/Contrast-Security-OSS/actionbot/commit/8abd978c460b0e7b9c9cc611eb5540e5a18011f9)
22+
- Initial upload [`594800b`](https://github.com/Contrast-Security-OSS/actionbot/commit/594800ba2c056682322dc9e2176f95f16c131ba7)

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ inputs:
1010
description: 'Set to either `allow` or `prohibit`. When allow is the policy, any actions not on the list will be in violation. When prohibit is the policy, any actions on the list will be in violation.'
1111
policy-url:
1212
required: true
13-
description: 'The url to a publicly available json file containing a list of allowed or prohibited actions.'
13+
description: 'The URL to a publicly accessible or private GitHub JSON file containing a list of allowed or prohibited actions. Private URLs require appropriate permissions or authentication.'
1414
fail-if-violations:
1515
required: false
1616
default: 'true'

lib/index.js

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38905,6 +38905,10 @@ class Action {
3890538905
}
3890638906
}
3890738907
exports.Action = Action;
38908+
function isGitHubUrl(url) {
38909+
const githubPattern = /^https?:\/\/(www\.)?github\.com\/.+/;
38910+
return githubPattern.test(url);
38911+
}
3890838912
function isPolicyResponse(obj) {
3890938913
return typeof obj === "object" && obj !== null && Array.isArray(obj.actions);
3891038914
}
@@ -39004,19 +39008,39 @@ function run(context) {
3900439008
console.log("No workflow files detected in change set.");
3900539009
return;
3900639010
}
39007-
// Load up the remote policy list
39008-
yield (0, node_fetch_1.default)(policyUrl)
39009-
.then((response) => response.json())
39010-
.then((json) => {
39011-
// json is now correctly typed as PolicyResponse
39012-
json.actions.forEach((as) => {
39013-
actionPolicyList.push(new Action(as));
39011+
if (!isGitHubUrl(policyUrl)) {
39012+
// Load up the remote policy list
39013+
yield (0, node_fetch_1.default)(policyUrl)
39014+
.then((response) => response.json())
39015+
.then((json) => {
39016+
// json is now correctly typed as PolicyResponse
39017+
json.actions.forEach((as) => {
39018+
actionPolicyList.push(new Action(as));
39019+
});
39020+
})
39021+
.catch((error) => {
39022+
console.error("Error fetching or parsing policy:", error);
39023+
// Handle the error appropriately (e.g., throw an error, set a default policy)
3901439024
});
39015-
})
39016-
.catch((error) => {
39017-
console.error("Error fetching or parsing policy:", error);
39018-
// Handle the error appropriately (e.g., throw an error, set a default policy)
39019-
});
39025+
}
39026+
else {
39027+
// Load up the github policy list
39028+
const response = yield client.rest.repos.getContent({
39029+
owner: github.context.repo.owner,
39030+
repo: github.context.repo.repo,
39031+
path: policyUrl.replace("https://github.com/", "").split("/").slice(2).join("/"),
39032+
});
39033+
if (response.data && "content" in response.data) {
39034+
const content = Buffer.from(response.data.content, "base64").toString("utf-8");
39035+
const json = JSON.parse(content);
39036+
json.actions.forEach((as) => {
39037+
actionPolicyList.push(new Action(as));
39038+
});
39039+
}
39040+
else {
39041+
throw new Error("Failed to load GitHub policy list.");
39042+
}
39043+
}
3902039044
console.log("\nACTION POLICY LIST");
3902139045
console.log(line);
3902239046
actionPolicyList.forEach((item) => {

package.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
{
22
"name": "actionbot",
3-
"version": "1.0.1",
3+
"version": "1.0.2",
44
"private": true,
55
"description": "Github Action Policy Checker as a Github Action",
66
"main": "lib/index.js",
77
"scripts": {
88
"build": "ncc build src/main.ts -o lib",
9+
"clean": "rm -rf lib",
910
"format": "prettier --write **/*.ts",
1011
"format-check": "prettier --check **/*.ts",
1112
"lint": "eslint src/**/*.ts",
1213
"package": "ncc build --source-map",
1314
"test": "jest",
15+
"version": "auto-changelog -p && git add CHANGELOG.md && git commit -m 'chore: update changelog' && git tag -a v$(node -p \"require('./package.json').version\") -m 'Version $(node -p \"require('./package.json').version\")'",
1416
"all": "npm run build && npm run format && npm run lint && npm run package && npm test"
1517
},
1618
"repository": {
@@ -30,18 +32,19 @@
3032
"dependencies": {
3133
"@actions/core": "^1.11.1",
3234
"@actions/github": "^6.0.0",
33-
"@vercel/ncc": "^0.38.3",
3435
"@octokit/rest": "^21.1.1",
3536
"@types/js-yaml": "^4.0.9",
3637
"@types/node-fetch": "^2.6.12",
37-
"octokit": "^4.1.2",
38-
"node-fetch": "3.3.2"
38+
"@vercel/ncc": "^0.38.3",
39+
"node-fetch": "3.3.2",
40+
"octokit": "^4.1.2"
3941
},
4042
"devDependencies": {
4143
"@types/jest": "^29.5.14",
4244
"@types/node": "^22.13.8",
4345
"@typescript-eslint/parser": "^8.26.0",
4446
"@vercel/ncc": "^0.38.1",
47+
"auto-changelog": "^2.5.0",
4548
"eslint": "^9.21.0",
4649
"eslint-plugin-github": "^6.0.0",
4750
"eslint-plugin-jest": "^28.11.0",

src/main.ts

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ interface PolicyResponse {
3535
actions: string[];
3636
}
3737

38+
function isGitHubUrl(url: string): boolean {
39+
const githubPattern = /^https?:\/\/(www\.)?github\.com\/.+/;
40+
return githubPattern.test(url);
41+
}
42+
3843
function isPolicyResponse(obj: any): obj is PolicyResponse {
3944
return typeof obj === "object" && obj !== null && Array.isArray(obj.actions);
4045
}
@@ -151,19 +156,44 @@ async function run(context: typeof github.context): Promise<void> {
151156
return;
152157
}
153158

154-
// Load up the remote policy list
155-
await fetch(policyUrl)
156-
.then((response) => response.json() as Promise<PolicyResponse>)
157-
.then((json) => {
158-
// json is now correctly typed as PolicyResponse
159+
if (!isGitHubUrl(policyUrl)) {
160+
// Load up the remote policy list
161+
await fetch(policyUrl)
162+
.then((response) => response.json() as Promise<PolicyResponse>)
163+
.then((json) => {
164+
// json is now correctly typed as PolicyResponse
165+
json.actions.forEach((as) => {
166+
actionPolicyList.push(new Action(as));
167+
});
168+
})
169+
.catch((error) => {
170+
console.error("Error fetching or parsing policy:", error);
171+
// Handle the error appropriately (e.g., throw an error, set a default policy)
172+
});
173+
} else {
174+
// Load up the github policy list
175+
const response = await client.rest.repos.getContent({
176+
owner: github.context.repo.owner,
177+
repo: github.context.repo.repo,
178+
path: policyUrl
179+
.replace("https://github.com/", "")
180+
.split("/")
181+
.slice(2)
182+
.join("/"),
183+
});
184+
185+
if (response.data && "content" in response.data) {
186+
const content = Buffer.from(response.data.content, "base64").toString(
187+
"utf-8",
188+
);
189+
const json = JSON.parse(content) as PolicyResponse;
159190
json.actions.forEach((as) => {
160191
actionPolicyList.push(new Action(as));
161192
});
162-
})
163-
.catch((error) => {
164-
console.error("Error fetching or parsing policy:", error);
165-
// Handle the error appropriately (e.g., throw an error, set a default policy)
166-
});
193+
} else {
194+
throw new Error("Failed to load GitHub policy list.");
195+
}
196+
}
167197

168198
console.log("\nACTION POLICY LIST");
169199
console.log(line);

0 commit comments

Comments
 (0)