Skip to content

Commit 5eeea47

Browse files
Pigbibicodex
andauthored
fix(oidc): allow exact PR review workflow SHA (#98)
Co-authored-by: Codex <noreply@openai.com>
1 parent 8a253d5 commit 5eeea47

4 files changed

Lines changed: 53 additions & 2 deletions

File tree

.github/workflows/vps_codex_service_ops.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
CODEX_AUDIT_SERVICE_ALLOWED_REFS: refs/heads/main,refs/pull/*/merge
6262
# Rotation tracked in #64; remove the old SHA by 2026-07-18 after final strategy-run verification.
6363
# Must match the immutable QPK `uses:` ref pinned by all strategy drift callers.
64-
CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS: QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@refs/heads/main,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@644cd9002ae92f2aaca6f7efb4afa4986fae05ea,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@d0a081ca5868faaf1a6dd870cf4b93643978cd11,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@fcddef20eea5deb876e739263042acdcb3e9cd1b,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@4f8465b28a6787d39d21e50f9d95a77841d6ad56,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@651c9ac4f37ce6e7fe1bac84dc7646cd5abc9e6e
64+
CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS: QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@refs/heads/main,QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@86458c44b06593b6d7a1602b3c38e7a1c143ef17,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@644cd9002ae92f2aaca6f7efb4afa4986fae05ea,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@d0a081ca5868faaf1a6dd870cf4b93643978cd11,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@fcddef20eea5deb876e739263042acdcb3e9cd1b,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@4f8465b28a6787d39d21e50f9d95a77841d6ad56,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@651c9ac4f37ce6e7fe1bac84dc7646cd5abc9e6e
6565
CODEX_AUDIT_SERVICE_ALLOWED_DIRECT_REPOSITORIES: QuantStrategyLab/AIAuditBridge
6666
CODEX_AUDIT_SERVICE_ALLOWED_SOURCE_REPOSITORIES: QuantStrategyLab/AIAuditBridge,QuantStrategyLab/BinancePlatform,QuantStrategyLab/CharlesSchwabPlatform,QuantStrategyLab/CnEquitySnapshotPipelines,QuantStrategyLab/CnEquityStrategies,QuantStrategyLab/CryptoLivePoolPipelines,QuantStrategyLab/CryptoStrategies,QuantStrategyLab/FirstradePlatform,QuantStrategyLab/HkEquitySnapshotPipelines,QuantStrategyLab/HkEquityStrategies,QuantStrategyLab/IBKRGatewayManager,QuantStrategyLab/InteractiveBrokersPlatform,QuantStrategyLab/LongBridgePlatform,QuantStrategyLab/MarketSignalSources,QuantStrategyLab/PoliticalEventTrackingResearch,QuantStrategyLab/QmtPlatform,QuantStrategyLab/QuantAdvisorResearch,QuantStrategyLab/QuantPlatformKit,QuantStrategyLab/QuantRuntimeSettings,QuantStrategyLab/QuantStrategyPlugins,QuantStrategyLab/ResearchSignalContextPipelines,QuantStrategyLab/SchwabTokenAutoRefresher,QuantStrategyLab/UsEquitySnapshotPipelines,QuantStrategyLab/UsEquityStrategies
6767
CODEX_AUDIT_SERVICE_MODEL: ${{ vars.CODEX_AUDIT_SERVICE_MODEL }}

scripts/deploy_codex_audit_service.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ ALLOWED_REFS="${CODEX_AUDIT_SERVICE_ALLOWED_REFS:-refs/heads/main,refs/pull/*/me
1616
ALLOWED_REPOSITORY_VISIBILITIES="${CODEX_AUDIT_SERVICE_ALLOWED_REPOSITORY_VISIBILITIES:-public}"
1717
# Single source of truth for delegated drift code. Rotation #64 removes the old SHA by 2026-07-18.
1818
# Rotate with the two-SHA procedure in docs/drift_oidc_rotation.md.
19-
ALLOWED_JOB_WORKFLOW_REFS="${CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS:-QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@refs/heads/main,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@644cd9002ae92f2aaca6f7efb4afa4986fae05ea,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@d0a081ca5868faaf1a6dd870cf4b93643978cd11,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@fcddef20eea5deb876e739263042acdcb3e9cd1b,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@4f8465b28a6787d39d21e50f9d95a77841d6ad56,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@651c9ac4f37ce6e7fe1bac84dc7646cd5abc9e6e}"
19+
ALLOWED_JOB_WORKFLOW_REFS="${CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS:-QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@refs/heads/main,QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@86458c44b06593b6d7a1602b3c38e7a1c143ef17,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@644cd9002ae92f2aaca6f7efb4afa4986fae05ea,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@d0a081ca5868faaf1a6dd870cf4b93643978cd11,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@fcddef20eea5deb876e739263042acdcb3e9cd1b,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@4f8465b28a6787d39d21e50f9d95a77841d6ad56,QuantStrategyLab/QuantPlatformKit/.github/workflows/reusable-drift-check.yml@651c9ac4f37ce6e7fe1bac84dc7646cd5abc9e6e}"
2020
ALLOWED_DIRECT_REPOSITORIES="${CODEX_AUDIT_SERVICE_ALLOWED_DIRECT_REPOSITORIES:-QuantStrategyLab/AIAuditBridge}"
2121
ALLOWED_SOURCE_REPOSITORIES="${CODEX_AUDIT_SERVICE_ALLOWED_SOURCE_REPOSITORIES:-QuantStrategyLab/AIAuditBridge,QuantStrategyLab/BinancePlatform,QuantStrategyLab/CharlesSchwabPlatform,QuantStrategyLab/CnEquitySnapshotPipelines,QuantStrategyLab/CnEquityStrategies,QuantStrategyLab/CryptoLivePoolPipelines,QuantStrategyLab/CryptoStrategies,QuantStrategyLab/FirstradePlatform,QuantStrategyLab/HkEquitySnapshotPipelines,QuantStrategyLab/HkEquityStrategies,QuantStrategyLab/IBKRGatewayManager,QuantStrategyLab/InteractiveBrokersPlatform,QuantStrategyLab/LongBridgePlatform,QuantStrategyLab/MarketSignalSources,QuantStrategyLab/PoliticalEventTrackingResearch,QuantStrategyLab/QmtPlatform,QuantStrategyLab/QuantAdvisorResearch,QuantStrategyLab/QuantPlatformKit,QuantStrategyLab/QuantRuntimeSettings,QuantStrategyLab/QuantStrategyPlugins,QuantStrategyLab/ResearchSignalContextPipelines,QuantStrategyLab/SchwabTokenAutoRefresher,QuantStrategyLab/UsEquitySnapshotPipelines,QuantStrategyLab/UsEquityStrategies}"
2222
JOB_DIR="${CODEX_AUDIT_SERVICE_JOB_DIR:-/var/lib/codex-audit-bridge/jobs}"

tests/test_oidc_reusable_workflow_auth.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,36 @@ def test_non_direct_caller_requires_trusted_reusable_workflow(self) -> None:
4444
payload["job_workflow_ref"] = "QuantStrategyLab/AIAuditBridge/.github/workflows/codex_pr_review.yml@refs/heads/main"
4545
self.assertEqual(self._verify(payload, env)["repository"], "QuantStrategyLab/QuantRuntimeSettings")
4646

47+
def test_exact_audit_bridge_sha_is_allowlisted_without_broadening_job_ref(self) -> None:
48+
exact_job_ref = (
49+
"QuantStrategyLab/AIAuditBridge/.github/workflows/"
50+
"codex_pr_review.yml@86458c44b06593b6d7a1602b3c38e7a1c143ef17"
51+
)
52+
payload: dict[str, object] = {
53+
"aud": "quant-codex-audit",
54+
"iss": auth.GITHUB_OIDC_ISSUER,
55+
"exp": int(time.time()) + 300,
56+
"repository": "QuantStrategyLab/QuantRuntimeSettings",
57+
"workflow_ref": "QuantStrategyLab/QuantRuntimeSettings/.github/workflows/codex_pr_review.yml@refs/heads/main",
58+
"job_workflow_ref": exact_job_ref,
59+
"ref": "refs/heads/main",
60+
"repository_visibility": "public",
61+
}
62+
env = {
63+
"CODEX_AUDIT_SERVICE_ALLOWED_REPOSITORIES": "QuantStrategyLab/QuantRuntimeSettings",
64+
"CODEX_AUDIT_SERVICE_ALLOWED_WORKFLOW_REFS": "QuantStrategyLab/QuantRuntimeSettings/.github/workflows/codex_pr_review.yml@refs/heads/main",
65+
"CODEX_AUDIT_SERVICE_ALLOWED_REFS": "refs/heads/main",
66+
"CODEX_AUDIT_SERVICE_ALLOWED_DIRECT_REPOSITORIES": "QuantStrategyLab/AIAuditBridge",
67+
"CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS": exact_job_ref,
68+
"CODEX_AUDIT_SERVICE_ALLOWED_REPOSITORY_VISIBILITIES": "public",
69+
}
70+
71+
self.assertEqual(self._verify(payload, env)["repository"], "QuantStrategyLab/QuantRuntimeSettings")
72+
73+
payload["job_workflow_ref"] = f"{exact_job_ref}0"
74+
with self.assertRaisesRegex(PermissionError, "job workflow ref is not allowed"):
75+
self._verify(payload, env)
76+
4777
def test_direct_audit_bridge_caller_does_not_require_reusable_workflow(self) -> None:
4878
payload: dict[str, object] = {
4979
"aud": "quant-codex-audit",

tests/test_run_monthly_codex_audit.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2511,6 +2511,27 @@ def test_vps_deploy_defaults_match_workflow_allowlists(self) -> None:
25112511
workflow_value = workflow_line.removeprefix(f"{workflow_name}: ")
25122512
self.assertEqual(script_value, workflow_value)
25132513

2514+
def test_vps_deploy_persists_exact_audit_bridge_pr_review_sha(self) -> None:
2515+
exact_job_ref = (
2516+
"QuantStrategyLab/AIAuditBridge/.github/workflows/"
2517+
"codex_pr_review.yml@86458c44b06593b6d7a1602b3c38e7a1c143ef17"
2518+
)
2519+
deploy_script = Path("scripts/deploy_codex_audit_service.sh").read_text(encoding="utf-8")
2520+
workflow = Path(".github/workflows/vps_codex_service_ops.yml").read_text(encoding="utf-8")
2521+
script_line = next(
2522+
line for line in deploy_script.splitlines() if line.startswith('ALLOWED_JOB_WORKFLOW_REFS="')
2523+
)
2524+
workflow_line = next(
2525+
line.strip()
2526+
for line in workflow.splitlines()
2527+
if line.strip().startswith("CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS: ")
2528+
)
2529+
script_value = script_line.split(":-", 1)[1][:-2]
2530+
workflow_value = workflow_line.removeprefix("CODEX_AUDIT_SERVICE_ALLOWED_JOB_WORKFLOW_REFS: ")
2531+
2532+
self.assertIn(exact_job_ref, script_value.split(","))
2533+
self.assertIn(exact_job_ref, workflow_value.split(","))
2534+
25142535

25152536
if __name__ == "__main__":
25162537
unittest.main()

0 commit comments

Comments
 (0)