From d38292b12e884c4a720ca47143bdcc8518c8351f Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Fri, 9 Oct 2026 14:40:18 -0400 Subject: [PATCH 1/2] ci: stage the shared policy fixture repair authority --- .github/public-workflow-action-allowlist.json | 70 +---- .github/public-workflow-authority.json | 157 +++++++++++ .../public-workflow-command-allowlist.json | 248 ++---------------- .../public-workflow-presence-allowlist.json | 8 +- 4 files changed, 193 insertions(+), 290 deletions(-) diff --git a/.github/public-workflow-action-allowlist.json b/.github/public-workflow-action-allowlist.json index 174f80f5..4c33341c 100644 --- a/.github/public-workflow-action-allowlist.json +++ b/.github/public-workflow-action-allowlist.json @@ -1,60 +1,4 @@ [ - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae", - "nodeSHA256": "75285419b94ac7c3e82c6bcdff625ac1aab862ff09465c03b7f67b5f68a187f2", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae for reviewed benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae", - "nodeSHA256": "89a251c63db3bcac9145c65adeb9dddd48afdd5c8cb13a9ad5ae16a3cd3f526f", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae for reviewed benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10", - "nodeSHA256": "53ad3f241f5c8d1d03bf90f108b1cc142bb2f4639861d07e4ecc910983808995", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 for reviewed benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3", - "nodeSHA256": "b1570fa9a4d99988920c8c534c481885469c1dfaca2327d7c088e35dadb1a568", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 for reviewed benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c", - "nodeSHA256": "c0d85fe8f94bd2187fb4d2a57310b75cf4561a018bc15a11b5fbea0baa13f07a", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/setup-go for the reviewed Go 1.26.5 benchmark toolchain." - }, - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e", - "nodeSHA256": "d6511486d7f0d7044978b8c71828add2508e72a9897718b7a91fdf151ffb3c49", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e for reviewed benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "uses": "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a", - "nodeSHA256": "12074f39596f10a86be9803abfc22df487bd693298254d1147668ad32952b442", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Pinned actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a for reviewed benchmark.yml automation." - }, { "path": ".github/workflows/ci.yml", "uses": "actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10", @@ -684,7 +628,7 @@ "uses": "actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10", "nodeSHA256": "53ad3f241f5c8d1d03bf90f108b1cc142bb2f4639861d07e4ecc910983808995", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." }, { @@ -692,7 +636,7 @@ "uses": "actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c", "nodeSHA256": "c0d85fe8f94bd2187fb4d2a57310b75cf4561a018bc15a11b5fbea0baa13f07a", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." }, { @@ -700,7 +644,7 @@ "uses": "actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e", "nodeSHA256": "d6511486d7f0d7044978b8c71828add2508e72a9897718b7a91fdf151ffb3c49", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." }, { @@ -708,7 +652,7 @@ "uses": "actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae", "nodeSHA256": "75285419b94ac7c3e82c6bcdff625ac1aab862ff09465c03b7f67b5f68a187f2", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." }, { @@ -716,7 +660,7 @@ "uses": "actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3", "nodeSHA256": "b1570fa9a4d99988920c8c534c481885469c1dfaca2327d7c088e35dadb1a568", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." }, { @@ -724,7 +668,7 @@ "uses": "actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae", "nodeSHA256": "89a251c63db3bcac9145c65adeb9dddd48afdd5c8cb13a9ad5ae16a3cd3f526f", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." }, { @@ -732,7 +676,7 @@ "uses": "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a", "nodeSHA256": "1405962dcbf154f33a16a10fef5272ba0a865f20dfe11358a522e310e29dab1c", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair action." } ] diff --git a/.github/public-workflow-authority.json b/.github/public-workflow-authority.json index ee6436de..041f0614 100644 --- a/.github/public-workflow-authority.json +++ b/.github/public-workflow-authority.json @@ -156,6 +156,163 @@ } ], "state": "active" + }, + { + "state": "staged", + "files": [ + { + "path": ".github/workflows/policytool/adoptionguard/main.go", + "sha256": "7854ccaa9593bc5d64eb93db78ec1bdd6b36d61b545bada95df34ce542f2002a" + }, + { + "path": ".github/workflows/policytool/adoptionguard/main_test.go", + "sha256": "f4220c8924a6feb96d124c06032cdced62342fe39165f8a0e96f6b2b397e7f17" + }, + { + "path": ".github/workflows/policytool/adoptionguard/run.sh", + "sha256": "b5597c106885bdc9b1f7161f7c6a1635d92f5f9273c41ec799233d68d6dbf3e4" + }, + { + "path": ".github/workflows/policytool/go.mod", + "sha256": "0a2d135980310757f36e733161b94498b4e0a1b6ac8c6de8a799f542d6c9ddb8" + }, + { + "path": ".github/workflows/policytool/go.sum", + "sha256": "790ef858e5aeed12269a69e764ac69c02c3877678b0e7d9384ad3728b6e09f6c" + }, + { + "path": ".github/workflows/policytool/main.go", + "sha256": "8dba6ad341fa07644868fd43717aff162c4feae1694ee9a122ef4cd401214a00" + }, + { + "path": ".github/workflows/policytool/main_test.go", + "sha256": "6b198d0ac211a22f39e65a885c903c5a956ed2e5642a2f0b599496efdaa2ad5c" + }, + { + "path": ".github/workflows/scripts/verify-public-workflow-branch-protection.sh", + "sha256": "0d48038f7e641f0a58ae2a0f9150d40f284619c2254951fb31066fbb121df304" + }, + { + "path": "scripts/check-public-workflow-policy.sh", + "sha256": "5af4e6ae8b5b0ae1b7557253c398fc4c40b1f329a45ccd13639dd0b89bc9dc46" + }, + { + "path": "scripts/fixtures/public-workflow-policy/lifecycle-future.yml", + "sha256": "de3bdf01a31d2a0d39a279a65258d47f0f504155065de720a1908a1b7a703103" + }, + { + "path": "scripts/fixtures/public-workflow-policy/lifecycle-old.yml", + "sha256": "6dc23984617b91711ff14a08e8d428d9dc47dc3c00f4efd703bf747fe7e6a122" + }, + { + "path": "scripts/fixtures/public-workflow-policy/pass-expression-and-deny-guard.yml", + "sha256": "6af7ce9692c0e3c3f4468927912db334bab659b36567703e27cd9d2c0957d908" + }, + { + "path": "scripts/fixtures/public-workflow-policy/pass-negative-guard.yml", + "sha256": "7af97a7da7d416064190ba39e6829148071714d39840dc7f354cab78fadc3665" + }, + { + "path": "scripts/fixtures/public-workflow-policy/pass.yml", + "sha256": "38ece391dcb2d2b84ba44121cd6bdcc2953a3822ab0e464224e0bb60199400e5" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-builtin-wrapper.yml", + "sha256": "56fcfd4f7752e6b462471a78b329bbf6e8d978fa047c4bdbf9d09b25cc350be0" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-command-analysis.yml", + "sha256": "589658280ae8623d932e691323b138c439a28fe27a79ea2859be7c00600b6820" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-deny-pattern-execution.yml", + "sha256": "c8475ed82b6fb7ac4ec227f48becc4a148d7d3665a5fdfdbac19096cca7c2165" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-dynamic-secrets.yml", + "sha256": "7900842a6adf772396eb4893925d26b71e1a4560053305031d7c4e15b3e2f5f8" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-env-indirection.yml", + "sha256": "6b524ac4c498f45d68896676f75c8171033558a9a270f5158870ae36604218d7" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-execution-context.yml", + "sha256": "50629e545d7fba12247f28a06e9632b52c3c8d63c01a2551fb8d9d7ac2a6e0b6" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-global.yml", + "sha256": "43620c1094cf6a8223f4b35c18bf54a621e09b5f5922b835bd7e22a48f1f205d" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-guard-suffix.yml", + "sha256": "4b5623b44d1dcef0198ce914a16a358180f65d733d5521863b4606178ea20823" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-implicit-permissions.yml", + "sha256": "5606653732f73c8c9af42c28a72f5d2a43336fd0edbb25524832e98713e798a8" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-legacy-github-token.yml", + "sha256": "595e24dcd363104586f7c973225cf6ba79606dfc1b9124ef383c668932e9fb5a" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-missing-shell.yml", + "sha256": "58757a1e09107185710dd3a2c401d6a3691d1c11f4db7f41b8a4f8dde57d0574" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-permissions.yml", + "sha256": "24ac3b5c02f97b7b3ec2e06f2d7c7c46035a17dda029ed8918c3e54d8e6933c4" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-provider-uses.yml", + "sha256": "3f6a028a527a04b1bcddd087174b56b85916fc347da23cb86b76948b2a006f45" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-runners.yml", + "sha256": "cbfec39b289dfcbee247f6fa5a415c01921ab02e03c63bd974df1322a6159050" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-script-execution.yml", + "sha256": "6e57329ba154ee32a37c2c8227f75db5422d9fdf3487180f4f8d388891c04f62" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-secret-syntax.yml", + "sha256": "3ef3fc0c94a53510069d63e58e7a7eef51de884d7446fe20476d60c4fa078648" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-shell-inheritance.yml", + "sha256": "330bc5a511a1c14d6adadd7e7f19a1baacdf47b513a2382e7cfa060babc460e0" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-shell.yml", + "sha256": "6dffd2756cf468c9bf4c268bfebfd1c4bfb96e81e30137a7dafbd0d39161df00" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-statement-authority.yml", + "sha256": "2ae4ecdde184f102004b81cca0de0e345278c7ebc2aa0993f5a8ef47acf50e91" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-unreviewed-uses.yml", + "sha256": "4e1a4f1d5c7b147af24dac04448617a77649e711366ab19701d6e878a1c0a274" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-unsafe-programs.yml", + "sha256": "5c464126d992dc5305ca68c6ebb0f7086650d0e86dc56aee35ee0de40e6b1f96" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject-yaml-structure.yml", + "sha256": "e564fe3b6655a68c242038c98f480fe432ed840aa3325caab88e052343352402" + }, + { + "path": "scripts/fixtures/public-workflow-policy/reject.yml", + "sha256": "e98e5b29312f6541e6d71fc532943a055c9164923cd560710d47414ac80aecc1" + }, + { + "path": "scripts/test-check-public-workflow-policy.sh", + "sha256": "9b857524e8b736a104e1aa65a3fa5edeaf76a3787ba8942871992675440f550b" + } + ] } ], "version": 1 diff --git a/.github/public-workflow-command-allowlist.json b/.github/public-workflow-command-allowlist.json index 3c90d886..1415fc70 100644 --- a/.github/public-workflow-command-allowlist.json +++ b/.github/public-workflow-command-allowlist.json @@ -1,196 +1,4 @@ [ - { - "path": ".github/workflows/benchmark.yml", - "command": "$assignment", - "statementSHA256": "c0c433693a307a0c5c423fa126f7690084d93243b539c72221d5148dcaa24f09", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed literal assignment for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "$assignment", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed literal assignment for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "[", - "statementSHA256": "21430cc4ac1193bbb95ec1575f04ae6b65d6ada2b4bca8c4195d288c9bc449bf", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed [ statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "[", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed [ statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "awk", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed awk statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "benchstat", - "statementSHA256": "961fec081cdb44d1e3ef10393cce0840c1f3ec48cc068f492701cf03de6ffed7", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed benchstat statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "break", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed break statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "cd", - "statementSHA256": "1da8bf23d2c0684c704bbca52edd911233fb4bb267f1118d5b94915af4ce2757", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed cd statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "cp", - "statementSHA256": "ecf28d9064234b3ad9daccf68db49f1f91c65c21c2ac8f1dae3c06b65132d9d8", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed cp statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "echo", - "statementSHA256": "175ed3056dc0639f05e3a0de9d2616f294cfadefd6089f69cbac1dffbd6490dd", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed echo statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "echo", - "statementSHA256": "21430cc4ac1193bbb95ec1575f04ae6b65d6ada2b4bca8c4195d288c9bc449bf", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed echo statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "echo", - "statementSHA256": "6ea234c2788bcc4ba388da39084e63ae28c829e83006b91554859019723f2c07", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed echo statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "echo", - "statementSHA256": "7041a39bf0738820394b5fc1f03e6d760956bb63942be0a85157550c6987511c", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed echo statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "echo", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed echo statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "echo", - "statementSHA256": "eedcefe944dfb5c1a4d393497272271bfa8ea66bfb96435c7881d477a4df550d", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed echo statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "exit", - "statementSHA256": "1a21be8bb1dc4721d30cc1850ead617faa55ae9aebf416da4369668bdeaf0824", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed exit statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "go", - "statementSHA256": "3c1b589932f67a655ff6bfb1741a31b1c9ab4668b3e6b408e4fcf96472c20edb", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed go statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "go", - "statementSHA256": "cfd6b00644f2b1a427bf34c2864d1ea1607bc8df4873876e092c2a015f2700bb", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed go statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "grep", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed grep statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "npm", - "statementSHA256": "1da8bf23d2c0684c704bbca52edd911233fb4bb267f1118d5b94915af4ce2757", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed npm statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "read", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed read statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "tail", - "statementSHA256": "d9a0185bb46ae5c1ec79645d990431495cf18d3f75cf24ab9d9e15790d1be188", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed tail statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "tee", - "statementSHA256": "cfd6b00644f2b1a427bf34c2864d1ea1607bc8df4873876e092c2a015f2700bb", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed tee statement for benchmark.yml automation." - }, - { - "path": ".github/workflows/benchmark.yml", - "command": "true", - "statementSHA256": "961fec081cdb44d1e3ef10393cce0840c1f3ec48cc068f492701cf03de6ffed7", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "rationale": "Exact reviewed true statement for benchmark.yml automation." - }, { "path": ".github/workflows/ci.yml", "command": "$assignment", @@ -2836,7 +2644,7 @@ "command": "cd", "statementSHA256": "1da8bf23d2c0684c704bbca52edd911233fb4bb267f1118d5b94915af4ce2757", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2844,7 +2652,7 @@ "command": "npm", "statementSHA256": "1da8bf23d2c0684c704bbca52edd911233fb4bb267f1118d5b94915af4ce2757", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2852,7 +2660,7 @@ "command": "go", "statementSHA256": "3c1b589932f67a655ff6bfb1741a31b1c9ab4668b3e6b408e4fcf96472c20edb", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2860,7 +2668,7 @@ "command": "go", "statementSHA256": "0b169221a14ced8d9e2626373a08ecd6cc5d98b45fb962b73b7c5e8fa649b676", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2868,7 +2676,7 @@ "command": "go", "statementSHA256": "cfd6b00644f2b1a427bf34c2864d1ea1607bc8df4873876e092c2a015f2700bb", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2876,7 +2684,7 @@ "command": "tee", "statementSHA256": "cfd6b00644f2b1a427bf34c2864d1ea1607bc8df4873876e092c2a015f2700bb", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2884,7 +2692,7 @@ "command": "$assignment", "statementSHA256": "6911dc69ba1aa10a01cd1b0563efbb02d008c9e0ffd5c72471177bf8db8f0eec", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2892,7 +2700,7 @@ "command": "cat", "statementSHA256": "6911dc69ba1aa10a01cd1b0563efbb02d008c9e0ffd5c72471177bf8db8f0eec", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2900,7 +2708,7 @@ "command": "echo", "statementSHA256": "e5b7e17a95219aa32ca80405727547a9c29b9780744e115583f6c1a68a224750", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2908,7 +2716,7 @@ "command": "$assignment", "statementSHA256": "ffd4c2588e960687e8be3db328048a0dcb944a9c1426e6afaafafef832109740", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2916,7 +2724,7 @@ "command": "[", "statementSHA256": "50b89f8af205b68cf50a606470fdea48d51311de3bf807c03fe8aca0b92ef7c1", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2924,7 +2732,7 @@ "command": "$assignment", "statementSHA256": "50b89f8af205b68cf50a606470fdea48d51311de3bf807c03fe8aca0b92ef7c1", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2932,7 +2740,7 @@ "command": "awk", "statementSHA256": "dabc56d53c8b4b869174d2673fb6759252ac3f41af4529dd558943edda60a0b7", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2940,7 +2748,7 @@ "command": "[", "statementSHA256": "76af494e770c8a05a29ea83b525a9bed94a4a6fcbaf3ac11de547454b47fed47", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2948,7 +2756,7 @@ "command": "echo", "statementSHA256": "76af494e770c8a05a29ea83b525a9bed94a4a6fcbaf3ac11de547454b47fed47", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2956,7 +2764,7 @@ "command": "exit", "statementSHA256": "76af494e770c8a05a29ea83b525a9bed94a4a6fcbaf3ac11de547454b47fed47", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2964,7 +2772,7 @@ "command": "echo", "statementSHA256": "aa9a819f2f2977ec77ec813b0fa8b8ab2b753db0eb369df762eb7bb9010892a8", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2972,7 +2780,7 @@ "command": "benchstat", "statementSHA256": "92e1f5a57f18999c6b9359e1c7a2d9d39cd8d4c0958759cdfaa32aa2ad8bd09f", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2980,7 +2788,7 @@ "command": "awk", "statementSHA256": "92e1f5a57f18999c6b9359e1c7a2d9d39cd8d4c0958759cdfaa32aa2ad8bd09f", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2988,7 +2796,7 @@ "command": "exit", "statementSHA256": "92e1f5a57f18999c6b9359e1c7a2d9d39cd8d4c0958759cdfaa32aa2ad8bd09f", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -2996,7 +2804,7 @@ "command": "[", "statementSHA256": "3dc8c35ff510a0b4eaa921e42db66fa7f2152f40b1f4133300759c176b247f62", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3004,7 +2812,7 @@ "command": "awk", "statementSHA256": "3dc8c35ff510a0b4eaa921e42db66fa7f2152f40b1f4133300759c176b247f62", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3012,7 +2820,7 @@ "command": "exit", "statementSHA256": "3dc8c35ff510a0b4eaa921e42db66fa7f2152f40b1f4133300759c176b247f62", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3020,7 +2828,7 @@ "command": "awk", "statementSHA256": "8c1c7655a9bddd70fe48d0aef7fd3bcb7cd34152622e7355e07f7e042a5d9197", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3028,7 +2836,7 @@ "command": "echo", "statementSHA256": "6ea234c2788bcc4ba388da39084e63ae28c829e83006b91554859019723f2c07", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3036,7 +2844,7 @@ "command": "cp", "statementSHA256": "ecf28d9064234b3ad9daccf68db49f1f91c65c21c2ac8f1dae3c06b65132d9d8", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3044,7 +2852,7 @@ "command": "echo", "statementSHA256": "175ed3056dc0639f05e3a0de9d2616f294cfadefd6089f69cbac1dffbd6490dd", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." }, { @@ -3052,7 +2860,7 @@ "command": "exit", "statementSHA256": "1a21be8bb1dc4721d30cc1850ead617faa55ae9aebf416da4369668bdeaf0824", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "rationale": "Focused frozen benchmark repair command." } ] diff --git a/.github/public-workflow-presence-allowlist.json b/.github/public-workflow-presence-allowlist.json index fd3564b8..4cf7ed4c 100644 --- a/.github/public-workflow-presence-allowlist.json +++ b/.github/public-workflow-presence-allowlist.json @@ -1,10 +1,4 @@ [ - { - "path": ".github/workflows/benchmark.yml", - "contextSHA256": "24ff378f17200e8c02f20803633bc56a61c472c86d176bd9d9ca3a001f1fc300", - "state": "active", - "presence": "present" - }, { "path": ".github/workflows/ci.yml", "contextSHA256": "532f4356f1104b87bb64c51db920bcf28c9fdceabcacad84d189522a3de014bc", @@ -120,7 +114,7 @@ { "path": ".github/workflows/benchmark.yml", "contextSHA256": "0095a1d437ba5a9b5ddad0c3de98e4c911e9c96bfbdf7ad2e0a0187ef69c24b7", - "state": "staged", + "state": "active", "presence": "present" } ] From f93e3e2df2ef50ea5eac49e5e62ba2570ab71ebf Mon Sep 17 00:00:00 2001 From: Jon Langevin Date: Fri, 9 Oct 2026 14:47:16 -0400 Subject: [PATCH 2/2] fix: isolate the public policy fetch fixture event boundary --- .../public-workflow-executable-allowlist.json | 10 +-- .github/workflows/policytool/main_test.go | 70 +++++++++++++++++++ scripts/check-public-workflow-policy.sh | 2 +- scripts/test-check-public-workflow-policy.sh | 68 +++++++++++++++--- 4 files changed, 136 insertions(+), 14 deletions(-) diff --git a/.github/public-workflow-executable-allowlist.json b/.github/public-workflow-executable-allowlist.json index 730c520a..31f2f848 100644 --- a/.github/public-workflow-executable-allowlist.json +++ b/.github/public-workflow-executable-allowlist.json @@ -12,7 +12,7 @@ "workflowPath": ".github/workflows/ci.yml", "contextSHA256": "532f4356f1104b87bb64c51db920bcf28c9fdceabcacad84d189522a3de014bc", "state": "active", - "sha256": "166d4c7f272b6e249abd5bd2efadb8034105cf62df3cff2200978c6e9fb6998c", + "sha256": "5af4e6ae8b5b0ae1b7557253c398fc4c40b1f329a45ccd13639dd0b89bc9dc46", "rationale": "Enforces the credential-free public workflow boundary in CI." }, { @@ -20,7 +20,7 @@ "workflowPath": ".github/workflows/ci.yml", "contextSHA256": "532f4356f1104b87bb64c51db920bcf28c9fdceabcacad84d189522a3de014bc", "state": "active", - "sha256": "7d209bb35ff3a7a46b22f9a10a920eb30218c3403726d1dac72e0bffd1d914a4", + "sha256": "9b857524e8b736a104e1aa65a3fa5edeaf76a3787ba8942871992675440f550b", "rationale": "Exercises fail-closed public workflow policy mutations in CI." }, { @@ -36,7 +36,7 @@ "workflowPath": ".github/workflows/ci.yml", "contextSHA256": "37b7935261b56568daee7ad04ebb647f5a53bef336b5da0e8efb5df5e666e06a", "state": "staged", - "sha256": "166d4c7f272b6e249abd5bd2efadb8034105cf62df3cff2200978c6e9fb6998c", + "sha256": "5af4e6ae8b5b0ae1b7557253c398fc4c40b1f329a45ccd13639dd0b89bc9dc46", "rationale": "Staged v0.86 CI authority. Enforces the credential-free public workflow boundary in CI." }, { @@ -52,7 +52,7 @@ "workflowPath": ".github/workflows/ci.yml", "contextSHA256": "37b7935261b56568daee7ad04ebb647f5a53bef336b5da0e8efb5df5e666e06a", "state": "staged", - "sha256": "7d209bb35ff3a7a46b22f9a10a920eb30218c3403726d1dac72e0bffd1d914a4", + "sha256": "9b857524e8b736a104e1aa65a3fa5edeaf76a3787ba8942871992675440f550b", "rationale": "Staged v0.86 CI authority. Exercises fail-closed public workflow policy mutations in CI." }, { @@ -83,7 +83,7 @@ "contextSHA256": "5e3ee7768ef2d57b0c1e15e6b27b1efbb892454db4b762cfc56806e7985248af", "path": "scripts/check-public-workflow-policy.sh", "rationale": "Stage the public-workflow Go 1.27.1 bridge frozen at 667a58a396b7c80af0ae7fb7bbb3a0b1c8b0c95e: bind only this exact repository executable scripts/check-public-workflow-policy.sh to the parser-derived hashes and workflow context. Adoption and promotion remain separate; no secret or provider authority is added.", - "sha256": "166d4c7f272b6e249abd5bd2efadb8034105cf62df3cff2200978c6e9fb6998c", + "sha256": "5af4e6ae8b5b0ae1b7557253c398fc4c40b1f329a45ccd13639dd0b89bc9dc46", "state": "active", "workflowPath": ".github/workflows/public-workflow-policy.yml" }, diff --git a/.github/workflows/policytool/main_test.go b/.github/workflows/policytool/main_test.go index 456b467d..b03a6979 100644 --- a/.github/workflows/policytool/main_test.go +++ b/.github/workflows/policytool/main_test.go @@ -1,15 +1,18 @@ package main import ( + "context" "encoding/json" "go/ast" "go/parser" "go/token" "os" + "os/exec" "path/filepath" "strconv" "strings" "testing" + "time" "gopkg.in/yaml.v3" "mvdan.cc/sh/v3/syntax" @@ -1447,3 +1450,70 @@ func TestAuthorityInventoryRejectsSymlinkedFixedAncestor(t *testing.T) { t.Fatalf("symlinked fixed-file ancestor error = %v", err) } } + +// Run only the real dependency-fixture function. Calling the full harness from +// its own policy-tool test would recurse into go test. +func TestPolicyFetchFixtureOwnsEventBoundary(t *testing.T) { + root := filepath.Join("..", "..", "..") + harness, err := os.ReadFile(filepath.Join(root, "scripts", "test-check-public-workflow-policy.sh")) + if err != nil { + t.Fatalf("read policy mutation harness: %v", err) + } + const signature = "\nrun_candidate_fetch() {\n" + if strings.Count(string(harness), signature) != 1 { + t.Fatal("policy mutation harness must define one fetch fixture") + } + start := strings.Index(string(harness), signature) + 1 + end := strings.Index(string(harness)[start:], "\n}\n") + if end < 0 { + t.Fatal("fetch fixture closing boundary missing") + } + fixture := string(harness)[start : start+end+3] + bash, err := exec.LookPath("bash") + if err != nil { + t.Fatalf("find bash: %v", err) + } + const probe = `set -euo pipefail +[[ "${EVENT_NAME}:${BASE_REF}:${EVENT_REF}" == pull_request_target:main:refs/heads/main ]] +[[ "$CANDIDATE_REPOSITORY" == example/repo ]] +[[ "$CANDIDATE_SHA" == 0123456789012345678901234567890123456789 ]] +[[ "$GIT_ASKPASS" == /bin/false ]] +[[ "$GIT_CONFIG_GLOBAL" == /dev/null ]] +[[ "$GIT_CONFIG_NOSYSTEM" == 1 ]] +[[ "$GIT_TERMINAL_PROMPT" == 0 ]] +printf 'fixture-event-boundary-ok\n' +` + for _, tc := range []struct { + name string + env []string + }{ + {name: "unset event variables"}, + {name: "hostile inherited event", env: []string{ + "EVENT_NAME=workflow_run", "BASE_REF=develop", "EVENT_REF=refs/tags/v0.0.0", + }}, + } { + t.Run(tc.name, func(t *testing.T) { + leaf := t.TempDir() + probePath := filepath.Join(leaf, "fetch-boundary.sh") + if err := os.WriteFile(probePath, []byte(probe), 0600); err != nil { + t.Fatal(err) + } + if err := os.Mkdir(filepath.Join(leaf, "fake-bin"), 0700); err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + body := "set -euo pipefail\n" + fixture + ` +fake_bin="$1/fake-bin" +candidate_fetch_script="$2" +run_candidate_fetch "$1/work" example/repo 0123456789012345678901234567890123456789 "$1/archive" +` + cmd := exec.CommandContext(ctx, bash, "-c", body, "fetch-fixture-test", leaf, probePath) + cmd.Env = append([]string{"PATH=/usr/bin:/bin"}, tc.env...) + out, err := cmd.CombinedOutput() + if err != nil || string(out) != "fixture-event-boundary-ok\n" { + t.Fatalf("fetch fixture must own its event tuple: err=%v output=%q", err, out) + } + }) + } +} diff --git a/scripts/check-public-workflow-policy.sh b/scripts/check-public-workflow-policy.sh index 0012f58b..962fbc28 100755 --- a/scripts/check-public-workflow-policy.sh +++ b/scripts/check-public-workflow-policy.sh @@ -75,7 +75,7 @@ verify_policytool_file() { verify_policytool() { verify_policytool_layout verify_policytool_file main.go 8dba6ad341fa07644868fd43717aff162c4feae1694ee9a122ef4cd401214a00 - verify_policytool_file main_test.go a88f4ec70a2736e54bf887594da855fb6d25d2cecb35321cd5fa8a2455304212 + verify_policytool_file main_test.go 6b198d0ac211a22f39e65a885c903c5a956ed2e5642a2f0b599496efdaa2ad5c verify_policytool_file go.mod 0a2d135980310757f36e733161b94498b4e0a1b6ac8c6de8a799f542d6c9ddb8 verify_policytool_file go.sum 790ef858e5aeed12269a69e764ac69c02c3877678b0e7d9384ad3728b6e09f6c } diff --git a/scripts/test-check-public-workflow-policy.sh b/scripts/test-check-public-workflow-policy.sh index a0b878b0..c3fac57f 100755 --- a/scripts/test-check-public-workflow-policy.sh +++ b/scripts/test-check-public-workflow-policy.sh @@ -89,6 +89,9 @@ cleanup() { } trap cleanup EXIT +# Validate the real input before any external mutation fixture is constructed. +"${checker_binary}" --scan-root "${production_repo_root}" >/dev/null + # BEGIN root-module-graph-check root_module_graph="$(GOWORK=off GOFLAGS=-mod=readonly go list -m all)" if grep -Eq '^mvdan\.cc/sh/v3 ' <<<"${root_module_graph}"; then @@ -1524,6 +1527,9 @@ run_candidate_fetch() { ( cd "${workdir}" PATH="${fake_bin}:$PATH" \ + EVENT_NAME=pull_request_target \ + BASE_REF=main \ + EVENT_REF=refs/heads/main \ CANDIDATE_REPOSITORY="${repository}" \ CANDIDATE_SHA="${sha}" \ GIT_ASKPASS=/bin/false \ @@ -2259,15 +2265,42 @@ active_authority="${tmp_dir}/authority-active.json" active_verifier="${tmp_dir}/authority-active-verifier.sh" staged_authority="${tmp_dir}/authority-staged.json" future_verifier="${tmp_dir}/authority-future-verifier.sh" -cp "${candidate_authority}" "${active_authority}" -cp "${candidate_verifier}" "${active_verifier}" -cp "${candidate_verifier}" "${future_verifier}" +original_candidate_authority="${tmp_dir}/authority-original-candidate.json" +original_archive_authority="${tmp_dir}/authority-original-archive.json" +original_archive_verifier="${tmp_dir}/authority-original-archive-verifier.sh" +cp -p "${candidate_authority}" "${original_candidate_authority}" +cp -p "${archive_authority}" "${original_archive_authority}" +cp -p "${candidate_verifier}" "${active_verifier}" +cp -p "${archive_verifier}" "${original_archive_verifier}" + +# Only this external archive uses a synthetic active baseline. The real checker +# must verify the complete inventory, not just a matching subset of file hashes. +realized_bundle_count=0 +bundle_count="$(jq -er '.bundles | length' "${original_archive_authority}")" +for ((bundle_index=0; bundle_index"${archive_authority}" + if "${archive_checker}" --scan-root "${archive_repo}" --bootstrap-authority \ + >"${tmp_dir}/authority-realized-${bundle_index}.log" 2>&1; then + realized_bundle_count=$((realized_bundle_count + 1)) + cp -p "${archive_authority}" "${active_authority}" + fi +done +if [[ "${realized_bundle_count}" -ne 1 ]]; then + echo "synthetic authority fixture requires exactly one complete realized bundle" >&2 + exit 1 +fi +cp "${active_authority}" "${archive_authority}" +cp "${active_authority}" "${candidate_authority}" +"${archive_checker}" --scan-root "${candidate_root}" >/dev/null +cp -p "${candidate_verifier}" "${future_verifier}" printf '\n# authority lifecycle fixture\n' >>"${future_verifier}" future_verifier_sha="$(sha256_file "${future_verifier}")" jq --arg path "${authority_path}" --arg sha "${future_verifier_sha}" ' .bundles += [{ state: "staged", - files: (.bundles[0].files | map(if .path == $path then .sha256 = $sha else . end)) + files: (.bundles[] | select(.state == "active") | .files | map(if .path == $path then .sha256 = $sha else . end)) }] ' "${active_authority}" >"${staged_authority}" @@ -2275,6 +2308,21 @@ jq --arg path "${authority_path}" --arg sha "${future_verifier_sha}" ' cp "${staged_authority}" "${candidate_authority}" "${checker_binary}" --scan-root "${candidate_root}" >/dev/null +# Synthetic isolation must not weaken the production one-staged-bundle rule. +jq '.bundles += [(.bundles[] | select(.state == "staged"))]' \ + "${staged_authority}" >"${candidate_authority}" +set +e +two_staged_output="$("${checker_binary}" --scan-root "${candidate_root}" 2>&1)" +two_staged_status=$? +set -e +if [[ "${two_staged_status}" -eq 0 ]] || ! grep -Fq -- \ + "authority manifest may contain at most one staged bundle" <<<"${two_staged_output}"; then + echo "two staged authority bundles were not explicitly rejected" >&2 + printf '%s\n' "${two_staged_output}" >&2 + exit 1 +fi +cp "${staged_authority}" "${candidate_authority}" + # The same pull request cannot both introduce and realize the staged bundle. cp "${future_verifier}" "${candidate_verifier}" set +e @@ -2298,10 +2346,14 @@ jq '.bundles = [(.bundles[] | select(.state == "staged") | .state = "active")]' "${staged_authority}" >"${candidate_authority}" "${archive_checker}" --scan-root "${candidate_root}" >/dev/null -cp "${active_authority}" "${candidate_authority}" -cp "${active_verifier}" "${candidate_verifier}" -cp "${active_authority}" "${archive_authority}" -cp "${active_verifier}" "${archive_verifier}" +cp -p "${original_candidate_authority}" "${candidate_authority}" +cp -p "${active_verifier}" "${candidate_verifier}" +cp -p "${original_archive_authority}" "${archive_authority}" +cp -p "${original_archive_verifier}" "${archive_verifier}" +assert_file_unchanged "candidate authority manifest" "${original_candidate_authority}" "${candidate_authority}" +assert_file_unchanged "archive authority manifest" "${original_archive_authority}" "${archive_authority}" +assert_file_unchanged "candidate verifier" "${active_verifier}" "${candidate_verifier}" +assert_file_unchanged "archive verifier" "${original_archive_verifier}" "${archive_verifier}" (cd "${policytool}" && \ "${checker_binary}" --scan-root "${candidate_root}" \