CloudFormation stack for the cli-artifacts-prod AWS account (declared in
supabase/aws-org-root). It owns the public-read S3 mirror of slim native artifacts that the
CLI downloads when registry blob CDNs or GitHub release assets are blocked, for example inside
agent sandboxes that allow *.amazonaws.com.
AWS::S3::Bucketsupabase-cli-artifacts: anonymousGetObjectthrough the bucket policy, TLS required, noListBucket, ACLs blocked, versioning with 30-day noncurrent expiry so a bad same-version overwrite can be recovered.AWS::IAM::Roleslim-artifacts-publisher: trusts the account's GitHub OIDC provider forrepo:supabase/cli:ref:refs/heads/developonly (exact match) and can do nothing buts3:PutObjectands3:AbortMultipartUploadon the bucket's objects. Theupload-natives-s3job in.github/workflows/mirror-slim-image.ymlassumes it once per release.
Objects are addressed as
https://supabase-cli-artifacts.s3.us-east-1.amazonaws.com/<service>/<release-version>/<service>-<release-version>-<target>.tar.zst
https://supabase-cli-artifacts.s3.us-east-1.amazonaws.com/<service>/<release-version>/<service>-<release-version>-<target>.manifest.json
https://supabase-cli-artifacts.s3.us-east-1.amazonaws.com/<service>/<release-version>/<service>-<release-version>-<target>.SHA256SUMS
where <release-version> is the immutable <upstream>-r<N> slim-services revision, which keeps
the GitHub release asset names so the SHA256SUMS lines match the archive name without
rewriting.
This bucket, like GHCR and ECR, is a byte mirror only — it is never a checksum authority. The
CLI does not fetch SHA256SUMS (from here or from GitHub) at runtime: it pins each target's
archive and manifest sha256 directly in packages/stack/src/Artifacts.ts, written by
.github/scripts/sync-artifacts-catalog.ts after that script has already verified this bucket's
copy against the release's committed SHA256SUMS (see
ADR 0026). A stale object here fails that sync,
not a CLI download.
.github/workflows/cli-artifacts-infra.yml runs cfn-lint on pull requests that touch this
directory or the workflow, and deploys the stack on pushes to develop with the account's
github-deploy role. Every other ref can only
assume the read-only github-preview role, which cannot create change sets, so pull requests do
not preview against AWS. The deploy job is skipped until the CLI_ARTIFACTS_AWS_ACCOUNT_ID
repository variable is set.
Two roles on purpose: github-deploy is account admin and only ever applies this template;
the per-release upload runs as the bucket-scoped publisher role.
The trust is branch-scoped, not workflow-scoped: any job on develop with id-token: write
can assume the publisher role. IAM evaluates only the sub and aud claims of the GitHub
token, and narrowing sub to one workflow would require a repository-wide subject template
that the org-managed github-deploy and github-preview trusts do not accept. The controls
are the protected branch, the write-only permission set, the one-hour session cap, and bucket
versioning.
Change TRUSTED_SUBJECT in the deploy job of the workflow (for example to a release branch)
and merge; the workflow passes it as the TrustedSubject parameter on every deploy. The
subject must be the plain repo:<owner>/<repo>:ref:refs/heads/<branch> form that
supabase/cli currently emits; repositories created or renamed after 2026-07-15 emit immutable
owner@<id>/repo@<id> subjects instead.
