Repository navigation
Conversation
…ades tsoa runs with noImplicitAdditionalProperties "throw-on-extras", and the webhook bodies were modelled as the full repository object. Gitea 1.27 adds fields to it (branch_count, has_code, allow_merge_update, ...), so every repository and push delivery came back 422 and new team repos were never made public, handed to their team, or branch-protected. The webhook models now declare only the fields the handlers read and accept the rest. Nothing else in the body was trusted anyway: both handlers re-fetch the repository from the Gitea API before acting. Provisioning takes the API's copy of the repository plus the sender instead of the raw event. Tests post 1.27-shaped payloads through the generated routes (both were 422 before this change), check that a payload missing a field the handlers read is still rejected, and drive the privileged paths with faked clients: repo creation and the first push to main act on the API's copy of the repository, and do nothing when it doesn't match the body. Verified end to end against Gitea 1.27.3: a new org repo went private to public with default branch main, and its first push created the main protection rule.
Bumps the local Gitea from 1.24.3 to 1.27.3, the release that fixes the Actions fork-PR approval bypasses, and applies the settings planned for git.appdevclub.com so local development sees the same behaviour: DISABLE_HTTP_GIT=false (Actions checkout needs git over HTTP), ENABLE_BASIC_AUTHENTICATION=false (no passwords over HTTP Basic) and DISABLE_QUERY_AUTH_TOKEN=true (no ?token=). With Basic passwords refused, bootstrap-gitea.sh could no longer recover a lost .gitea-token: it listed and deleted the old token with the admin password (HTTP 403). The CLI can mint tokens but not list or delete them, so recovery now mints a short-lived token and sends it as the Basic password to remove the stale people-portal-dev token (and any rotation tokens an earlier failed run left), saves the replacement, then deletes the short-lived token by name. An EXIT trap revokes the short-lived token if recovery stops partway. Tokens reach curl through --config on stdin and the Python helper through its environment, never argv. Tested: normal run; recovery with the stale token present, absent, and with an orphaned rotation token; and a recovery with the lookup's container stopped mid-run, which exits non-zero and leaves no extra token. Each success ends with exactly one valid people-portal-dev token and .gitea-token mode 600; no token appeared in any script process's arguments. Upgrade checked on an existing 1.24.3 volume: migrations 336-342 ran in one boot and scripts/verify.sh passes all 16 checks.
Covers why (fork-PR approval-gate CVEs fixed in 1.26.3 and 1.27.3, with instance-wide club runners), the target config (HTTP git on so Actions checkout works, passwords off over HTTP Basic, no ?token=), backup and rollback, release-note items, People Portal's webhook fix as a prerequisite, per-org Restricted job tokens (UI only in 1.27.3), and a verification checklist. Results quoted in the page come from the dev-stack upgrade and a hardened act_runner VM. Also moves the legacy manual Gitea compose example off 1.21.0.
3 tasks done
Collaborator
Author
|
Closing: we're staying on Gitea 1.24.3 instead of upgrading. Checkout was fixed by config alone (DISABLE_HTTP_GIT=false, ENABLE_BASIC_AUTHENTICATION=false, DISABLE_QUERY_AUTH_TOKEN=true), deployed through TechOperationsCDK. The 1.27-specific webhook model change and dev-stack bump aren't needed on 1.24.3. |
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Prepares People Portal and the dev stack for upgrading git.appdevclub.com from Gitea 1.24.3 to 1.27.3, which fixes the Actions fork-PR approval-gate bypasses (CVE-2026-58424, CVE-2026-71184). Found by running the upgrade end to end on the local dev stack with a hardened act_runner VM.
This must ship before (or with) the prod Gitea upgrade. On 1.27.3, every Gitea webhook delivery to People Portal returned 422: Gitea adds fields to the webhook
repositoryobject (branch_count,has_code,allow_merge_update, ...) and tsoa runs withnoImplicitAdditionalProperties: throw-on-extras. New team repos would never be provisioned or branch-protected.Commits
routes.tsregenerated.DISABLE_HTTP_GIT=false(Actions checkout needs it),ENABLE_BASIC_AUTHENTICATION=false,DISABLE_QUERY_AUTH_TOKEN=true. With Basic passwords refused,bootstrap-gitea.sh's token recovery broke (403); it now uses a short-lived CLI-minted token as the Basic password, sweeps stale and orphaned rotation tokens, saves the replacement before cleanup, revokes the short-lived token via an EXIT trap on failure, and keeps tokens out of argv.Test plan
prettier@3.9.10 --checkon webui/server src,nx run-many -t build -p pplserver pplui,nx run pplserver:test-unit(CI's PR checks); full server suite 135/135gitea-webhook-payloads.test.js: 1.27-shaped payloads accepted (both were 422 on the old code); missing required field still rejected; created / first-push-to-main act on the API's repository and do nothing on an id/owner mismatch (faked clients)scripts/verify.sh16/16main; first push created themainrule (2 approvals,PeoplePortalTeamOwnersallowlists, no force push); no validation errorscontents: write201?token=401corpwikinpm run buildsucceeds