Skip to content

ci(codebuild): add linux x64/arm64 oidc status checks - #43

Merged
echobt merged 5 commits into
mainfrom
cursor/codebuild-ci-137c
Sep 8, 2026
Merged

ci(codebuild): add linux x64/arm64 oidc status checks#43
echobt merged 5 commits into
mainfrom
cursor/codebuild-ci-137c

Conversation

@echobt

@echobt echobt commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Add complete, public-safe AWS CodeBuild CI for Cortex CLI / Cortex Code so PR and main Linux jobs can run on dedicated x64 and arm64 CodeBuild projects — the same GitHub Actions → CodeBuild status-check pattern as CortexLM/backend (cortex-gha-x64 / cortex-gha-arm64), adapted for this Rust CLI.

Marker: CLI_CODEBUILD_CI_READY

Existing workflows are unchanged as merge gates: ci.yml, release.yml, publish-r2.yml, homebrew.yml, winget.yml, version-bump.yml, test-stability.yml. CodeBuild extends them. Staging/prod app deploy is untouched (prod HOLD). Windows CodeBuild is documented as a follow-up only (not a prod gate).

No secrets, PATs, AWS keys, or account IDs are committed. The workflow assumes a role via GitHub OIDC. The role ARN is a repository variable.

Security model (current)

  • Unprivileged pull_request: wiring only. Checks out the PR head to validate the workflow file. Does not assume OIDC and does not StartBuild.
  • Privileged pull_request_target / main push: trusted workflow from main. Buildspec from the PR base (or pushed main SHA). Head SHA is CORTEX_SOURCE_SHA.
  • OIDC trust: repo:CortexLM/cli:ref:refs/heads/main plus job_workflow_ref for .github/workflows/codebuild.yml on main. Not repo:…:pull_request.
  • PR projects: cortex-cli-gha-*-pr — logs-only IAM, NO_CACHE. Cached projects are for trusted main only.
  • P2 cache wipe: Cargo artifacts use CARGO_TARGET_DIR=/tmp/cortex-cli-target, outside the cloned source tree.

Coverage flake (this revision)

a_second_turn_is_refused_while_one_is_running_and_the_budget_is_enforced under cargo llvm-cov nextest can emit method: turn_aborted / event.reason: interrupted instead of a typed Error event. The test now accepts those abort frames.

What landed

  • .github/workflows/codebuild.yml — OIDC StartBuild; posts cortex-cli-gha-x64 / cortex-cli-gha-arm64 commit statuses. Skips StartBuild (and does not post a green status) until AWS_CODEBUILD_ROLE_ARN is set. Fork PRs stay on GitHub-hosted ci.yml.
  • deploy/aws/codebuild/ — buildspec, cargo cache paths, CloudFormation, IAM JSON.
  • scripts/readiness/test_codebuild.py — public-safety tests (run by the quality job).

One-time IAM / OIDC (admin)

Do this once in the AWS account that already hosts backend CodeBuild (reuse the GitHub OIDC provider, not the backend projects). Replace ACCOUNT_ID / REGION only in the console or CLI; never commit them.

1. GitHub OIDC provider

  • IAM → Identity providers → token.actions.githubusercontent.com
  • Audience: sts.amazonaws.com
  • If the backend account already has this provider, leave it. Create it only when missing (CreateGithubOidcProvider=true on the stack).

2. Deploy the stack

aws cloudformation deploy \
  --stack-name cortex-cli-codebuild \
  --template-file deploy/aws/codebuild/cloudformation.yaml \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    GitHubOrgRepo=CortexLM/cli \
    ProjectNameX64=cortex-cli-gha-x64 \
    ProjectNameArm64=cortex-cli-gha-arm64 \
    ProjectNameX64Pr=cortex-cli-gha-x64-pr \
    ProjectNameArm64Pr=cortex-cli-gha-arm64-pr \
    GhaRoleName=cortex-cli-codebuild-gha \
    CreateGithubOidcProvider=false

Trust subjects: repo:CortexLM/cli:ref:refs/heads/main and the job_workflow_ref for codebuild.yml on main. GHA permissions: codebuild:StartBuild, codebuild:BatchGetBuilds, logs:GetLogEvents on the four projects.

3. CodeBuild project names

GitHub status context main project (S3 cache) PR project (no cache, logs-only role)
cortex-cli-gha-x64 cortex-cli-gha-x64 (LINUX_CONTAINER, standard:7.0) cortex-cli-gha-x64-pr
cortex-cli-gha-arm64 cortex-cli-gha-arm64 (ARM_CONTAINER, amazonlinux-aarch64-standard:3.0) cortex-cli-gha-arm64-pr

Source type NO_SOURCE. Cached projects: private S3 cargo cache, 90 minute timeout. PR projects: NO_CACHE, service role cannot touch S3. No R2, WorkOS, or staging/prod secrets.

Do not reuse backend projects cortex-gha-x64 / cortex-gha-arm64 as the CLI source.

4. GitHub repository variables (not secrets)

Variable Value
AWS_CODEBUILD_ROLE_ARN GithubActionsRoleArn stack output
AWS_REGION Stack region (workflow default us-east-1)
AWS_CODEBUILD_PROJECT_X64 Optional; default cortex-cli-gha-x64
AWS_CODEBUILD_PROJECT_ARM64 Optional; default cortex-cli-gha-arm64
AWS_CODEBUILD_PROJECT_X64_PR Optional; default cortex-cli-gha-x64-pr
AWS_CODEBUILD_PROJECT_ARM64_PR Optional; default cortex-cli-gha-arm64-pr

Do not add AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY.

5. Required checks

After a successful StartBuild on a test PR, add required branch-protection checks cortex-cli-gha-x64 and cortex-cli-gha-arm64 in addition to existing ci.yml jobs. Until the role variable is set, this PR’s CodeBuild workflow only runs CodeBuild wiring.

Full runbook: deploy/aws/codebuild/README.md.

Test plan

  • python3 -B -m unittest discover -s scripts/readiness -p test_codebuild.py -v
  • Existing workflow / agents-link unit tests
  • First-revision GitHub CI (18 checks green on 48bb60d)
  • GitHub CI green on 3881f5a (18 checks, including changed-line coverage)
  • TUI / snapshot tests — no TUI surfaces changed

Attestation (required)

I attest that:

  • Security reviewed — OIDC is limited to trusted main workflow runs. Unprivileged pull_request cannot assume the role or StartBuild. Unapproved PRs cannot start cache-capable projects or supply the buildspec. No secrets in git.
  • Product-facing errors — no user-visible CLI/TUI copy changed.
  • TUI verified — no TUI surface was touched.
  • Tests addedtest_codebuild.py covers trusted buildspec, *-pr projects, OIDC subjects, and cache-path isolation. StartBuild skip does not post a green status. Exec-runtime abort assertion covers llvm-cov interrupt frames.
  • No secrets — no API keys, WorkOS secrets, R2/AWS credentials, account IDs, or .env files are included.

Risk

  • Release / R2 / version bump: not invoked.
  • Public repo: vars.* + OIDC; CloudFormation uses ${AWS::AccountId} only at deploy time.
  • Fork PRs: StartBuild skipped; GitHub-hosted ci.yml remains the gate.
  • Windows: not on CodeBuild (follow-up only; not a prod gate).
  • Prod app deploy HOLD unchanged.
Open in Web Open in Cursor 

@echobt
echobt marked this pull request as ready for review September 7, 2026 22:02
@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown

Greptile Summary

This change adds GitHub-triggered AWS CodeBuild checks for Linux x64 and arm64, along with the supporting CodeBuild, IAM, cache, setup, and readiness assets.

It should not merge until the CodeBuild submission path no longer lets unapproved same-repository pull requests provide commands that run with mutable shared-cache permissions. The restored Rust build cache should also be preserved so the new checks can reuse compilation artifacts.

Confidence Score: 3/5

The change is not safe to merge because an unapproved same-repository pull request can submit cache-capable CodeBuild commands.

Executed checks confirmed the credentialed pull-request buildspec path and independently confirmed that the install cleanup deletes the restored Rust target cache.

Files Needing Attention: .github/workflows/codebuild.yml must stop forwarding pull-request-controlled buildspec content to the cache-capable CodeBuild project. deploy/aws/codebuild/buildspec-ci.yml must retain the restored target cache.

Security Review

An unapproved same-repository pull request can modify the buildspec submitted to CodeBuild. The resulting build runs with a service role that can read, write, and delete objects in the shared S3 cache, allowing cache disclosure, modification, or deletion before approval.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for the posted P1 finding and linked it to its review comment.
  • T-Rex produced proofs for the posted P2 finding, including an additional P2 proof, and linked them to their review comments.
  • A second P1 finding proof was produced and prepared for review.
  • The configuration chain from pull_request to CodeBuild inline buildspec override was documented, with the contract-validation showing the potential unauthorized cache access.
  • The cache-removal validation step was demonstrated, showing that the build removes the cache sentinel before the build phase.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. General comment

    P1 Same-repository pull requests can submit CodeBuild commands with shared-cache permissions

    • Bug
      • .github/workflows/codebuild.yml:124 passes the contents of deploy/aws/codebuild/buildspec-ci.yml from the checked-out PR head as buildspec-override. A same-repository pull request satisfies the job's same_repo gate and can obtain an OIDC subject matching repo:CortexLM/cli:*. The assumed GitHub Actions role can call codebuild:StartBuild; the project executes the supplied buildspec using CodeBuildServiceRole, which can read, write, and delete objects in the shared cache bucket.
    • Cause
      • The workflow allows pull_request runs, checks out PR-controlled repository content, and forwards that content as an inline StartBuild buildspec override. The OIDC trust policy does not limit subjects to a protected ref or approved workflow context, while the downstream service role grants mutable shared-cache access.
    • Fix
      • Do not run this credentialed CodeBuild submission job for pull requests (for example, restrict the codebuild job to github.event_name == 'push' on protected branches), or source the buildspec from a trusted immutable revision. Also narrow OIDC trust to the required protected ref/workflow context and restrict StartBuild overrides where feasible. Do not treat a same-repository PR as trusted merely because it is not a fork.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P2 CodeBuild install phase deletes the restored Rust target cache

    • Bug
      • The S3 cache path /tmp/cortex-cli-src/target/**/* is restored for the build, but the install command sets SRC=/tmp/cortex-cli-src and immediately removes that parent directory. The subsequent clone creates a new source tree with no restored target, so Rust compilation artifacts are unavailable to the build phase.
    • Cause
      • deploy/aws/codebuild/buildspec-ci.yml:36 performs rm -rf "$SRC" after cache restoration and before the clone/build commands.
    • Fix
      • Preserve the cached target directory while refreshing sources—for example, clone into a separate source directory and set Cargo’s target directory to a cache path outside the deleted clone root, or delete only non-cache source contents while retaining target.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "ci(codebuild): add oidc linux x64/arm64 ..." | Re-trigger Greptile

Comment thread .github/workflows/codebuild.yml
Comment thread deploy/aws/codebuild/buildspec-ci.yml
cursoragent and others added 5 commits September 8, 2026 06:54
Wire GitHub Actions to dedicated CodeBuild projects via OIDC so PR/main
CI can run the heavy Linux suite on x64 and arm64 without long-lived
keys. Existing workflows stay required; Windows CodeBuild is documented
as a follow-up only.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
Load the buildspec from the PR base, send pull requests to logs-only
NO_CACHE projects, and keep Cargo artifacts in CARGO_TARGET_DIR so a
source refresh cannot wipe the restored target cache.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
StartBuild no longer runs on pull_request (untrusted workflow file).
OIDC trusts only main plus this workflow ref. pull_request_target uses
the base buildspec and logs-only *-pr projects. Push to main still uses
the cached projects.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
The wiring job was pinned to the PR base, so pull_request CI ran main
and discovered zero tests. Checkout the PR sha on pull_request; keep
the base pin only for pull_request_target and StartBuild.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
Coverage instrumentation can delay the first turn so cancel arrives as
turn_aborted / interrupted instead of a typed Error event.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/codebuild-ci-137c branch from 3881f5a to 0a377ed Compare September 8, 2026 06:54
@echobt
echobt merged commit 7f1b5da into main Sep 8, 2026
18 checks passed
@echobt
echobt deleted the cursor/codebuild-ci-137c branch September 8, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants