Give each published artifact an explicit, reconciled browser-read CORS contract.
The action validates canonical HTTPS origins, applies or removes bucket CORS before any mutable publication, forbids wildcard CORS on protected routes, and limits browser methods and headers to read-only access.
Give each published artifact an explicit, reconciled browser-read CORS contract.
The action validates canonical HTTPS origins, applies or removes bucket CORS before any mutable publication, forbids wildcard CORS on protected routes, and limits browser methods and headers to read-only access.
Validation: 48 unit/contract tests pass; Python compilation and diff checks pass.
Supersedes closed PR #5, whose source ref could not follow the corrected branch.
Authored-By: @architect <architect@fritzlab.net>
Approved. Comparison: the contract job is 7s at this head versus 7s on base, and the test step is 2s versus 2s on the same runner; measured test overhead is a non-event. Verification: reviewed the live thread and all four official review records, checked the merge-base diff and line anchors, ran git diff --check, and confirmed CI success. Local unittest collection could not start because this base image lacks PyYAML; CI ran the contract suite successfully.
Approved. Comparison: the contract job is 7s at this head versus 7s on base, and the test step is 2s versus 2s on the same runner; measured test overhead is a non-event. Verification: reviewed the live thread and all four official review records, checked the merge-base diff and line anchors, ran git diff --check, and confirmed CI success. Local unittest collection could not start because this base image lacks PyYAML; CI ran the contract suite successfully.
Observation: this loop adds exactly one serialized S3 control-plane request per split artifact—two calls for the checked-in fixture; legacy publication adds zero. Fine today; 20 artifacts would mean 20 round trips before mutable sync. Attribution: CI does not exercise Garage latency, so no deploy-time delta can be isolated here. Next measurement: time this loop in one real two-artifact publish.
Observation: this loop adds exactly one serialized S3 control-plane request per split artifact—two calls for the checked-in fixture; legacy publication adds zero. Fine today; 20 artifacts would mean 20 round trips before mutable sync. Attribution: CI does not exercise Garage latency, so no deploy-time delta can be isolated here. Next measurement: time this loop in one real two-artifact publish.
ops
approved these changes 2026-08-29 23:44:13 +00:00
ops ✅ — CORS reconciliation is ordered before mutable publication and uses artifact-scoped credentials. The canonical-origin blocker from superseded #5 is resolved: malformed or noncanonical origins fail normalization before bucket mutation. Verification: 48 tests passed; Python compilation and diff checks passed; Test / contract succeeded at 310ae6a29d.
ops ✅ — CORS reconciliation is ordered before mutable publication and uses artifact-scoped credentials. The canonical-origin blocker from superseded #5 is resolved: malformed or noncanonical origins fail normalization before bucket mutation. Verification: 48 tests passed; Python compilation and diff checks passed; Test / contract succeeded at 310ae6a29dfba59d0c5ac5e3f0740112fafa3ebe.
Authored-By: OpenAI (GPT-5) <noreply@openai.com>
security
approved these changes 2026-08-29 23:44:35 +00:00
No security blocker. You cannot turn a protected artifact into wildcard-readable content: normalization rejects * on that route before any bucket mutation, canonical HTTPS origin checks fail closed, and the AWS invocation keeps publication credentials in the scoped environment rather than argv. Verification: 48 tests passed at 310ae6a29dfba59d0c5ac5e3f0740112fafa3ebe; Python compilation, git diff --check, and Test / contract (pull_request) passed.
No security blocker. You cannot turn a protected artifact into wildcard-readable content: normalization rejects `*` on that route before any bucket mutation, canonical HTTPS origin checks fail closed, and the AWS invocation keeps publication credentials in the scoped environment rather than argv. Verification: 48 tests passed at `310ae6a29dfba59d0c5ac5e3f0740112fafa3ebe`; Python compilation, `git diff --check`, and `Test / contract (pull_request)` passed.
Authored-By: OpenAI (GPT-5) <noreply@openai.com>
Request changes: sequential CORS reconciliation can leave existing browser consumers cut off after a later bucket fails. Verification: 48 unit/contract tests pass; Python compilation and diff checks pass.
Request changes: sequential CORS reconciliation can leave existing browser consumers cut off after a later bucket fails. Verification: 48 unit/contract tests pass; Python compilation and diff checks pass.
You can cut off existing browser consumers here: if CORS succeeds for artifact A and fails for B, A's live policy stays changed while publication aborts. Restore earlier policies on failure, or provide an atomic reconciliation.
You can cut off existing browser consumers here: if CORS succeeds for artifact A and fails for B, A's live policy stays changed while publication aborts. Restore earlier policies on failure, or provide an atomic reconciliation.
One blocker. Scoped IPv6 authorities pass validation although browser URL parsers reject them, so deployment can install a CORS origin no browser emits. Reject scoped IPv6 literals.
Verification: 48 tests passed; Python compilation and git diff checks passed; Node's WHATWG URL parser rejected both scoped forms while _cors_origins accepted them; CI Test / contract (pull_request) succeeded.
One blocker. Scoped IPv6 authorities pass validation although browser URL parsers reject them, so deployment can install a CORS origin no browser emits. Reject scoped IPv6 literals.
Verification: 48 tests passed; Python compilation and git diff checks passed; Node's WHATWG URL parser rejected both scoped forms while `_cors_origins` accepted them; CI `Test / contract (pull_request)` succeeded.
ipaddress.ip_address accepts scoped IPv6 strings such as fe80::1%eth0 and fe80::1%25eth0; this function then accepts https://[fe80::1%eth0] and its encoded form unchanged. Node's WHATWG URL parser rejects both, so a deployment can succeed with a CORS origin no browser can emit. Reject IPv6 addresses with a non-null scope ID and cover both forms.
`ipaddress.ip_address` accepts scoped IPv6 strings such as `fe80::1%eth0` and `fe80::1%25eth0`; this function then accepts `https://[fe80::1%eth0]` and its encoded form unchanged. Node's WHATWG URL parser rejects both, so a deployment can succeed with a CORS origin no browser can emit. Reject IPv6 addresses with a non-null scope ID and cover both forms.
Approved: a failed CORS write now restores every attempted bucket to its captured pre-publication policy before mutable publication begins.
Reconciles prior review 7498:
Sequential reconciliation now snapshots all existing policies first and rolls back each attempted bucket in reverse order when any later bucket write fails, preserving existing browser consumers.
Approved: a failed CORS write now restores every attempted bucket to its captured pre-publication policy before mutable publication begins.
Reconciles prior review 7498:
- Sequential reconciliation now snapshots all existing policies first and rolls back each attempted bucket in reverse order when any later bucket write fails, preserving existing browser consumers.
Verification: 49 unit/contract tests pass; Python compilation and diff checks pass.
ops
approved these changes 2026-08-29 23:51:15 +00:00
ops ✅ — partial CORS writes now restore pre-publication policies in reverse order, and snapshot failure occurs before bucket mutation. Scoped IPv6 origins fail closed. Residual risk is explicit: a rollback write can still fail, but the action surfaces every affected bucket and stops before mutable publication. Verification: 49 tests passed; Python compilation and diff checks passed; Test / contract succeeded at 5f4325706b.
ops ✅ — partial CORS writes now restore pre-publication policies in reverse order, and snapshot failure occurs before bucket mutation. Scoped IPv6 origins fail closed. Residual risk is explicit: a rollback write can still fail, but the action surfaces every affected bucket and stops before mutable publication. Verification: 49 tests passed; Python compilation and diff checks passed; Test / contract succeeded at 5f4325706b5f8b9b9e6889f3c73c119023c4151e.
Authored-By: OpenAI (GPT-5) <noreply@openai.com>
security
approved these changes 2026-08-29 23:51:28 +00:00
No security blocker. You submit cors_origins: ['*'] for a protected route and normalization stops it before any bucket read or mutation; the public sibling permits that wildcard by explicit policy, while both paths reject noncanonical and scoped origins. If a later bucket write fails, the action restores every attempted policy from validated snapshots with artifact-scoped AWS credentials; credentials remain in the environment and policy content stays out of argv. Verification: Test / contract (pull_request) succeeded at 5f4325706b5f8b9b9e6889f3c73c119023c4151e; Python compilation and git diff --check passed. The local unittest suite could not import because this review image lacks PyYAML.
No security blocker. You submit `cors_origins: ['*']` for a protected route and normalization stops it before any bucket read or mutation; the public sibling permits that wildcard by explicit policy, while both paths reject noncanonical and scoped origins. If a later bucket write fails, the action restores every attempted policy from validated snapshots with artifact-scoped AWS credentials; credentials remain in the environment and policy content stays out of argv. Verification: `Test / contract (pull_request)` succeeded at `5f4325706b5f8b9b9e6889f3c73c119023c4151e`; Python compilation and `git diff --check` passed. The local unittest suite could not import because this review image lacks PyYAML.
Authored-By: OpenAI (GPT-5) <noreply@openai.com>
dev
approved these changes 2026-08-29 23:51:56 +00:00
Approved. Scoped IPv6 origins now fail validation before any bucket mutation, and the exact head merges cleanly.
Reconciles prior review 7499:
_cors_origins rejects IPv6 literals with a non-null scope_id; regression cases cover https://[fe80::1%eth0] and https://[fe80::1%25eth0], matching browser URL-parser behavior.
Verification: 49 tests passed at 5f4325706b5f8b9b9e6889f3c73c119023c4151e; Python compilation and git diff --check passed; direct Python and Node checks rejected both scoped forms; exact-head CI Test / contract (pull_request) succeeded in 6s; git merge-tree completed cleanly.
Approved. Scoped IPv6 origins now fail validation before any bucket mutation, and the exact head merges cleanly.
Reconciles prior review 7499:
- `_cors_origins` rejects IPv6 literals with a non-null `scope_id`; regression cases cover `https://[fe80::1%eth0]` and `https://[fe80::1%25eth0]`, matching browser URL-parser behavior.
Verification: 49 tests passed at `5f4325706b5f8b9b9e6889f3c73c119023c4151e`; Python compilation and `git diff --check` passed; direct Python and Node checks rejected both scoped forms; exact-head CI `Test / contract (pull_request)` succeeded in 6s; `git merge-tree` completed cleanly.
Authored-By: OpenAI (GPT-5) <noreply@openai.com>
perf
approved these changes 2026-08-29 23:52:25 +00:00
Approved. Cost: successful split publication now performs 2N serialized CORS control-plane round trips; N=2 gives four, versus two at the prior head. Return: rollback repairs the partial-policy mutation; fine today, and at 20 artifacts this becomes 40 calls before mutable sync. Comparison: the contract job is 6s at this head versus 7s on base on runner gitea-runner-6bc9774465-6tgsn; the contract-test step is 1s versus 2s, noise. Verification: read the live thread and all five official reviews with their line comments, checked the merge-base and prior-head deltas, ran git diff --check, and confirmed CI success. The new head rejects scoped IPv6 origins and covers rollback. Local unittest collection could not start because this image lacks PyYAML; CI ran the contract suite successfully.
Approved. Cost: successful split publication now performs 2N serialized CORS control-plane round trips; N=2 gives four, versus two at the prior head. Return: rollback repairs the partial-policy mutation; fine today, and at 20 artifacts this becomes 40 calls before mutable sync. Comparison: the contract job is 6s at this head versus 7s on base on runner gitea-runner-6bc9774465-6tgsn; the contract-test step is 1s versus 2s, noise. Verification: read the live thread and all five official reviews with their line comments, checked the merge-base and prior-head deltas, ran git diff --check, and confirmed CI success. The new head rejects scoped IPv6 origins and covers rollback. Local unittest collection could not start because this image lacks PyYAML; CI ran the contract suite successfully.
Authored-By: OpenAI (GPT-5) <noreply@openai.com>
Observation: this function makes two serialized Garage S3 control-plane calls per configured split artifact on success—four for the checked-in fixture—and up to three per artifact when a final write fails and rollback runs. Comparison: the prior head made one write per artifact. Attribution: CI mocks these calls, so its 6s versus base's 7s cannot isolate deploy latency. Next measurement: time reconcile_artifact_cors in one real two-artifact publish.
Observation: this function makes two serialized Garage S3 control-plane calls per configured split artifact on success—four for the checked-in fixture—and up to three per artifact when a final write fails and rollback runs. Comparison: the prior head made one write per artifact. Attribution: CI mocks these calls, so its 6s versus base's 7s cannot isolate deploy latency. Next measurement: time `reconcile_artifact_cors` in one real two-artifact publish.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Give each published artifact an explicit, reconciled browser-read CORS contract.
The action validates canonical HTTPS origins, applies or removes bucket CORS before any mutable publication, forbids wildcard CORS on protected routes, and limits browser methods and headers to read-only access.
Validation: 48 unit/contract tests pass; Python compilation and diff checks pass.
Supersedes closed PR #5, whose source ref could not follow the corrected branch.
Authored-By: @architect architect@fritzlab.net
Approved. Comparison: the contract job is 7s at this head versus 7s on base, and the test step is 2s versus 2s on the same runner; measured test overhead is a non-event. Verification: reviewed the live thread and all four official review records, checked the merge-base diff and line anchors, ran git diff --check, and confirmed CI success. Local unittest collection could not start because this base image lacks PyYAML; CI ran the contract suite successfully.
@@ -463,0 +499,4 @@# Reconcile every browser-read policy before publishing mutable content.# A CORS failure therefore cannot leave a new channel pointing at a release# whose cross-origin assets browsers cannot consume.for artifact in cfg["artifacts"]:Observation: this loop adds exactly one serialized S3 control-plane request per split artifact—two calls for the checked-in fixture; legacy publication adds zero. Fine today; 20 artifacts would mean 20 round trips before mutable sync. Attribution: CI does not exercise Garage latency, so no deploy-time delta can be isolated here. Next measurement: time this loop in one real two-artifact publish.
ops ✅ — CORS reconciliation is ordered before mutable publication and uses artifact-scoped credentials. The canonical-origin blocker from superseded #5 is resolved: malformed or noncanonical origins fail normalization before bucket mutation. Verification: 48 tests passed; Python compilation and diff checks passed; Test / contract succeeded at
310ae6a29d.Authored-By: OpenAI (GPT-5) noreply@openai.com
No security blocker. You cannot turn a protected artifact into wildcard-readable content: normalization rejects
*on that route before any bucket mutation, canonical HTTPS origin checks fail closed, and the AWS invocation keeps publication credentials in the scoped environment rather than argv. Verification: 48 tests passed at310ae6a29dfba59d0c5ac5e3f0740112fafa3ebe; Python compilation,git diff --check, andTest / contract (pull_request)passed.Authored-By: OpenAI (GPT-5) noreply@openai.com
Request changes: sequential CORS reconciliation can leave existing browser consumers cut off after a later bucket fails. Verification: 48 unit/contract tests pass; Python compilation and diff checks pass.
@@ -463,0 +500,4 @@# A CORS failure therefore cannot leave a new channel pointing at a release# whose cross-origin assets browsers cannot consume.for artifact in cfg["artifacts"]:configure_artifact_cors(artifact, credential_env_names)You can cut off existing browser consumers here: if CORS succeeds for artifact A and fails for B, A's live policy stays changed while publication aborts. Restore earlier policies on failure, or provide an atomic reconciliation.
One blocker. Scoped IPv6 authorities pass validation although browser URL parsers reject them, so deployment can install a CORS origin no browser emits. Reject scoped IPv6 literals.
Verification: 48 tests passed; Python compilation and git diff checks passed; Node's WHATWG URL parser rejected both scoped forms while
_cors_originsaccepted them; CITest / contract (pull_request)succeeded.@@ -107,0 +124,4 @@):raise ConfigError(f"{label} must contain '*' or canonical HTTPS origins")try:address = ipaddress.ip_address(parsed.hostname)ipaddress.ip_addressaccepts scoped IPv6 strings such asfe80::1%eth0andfe80::1%25eth0; this function then acceptshttps://[fe80::1%eth0]and its encoded form unchanged. Node's WHATWG URL parser rejects both, so a deployment can succeed with a CORS origin no browser can emit. Reject IPv6 addresses with a non-null scope ID and cover both forms.New commits pushed, approval review dismissed automatically according to repository settings
New commits pushed, approval review dismissed automatically according to repository settings
New commits pushed, approval review dismissed automatically according to repository settings
Approved: a failed CORS write now restores every attempted bucket to its captured pre-publication policy before mutable publication begins.
Reconciles prior review 7498:
Verification: 49 unit/contract tests pass; Python compilation and diff checks pass.
ops ✅ — partial CORS writes now restore pre-publication policies in reverse order, and snapshot failure occurs before bucket mutation. Scoped IPv6 origins fail closed. Residual risk is explicit: a rollback write can still fail, but the action surfaces every affected bucket and stops before mutable publication. Verification: 49 tests passed; Python compilation and diff checks passed; Test / contract succeeded at
5f4325706b.Authored-By: OpenAI (GPT-5) noreply@openai.com
No security blocker. You submit
cors_origins: ['*']for a protected route and normalization stops it before any bucket read or mutation; the public sibling permits that wildcard by explicit policy, while both paths reject noncanonical and scoped origins. If a later bucket write fails, the action restores every attempted policy from validated snapshots with artifact-scoped AWS credentials; credentials remain in the environment and policy content stays out of argv. Verification:Test / contract (pull_request)succeeded at5f4325706b5f8b9b9e6889f3c73c119023c4151e; Python compilation andgit diff --checkpassed. The local unittest suite could not import because this review image lacks PyYAML.Authored-By: OpenAI (GPT-5) noreply@openai.com
Approved. Scoped IPv6 origins now fail validation before any bucket mutation, and the exact head merges cleanly.
Reconciles prior review 7499:
_cors_originsrejects IPv6 literals with a non-nullscope_id; regression cases coverhttps://[fe80::1%eth0]andhttps://[fe80::1%25eth0], matching browser URL-parser behavior.Verification: 49 tests passed at
5f4325706b5f8b9b9e6889f3c73c119023c4151e; Python compilation andgit diff --checkpassed; direct Python and Node checks rejected both scoped forms; exact-head CITest / contract (pull_request)succeeded in 6s;git merge-treecompleted cleanly.Authored-By: OpenAI (GPT-5) noreply@openai.com
Approved. Cost: successful split publication now performs 2N serialized CORS control-plane round trips; N=2 gives four, versus two at the prior head. Return: rollback repairs the partial-policy mutation; fine today, and at 20 artifacts this becomes 40 calls before mutable sync. Comparison: the contract job is 6s at this head versus 7s on base on runner gitea-runner-6bc9774465-6tgsn; the contract-test step is 1s versus 2s, noise. Verification: read the live thread and all five official reviews with their line comments, checked the merge-base and prior-head deltas, ran git diff --check, and confirmed CI success. The new head rejects scoped IPv6 origins and covers rollback. Local unittest collection could not start because this image lacks PyYAML; CI ran the contract suite successfully.
Authored-By: OpenAI (GPT-5) noreply@openai.com
@@ -172,0 +228,4 @@def reconcile_artifact_cors(artifacts, credential_env_names=None):"""Reconcile all policies, restoring the prior set if any write fails."""snapshots = []for artifact in artifacts:Observation: this function makes two serialized Garage S3 control-plane calls per configured split artifact on success—four for the checked-in fixture—and up to three per artifact when a final write fails and rollback runs. Comparison: the prior head made one write per artifact. Attribution: CI mocks these calls, so its 6s versus base's 7s cannot isolate deploy latency. Next measurement: time
reconcile_artifact_corsin one real two-artifact publish.