Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/v2-ci-ordinary-settlement.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
env:
PACKAGE_VERSION: 0.1.3
# Published release asset digest, independently read back from GitHub.
PACKAGE_SHA256: c505159023f0740c885696ebe24f8e066e197d9cf09cc3e64050d4210bcd0cdb
PACKAGE_VERSION: 0.3.0
# Verified served release asset; exact original candidate bytes.
PACKAGE_SHA256: a8cd6d602e1203257e1241df0b5dfdb9d867334b46dc406d8cdaa8e6d2b3019c
permissions:
actions: read
contents: read
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
set -euo pipefail
receipt="$RUNNER_TEMP/ordinary-v2-receipt/ordinary-v2-preflight.json"
test "$(sha256sum "$receipt" | cut -d ' ' -f 1)" = "$EXPECTED_RECEIPT_SHA256"
python3 tools/v2-ci-ordinary-observe.py verify "$receipt"
python3 tools/v2-ci-ordinary-observe.py verify-main "$receipt"
- name: Set up the pinned .NET SDK
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68
with:
Expand Down Expand Up @@ -125,4 +125,4 @@ jobs:
V2_ORDINARY_AUTHORIZER_PRIVATE_KEY: ${{ secrets.V2_ORDINARY_AUTHORIZER_PRIVATE_KEY }}
run: |
set -euo pipefail
"$RUNNER_TEMP/ordinary-v2-cli/fsgg-coordination" ordinary-settlement execute
"$RUNNER_TEMP/ordinary-v2-cli/fsgg-coordination" ordinary-settlement execute-main
107 changes: 107 additions & 0 deletions policy/v2-ci-ordinary-settlement-main-anchor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{
"schema": "fsgg.github.v2-ci-ordinary-settlement-anchor/1",
"policyId": "v2-ci-i1-ordinary-settlement-v1",
"operationClass": "ordinary-post-merge-delivery-settlement",
"authorizer": {
"keyId": "ordinary-v2-production-6121c3f2ab38acf3",
"algorithm": "RSA-PSS-SHA256",
"publicKeySpkiSha256": "6121c3f2ab38acf38a37f782eb7775da78598b9cfabc0054917d3d59fe50e3ee"
},
"writer": {
"appId": 5064713,
"installationId": 164553252,
"repository": "FS-GG/FS.GG.Coordination.Authority",
"repositoryId": 1351660651,
"permissions": {
"contents": "write",
"metadata": "read"
}
},
"rulesets": {
"writer": {
"id": 24802693,
"name": "ordinary-v2-main-writer",
"enforcement": "active",
"updatedAt": "2026-10-09T18:56:41.235+02:00",
"conditions": {
"ref_name": {
"exclude": [],
"include": [
"refs/heads/main"
]
}
},
"rules": [
{
"type": "creation"
},
{
"type": "update"
}
],
"bypassActors": [
{
"actorId": 4882140,
"actorType": "Integration",
"bypassMode": "always"
},
{
"actorId": 5064713,
"actorType": "Integration",
"bypassMode": "always"
}
]
},
"integrity": {
"id": 24802698,
"name": "ordinary-v2-main-integrity",
"enforcement": "active",
"updatedAt": "2026-10-09T18:56:42.726+02:00",
"conditions": {
"ref_name": {
"exclude": [],
"include": [
"refs/heads/main"
]
}
},
"rules": [
{
"type": "deletion"
},
{
"type": "non_fast_forward"
}
],
"bypassActors": []
}
},
"effectiveRules": [
{
"type": "deletion",
"rulesetId": 24802698,
"rulesetSourceType": "Repository",
"rulesetSource": "FS-GG/FS.GG.Coordination.Authority"
},
{
"type": "non_fast_forward",
"rulesetId": 24802698,
"rulesetSourceType": "Repository",
"rulesetSource": "FS-GG/FS.GG.Coordination.Authority"
},
{
"type": "creation",
"rulesetId": 24802693,
"rulesetSourceType": "Repository",
"rulesetSource": "FS-GG/FS.GG.Coordination.Authority"
},
{
"type": "update",
"rulesetId": 24802693,
"rulesetSourceType": "Repository",
"rulesetSource": "FS-GG/FS.GG.Coordination.Authority"
}
],
"acceptedAt": "2026-10-09T19:31:28.661736+00:00",
"sourceCommit": "8eef1ab7f205132553632e03dc650e7ecdd03679"
}
31 changes: 16 additions & 15 deletions policy/v2-ci-ordinary-settlement.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"repositoryId": 1292226968
},
"sourceImplementation": {
"repository": "FS-GG/.github",
"commit": "7e1ac5f4689cbc8cd9b6db93b5ed7898c0c68319",
"adaptation": "audio-local-protected-policy-authority",
"observerSha256": "6e63f6f724fb267e77ef02f41b4c58a833e0dc5b08c003f07fd16c89e4f7fd55",
"repository": "FS-GG/FS.GG.Coordination",
"commit": "8eef1ab7f205132553632e03dc650e7ecdd03679",
"adaptation": "audio-local-protected-policy-authority; main-storage extension with local profile preserved",
"observerSha256": "7f5500d810ab9169d967f8c19fbcb01d706ebf82fdeea6e4a6927b0b19eef29a",
"qualificationSha256": "7eccceae0aad930d3cdbce24767cbb9555693ca7032e660d1d71519a79529454"
},
"operationClass": "ordinary-post-merge-delivery-settlement",
Expand Down Expand Up @@ -106,19 +106,20 @@
},
"packagePin": {
"status": "published-served-verified",
"version": "0.1.3",
"sha256": "c505159023f0740c885696ebe24f8e066e197d9cf09cc3e64050d4210bcd0cdb",
"hostedCandidateRunId": 36404053953,
"publishRunId": 36407941780,
"publishRunHeadSha": "dc8a85eec6a3b141dd35e79c6b7ca521c3511753",
"publishWorkflow": ".github/workflows/callable-cli-release-publish.yml",
"releaseUrl": "https://github.com/FS-GG/FS.GG.Coordination/releases/tag/v0.1.3",
"releasePublishedAt": "2026-09-28T10:11:00Z",
"assetName": "FS.GG.Coordination.Cli.0.1.3.nupkg",
"assetSize": 6399657,
"version": "0.3.0",
"sha256": "a8cd6d602e1203257e1241df0b5dfdb9d867334b46dc406d8cdaa8e6d2b3019c",
"sourceCommit": "8eef1ab7f205132553632e03dc650e7ecdd03679",
"servedPackageVerified": true,
"requiredBeforeActivation": true,
"requiredCapability": "audio-v1 selected source",
"requiredBeforeActivation": true
"publishRunId": 37983508705,
"publishRunHeadSha": "401a89e3e63c0eefda02124475e92d0c4b752cfd",
"releasePublishedAt": "2026-10-09T19:55:53Z",
"assetSize": 8694990,
"hostedCandidateRunId": 37977490696,
"releaseUrl": "https://github.com/FS-GG/FS.GG.Coordination/releases/tag/v0.3.0",
"assetName": "FS.GG.Coordination.Cli.0.3.0.nupkg",
"publishWorkflow": ".github/workflows/callable-cli-release-publish.yml"
},
"credentialInventory": [
{
Expand Down
22 changes: 11 additions & 11 deletions tests/v2-ci-ordinary-observe/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AudioObservationSourceTests(unittest.TestCase):
def test_tools_are_exact_committed_profile_bytes(self):
expected = {
"tools/v2-ci-ordinary-observe.py":
"6e63f6f724fb267e77ef02f41b4c58a833e0dc5b08c003f07fd16c89e4f7fd55",
"7f5500d810ab9169d967f8c19fbcb01d706ebf82fdeea6e4a6927b0b19eef29a",
"tools/v2-ci-ordinary-qualification.py":
"7eccceae0aad930d3cdbce24767cbb9555693ca7032e660d1d71519a79529454",
}
Expand Down Expand Up @@ -90,18 +90,18 @@ def test_workflow_prepares_bounded_settlement_but_keeps_activation_receipt_guard
self.assertIn("FSGG_V2_SOURCE_PROFILE: audio-v1", workflow)
self.assertIn("persist-credentials: false", workflow)
self.assertIn("python3 tools/v2-ci-ordinary-observe.py produce", workflow)
self.assertIn("python3 tools/v2-ci-ordinary-observe.py verify", workflow)
self.assertIn("PACKAGE_VERSION: 0.1.3", workflow)
self.assertIn("python3 tools/v2-ci-ordinary-observe.py verify-main", workflow)
self.assertIn("PACKAGE_VERSION: 0.3.0", workflow)
self.assertIn(
"PACKAGE_SHA256: c505159023f0740c885696ebe24f8e066e197d9cf09cc3e64050d4210bcd0cdb",
"PACKAGE_SHA256: a8cd6d602e1203257e1241df0b5dfdb9d867334b46dc406d8cdaa8e6d2b3019c",
workflow,
)
self.assertIn(
"https://github.com/FS-GG/FS.GG.Coordination/releases/download/v$PACKAGE_VERSION/FS.GG.Coordination.Cli.$PACKAGE_VERSION.nupkg",
workflow,
)
self.assertNotIn("api.nuget.org/v3-flatcontainer", workflow)
self.assertIn("ordinary-settlement execute", workflow)
self.assertIn("ordinary-settlement execute-main", workflow)
for name in (
"V2_ORDINARY_APP_ID", "V2_ORDINARY_APP_PRIVATE_KEY",
"V2_ORDINARY_AUTHORIZER_PRIVATE_KEY",
Expand Down Expand Up @@ -130,9 +130,9 @@ def test_policy_and_anchor_bind_source_and_shared_authority_scope(self):
},
policy["selectedSource"],
)
self.assertEqual("7e1ac5f4689cbc8cd9b6db93b5ed7898c0c68319",
self.assertEqual("8eef1ab7f205132553632e03dc650e7ecdd03679",
policy["sourceImplementation"]["commit"])
self.assertEqual("audio-local-protected-policy-authority",
self.assertEqual("audio-local-protected-policy-authority; main-storage extension with local profile preserved",
policy["sourceImplementation"]["adaptation"])
self.assertEqual("installed", policy["status"])
self.assertTrue(policy["credentialJob"]["installed"])
Expand All @@ -151,13 +151,13 @@ def test_policy_and_anchor_bind_source_and_shared_authority_scope(self):
set(observation["secretNames"]),
)
self.assertEqual("published-served-verified", policy["packagePin"]["status"])
self.assertEqual("0.1.3", policy["packagePin"]["version"])
self.assertEqual("0.3.0", policy["packagePin"]["version"])
self.assertEqual(
"c505159023f0740c885696ebe24f8e066e197d9cf09cc3e64050d4210bcd0cdb",
"a8cd6d602e1203257e1241df0b5dfdb9d867334b46dc406d8cdaa8e6d2b3019c",
policy["packagePin"]["sha256"],
)
self.assertEqual(36407941780, policy["packagePin"]["publishRunId"])
self.assertEqual("FS.GG.Coordination.Cli.0.1.3.nupkg",
self.assertEqual(37983508705, policy["packagePin"]["publishRunId"])
self.assertEqual("FS.GG.Coordination.Cli.0.3.0.nupkg",
policy["packagePin"]["assetName"])
self.assertTrue(policy["packagePin"]["servedPackageVerified"])
self.assertTrue(all(item["provisioned"] is True
Expand Down
6 changes: 3 additions & 3 deletions tests/v2-ci-ordinary-qualification/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ def test_policy_installs_published_package_only_with_enrolled_credentials(self):
for item in self.policy["credentialInventory"]))
self.assertEqual("published-served-verified",
self.policy["packagePin"]["status"])
self.assertEqual("0.1.3", self.policy["packagePin"]["version"])
self.assertEqual("0.3.0", self.policy["packagePin"]["version"])
self.assertEqual(
"c505159023f0740c885696ebe24f8e066e197d9cf09cc3e64050d4210bcd0cdb",
"a8cd6d602e1203257e1241df0b5dfdb9d867334b46dc406d8cdaa8e6d2b3019c",
self.policy["packagePin"]["sha256"],
)
self.assertEqual(36407941780, self.policy["packagePin"]["publishRunId"])
self.assertEqual(37983508705, self.policy["packagePin"]["publishRunId"])
self.assertTrue(self.policy["packagePin"]["servedPackageVerified"])
self.assertEqual(36410714353,
self.policy["credentialEnrollmentEvidence"]["bridgeRunId"])
Expand Down
17 changes: 11 additions & 6 deletions tools/v2-ci-ordinary-observe.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ def current_file(repository: str, path: str, revision: str) -> bytes:
raise QUALIFICATION.Refusal(f"current protected file malformed: {path}") from error


def current_authority(repository: str, policy: dict, policy_path: pathlib.Path = POLICY_PATH) -> None:
def current_authority(repository: str, policy: dict, policy_path: pathlib.Path = POLICY_PATH,
*, main_storage: bool = False) -> None:
"""Fence a queued or rerun job against the present protected source."""
before = api(f"repos/{repository}/git/ref/heads/main")
revision = before.get("object", {}).get("sha") if isinstance(before, dict) else None
Expand All @@ -84,6 +85,8 @@ def current_authority(repository: str, policy: dict, policy_path: pathlib.Path =
paths.append("policy/v2-ci-ordinary-settlement-rehearsal-anchor.json"
if policy_path == REHEARSAL_POLICY_PATH
else "policy/v2-ci-ordinary-settlement-anchor.json")
if main_storage:
paths.append("policy/v2-ci-ordinary-settlement-main-anchor.json")
for path in paths:
if current_file(repository, path, revision) != (ROOT / path).read_bytes():
raise QUALIFICATION.Refusal(f"current protected authority changed: {path}")
Expand Down Expand Up @@ -163,7 +166,8 @@ def equivalent_tree(repository: str, head: str, source: str, base: str) -> str:
return head_tree


def observe(environ: dict[str, str], rehearsal: bool = False) -> dict:
def observe(environ: dict[str, str], rehearsal: bool = False,
*, main_storage: bool = False) -> dict:
policy_path = REHEARSAL_POLICY_PATH if rehearsal else POLICY_PATH
policy = QUALIFICATION.read_json(str(policy_path))
source = environ.get("GITHUB_SHA", "")
Expand Down Expand Up @@ -204,7 +208,7 @@ def observe(environ: dict[str, str], rehearsal: bool = False) -> dict:
capture_output=True, text=True, cwd=ROOT).stdout.strip()
if checkout != source:
raise QUALIFICATION.Refusal("checkout differs from triggering source")
current_authority(policy["repository"], policy, policy_path)
current_authority(policy["repository"], policy, policy_path, main_storage=main_storage)
run_id, attempt = environ.get("GITHUB_RUN_ID", ""), environ.get("GITHUB_RUN_ATTEMPT", "")
if not run_id.isdecimal() or not attempt.isdecimal() or int(run_id) < 1 or int(attempt) < 1:
raise QUALIFICATION.Refusal("invalid workflow run identity")
Expand Down Expand Up @@ -343,12 +347,13 @@ def rank(check: dict) -> tuple[datetime, int]:


def main() -> int:
actions = ("produce", "verify", "produce-rehearsal", "verify-rehearsal")
actions = ("produce", "verify", "verify-main", "produce-rehearsal", "verify-rehearsal")
if len(sys.argv) != 3 or sys.argv[1] not in actions:
print("usage: v2-ci-ordinary-observe.py produce|verify|produce-rehearsal|verify-rehearsal RECEIPT_PATH", file=sys.stderr)
print("usage: v2-ci-ordinary-observe.py produce|verify|verify-main|produce-rehearsal|verify-rehearsal RECEIPT_PATH", file=sys.stderr)
return 2
try:
actual = observe(dict(os.environ), rehearsal=sys.argv[1].endswith("-rehearsal"))
actual = observe(dict(os.environ), rehearsal=sys.argv[1].endswith("-rehearsal"),
main_storage=sys.argv[1] == "verify-main")
target = pathlib.Path(sys.argv[2])
encoded = json.dumps(actual, sort_keys=True, separators=(",", ":")) + "\n"
if sys.argv[1].startswith("produce"):
Expand Down
Loading