diff --git a/.github/workflows/plugin-security-scan.yml b/.github/workflows/plugin-security-scan.yml new file mode 100644 index 00000000..686ac2e9 --- /dev/null +++ b/.github/workflows/plugin-security-scan.yml @@ -0,0 +1,27 @@ +name: Plugin Security Scan + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + persist-credentials: false + + - uses: hashgraph-online/ai-plugin-scanner-action@432eebe0fb9212be97c8d15cb1da9668a91e7914 + with: + plugin_dir: "." + mode: scan + format: json + min_score: 80 + fail_on_severity: high diff --git a/tests/release/orchestration-protocol-boundaries.test.ts b/tests/release/orchestration-protocol-boundaries.test.ts index 3020fc8f..5a157fe0 100644 --- a/tests/release/orchestration-protocol-boundaries.test.ts +++ b/tests/release/orchestration-protocol-boundaries.test.ts @@ -23,6 +23,27 @@ function collectBunRunTargets(content: string): string[] { } describe("orchestration and proof protocol boundaries", () => { + it("keeps the plugin scanner workflow read-only and source-pinned", async () => { + const workflow = await readFile( + join(REPOSITORY_ROOT, ".github/workflows/plugin-security-scan.yml"), + "utf8", + ); + + expect(workflow).toContain("permissions:\n contents: read"); + expect(workflow).toContain("persist-credentials: false"); + expect(workflow).toContain( + "hashgraph-online/ai-plugin-scanner-action@432eebe0fb9212be97c8d15cb1da9668a91e7914", + ); + expect(workflow).toContain('plugin_dir: "."'); + expect(workflow).toContain("mode: scan"); + expect(workflow).toContain("format: json"); + expect(workflow).toContain("min_score: 80"); + expect(workflow).toContain("fail_on_severity: high"); + expect(workflow).not.toContain("online: true"); + expect(workflow).not.toContain("submission_enabled: true"); + expect(workflow).not.toContain("secrets."); + }); + it("fetches the history required by source-bound unit tests", async () => { const workflow = await readFile( join(REPOSITORY_ROOT, ".github/workflows/ci.yml"),