Compare commits

..

9 Commits

Author SHA1 Message Date
github-actions[bot]
82f22ec4f0 bump(remember): f1a00382 → 9d732495 (#3400)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:03:13 -05:00
github-actions[bot]
92fcf8973b bump(hunter): 0a03795d → 0bea093c (#3398)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:02:54 -05:00
github-actions[bot]
f2e1d01b77 bump(crowdstrike-falcon-foundry): 20ef548a → 7b2cda5c (#3393)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:02:37 -05:00
github-actions[bot]
b6d4f81be3 bump(data-engineering): ed2fe757 → d33a14dd (#3394)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:02:34 -05:00
github-actions[bot]
50c34b2478 bump(semgrep): 5ee984a4 → 8e652ba6 (#3401)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:02:16 -05:00
github-actions[bot]
a30e0614d3 bump(hyperframes): 56859b61 → 92385711 (#3399)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:01:59 -05:00
github-actions[bot]
c63064637d bump(exa): 40d9990f → f7e90323 (#3397)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:01:56 -05:00
github-actions[bot]
d1410844ad bump(carta-investors): d73a3615 → 4bd05d34 (#3392)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:01:51 -05:00
github-actions[bot]
89aae89012 bump(astronomer-data-agents): ed2fe757 → d33a14dd (#3391)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-26 00:01:45 -05:00
4 changed files with 35 additions and 65 deletions

View File

@@ -223,7 +223,7 @@
"source": {
"source": "url",
"url": "https://github.com/astronomer/agents.git",
"sha": "ed2fe757381ff42337fd7bce56a50f31134d9dce"
"sha": "d33a14ddd4cd8045f90acfe49d2552120feeeced"
},
"homepage": "https://github.com/astronomer/agents"
},
@@ -583,7 +583,7 @@
"url": "https://github.com/carta/plugins.git",
"path": "plugins/carta-investors",
"ref": "main",
"sha": "d73a3615864a5590ad6105df1b3e1b26324d1813"
"sha": "4bd05d342e5908b9e246c4806c92ffa1872b22e5"
},
"homepage": "https://carta.com"
},
@@ -935,7 +935,7 @@
"source": {
"source": "url",
"url": "https://github.com/CrowdStrike/foundry-skills.git",
"sha": "20ef548a615a5a8a18de7edbe65eb4bb10c8563b"
"sha": "7b2cda5cd3c5383924c365a3194172feb9fbac59"
},
"homepage": "https://github.com/CrowdStrike/foundry-skills"
},
@@ -1016,7 +1016,7 @@
"source": {
"source": "url",
"url": "https://github.com/astronomer/agents.git",
"sha": "ed2fe757381ff42337fd7bce56a50f31134d9dce"
"sha": "d33a14ddd4cd8045f90acfe49d2552120feeeced"
},
"homepage": "https://github.com/astronomer/agents"
},
@@ -1221,7 +1221,7 @@
"source": {
"source": "url",
"url": "https://github.com/exa-labs/exa-mcp-server.git",
"sha": "40d9990f48c55301535b0ea2d950176e6f115df3"
"sha": "f7e9032308a6dca9dbad76d22bc3cda287ba6775"
},
"homepage": "https://exa.ai/docs/reference/exa-mcp"
},
@@ -1442,7 +1442,7 @@
"source": {
"source": "url",
"url": "https://github.com/hunter-io/claude-plugin.git",
"sha": "0a03795dfe7258f46e702a2898bfc25aebbfcc58"
"sha": "0bea093cd18c4725f7ded7bd49400df578421cd6"
},
"homepage": "https://hunter.io"
},
@@ -1456,7 +1456,7 @@
"source": {
"source": "url",
"url": "https://github.com/heygen-com/hyperframes.git",
"sha": "56859b618f45f646835c717a8a6dfaabbbda636d"
"sha": "92385711dccbe89a6673357a6f39da7379d68528"
},
"homepage": "https://hyperframes.heygen.com"
},
@@ -2411,7 +2411,7 @@
"source": {
"source": "url",
"url": "https://github.com/Digital-Process-Tools/claude-remember.git",
"sha": "f1a00382598ef627c858d9eed6438047b072ba41"
"sha": "9d7324957b4d6e92fd57d265a2685a363e93f63e"
},
"homepage": "https://github.com/Digital-Process-Tools/claude-remember"
},
@@ -2656,7 +2656,7 @@
"source": "git-subdir",
"url": "https://github.com/semgrep/mcp-marketplace.git",
"path": "plugin",
"sha": "5ee984a4aeee83b3edae3ed44be4be8d333d24d1"
"sha": "8e652ba6f586bb20377a72792c402c5a85a9b284"
},
"homepage": "https://github.com/semgrep/mcp-marketplace.git"
},

View File

@@ -121,33 +121,4 @@ async function evaluate({ github, context }) {
return analyze({ changedFiles, before, after, liveRepos: liveReposOf(liveBase) });
}
// Authors that are NOT subject to the external-contributor scope rules:
// - the repo's own automation bot — its bump PRs legitimately MODIFY existing entries
// (SHA bumps), which the additions-only external-contributor rule forbids; AND
// - org members (write/admin).
// Safe under pull_request_target: a fork PR cannot set its author to github-actions[bot]
// (that login is only ever the org's own GITHUB_TOKEN workflow), and the member path is a
// real permission lookup. Wrapped in try/catch because getCollaboratorPermissionLevel throws
// for a non-collaborator/unknown user — without this, both callers would error the job rather
// than fall through to scope evaluation.
const EXEMPT_BOTS = new Set(['github-actions[bot]']);
async function isExemptAuthor({ github, context }) {
const author = context.payload.pull_request.user.login;
if (EXEMPT_BOTS.has(author)) {
return { exempt: true, reason: `${author} is the trusted automation bot` };
}
try {
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner, repo: context.repo.repo, username: author,
});
if (['admin', 'write'].includes(data.permission)) {
return { exempt: true, reason: `${author} is ${data.permission} (member)` };
}
} catch (e) {
// not a collaborator / lookup failed → not exempt; fall through to scope evaluation
}
return { exempt: false };
}
module.exports = { normalizeRepo, liveReposOf, analyze, readPlugins, evaluate, isExemptAuthor, MARKETPLACE };
module.exports = { normalizeRepo, liveReposOf, analyze, readPlugins, evaluate, MARKETPLACE };

View File

@@ -23,13 +23,14 @@ jobs:
script: |
const author = context.payload.pull_request.user.login;
const { evaluate, isExemptAuthor } = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/external-pr-scope.js`);
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: author
});
// Members (write/admin) and the repo's own automation bot (bump SHA PRs) are never
// auto-closed.
const ex = await isExemptAuthor({ github, context });
if (ex.exempt) {
console.log(`${ex.reason} — allowing PR`);
if (['admin', 'write'].includes(data.permission)) {
console.log(`${author} has ${data.permission} access, allowing PR`);
return;
}
@@ -37,9 +38,9 @@ jobs:
// contribution — it adds marketplace.json entries whose source repo ALREADY backs
// a live plugin here, and changes nothing else. (No maintained allowlist: the set
// of allowed repos is derived from the live marketplace.) This grants only the
// right to open a reviewable PR; the validate + scan checks and a maintainer
// approval still gate the merge (the External PR Scope Guard is advisory signal,
// not a required check).
// right to open a reviewable PR; the External PR Scope Guard required check and a
// maintainer approval still gate the merge.
const { evaluate } = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/external-pr-scope.js`);
const result = await evaluate({ github, context });
if (result.ok && result.added.length > 0) {
console.log(`In-scope external contribution (adds: ${result.added.join(', ')}) — allowing PR.`);

View File

@@ -1,17 +1,14 @@
name: External PR Scope Guard
# Advisory check that surfaces what a NON-MEMBER pull request may change.
# Members (write/admin) and the repo's own automation bot (bump SHA PRs) are unrestricted and
# skip this check. For a non-member PR this fails unless the PR is an in-scope external
# contribution per .github/scripts/external-pr-scope.js: it changes ONLY
# .claude-plugin/marketplace.json, the delta is additions-only (no existing entry modified or
# removed), and every ADDED entry's source.url is a repo that ALREADY backs a live plugin in
# this marketplace (the allowed set is derived from the live marketplace — there is no
# maintained allowlist).
# Required status check that constrains what a NON-MEMBER pull request may change.
# Members (write/admin) are unrestricted and skip this check. For a non-member PR this
# fails unless the PR is an in-scope external contribution per .github/scripts/external-pr-scope.js:
# it changes ONLY .claude-plugin/marketplace.json, the delta is additions-only (no existing
# entry modified or removed), and every ADDED entry's source.url is a repo that ALREADY backs
# a live plugin in this marketplace (the allowed set is derived from the live marketplace —
# there is no maintained allowlist).
#
# Do NOT add this job to branch protection as a required status check. The merge gate is the
# `validate` + `scan` checks plus a maintainer approval; this guard is advisory signal for the
# reviewer, not a hard gate. (Making it required would block the no-approval bump-merge path.)
# Add the scope-guard job as a REQUIRED status check in branch protection for it to block merge.
#
# Security: runs on pull_request_target but checks out only the BASE repo (trusted) for the
# shared script; the head marketplace.json is fetched as DATA via the API and parsed, never executed.
@@ -32,16 +29,17 @@ jobs:
- uses: actions/github-script@v7
with:
script: |
const { evaluate, isExemptAuthor } = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/external-pr-scope.js`);
const author = context.payload.pull_request.user.login;
// Members (write/admin) and the repo's own automation bot (bump SHA PRs) are
// unrestricted; only genuinely external contributions are scope-checked.
const ex = await isExemptAuthor({ github, context });
if (ex.exempt) {
console.log(`${ex.reason} — scope guard not applicable.`);
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner, repo: context.repo.repo, username: author,
});
if (['admin', 'write'].includes(perm.permission)) {
console.log(`${author} is ${perm.permission} (member) — scope guard not applicable.`);
return;
}
const { evaluate } = require(`${process.env.GITHUB_WORKSPACE}/.github/scripts/external-pr-scope.js`);
const result = await evaluate({ github, context });
if (!result.ok) {