-
feat(webapp): apply default repository policy on ECR repo creation (#3467)
发布于
2026-04-29 14:17:23 +00:00 | 931 次提交 在此版本后已推送到 mainSummary
Self-hosters that operate the webapp's ECR account separately from the
account running the EKS workers (e.g., a shared platform account that
hosts the registry plus per-team accounts that host clusters) currently
hit a 403 Forbidden the first time any project is deployed:Failed to pull image "<acct-A>.dkr.ecr.<region>.amazonaws.com/<namespace>/proj_…:…": unexpected status from HEAD request to .../v2/.../manifests/sha256:…: 403 ForbiddenensureEcrRepositoryExistsin
apps/webapp/app/v3/getDeploymentImageRef.server.tscalls
CreateRepositoryandPutLifecyclePolicy, but never
SetRepositoryPolicy— so the new repo inherits the AWS default (only
the registry-owner account can read/pull). Workers in the cluster
account get 403 every single deploy. The only workarounds today are
running a one-off post-create script or pre-creating every repo by hand.Proposed change
Add an optional env var:
DEPLOY_REGISTRY_ECR_DEFAULT_REPOSITORY_POLICY (V4 mirror: V4_DEPLOY_REGISTRY_ECR_DEFAULT_REPOSITORY_POLICY)Raw IAM policy JSON. When set, the webapp calls
SetRepositoryPolicy
immediately afterCreateRepositoryso every new repo carries that
policy from creation. Operators control the principal/actions; we don't
bake in any opinions about cross-account boundaries.Example value (for the typical self-host case — grant pull to the
cluster account):{ "Version": "2012-10-17", "Statement": [{ "Sid": "AllowClusterAccountPull", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::<cluster-account-id>:root"}, "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability" ] }] }Why env var (not a chart-level field)
- Mirrors the shape of the sibling vars (
DEPLOY_REGISTRY_ECR_TAGS,
DEPLOY_REGISTRY_ECR_ASSUME_ROLE_ARN, etc.) which are already
operator-supplied viawebapp.extraEnvVarsin self-host setups. - Cloud is unaffected — the env var is optional, unset by default;
existing behavior unchanged. - Existing repos are unaffected — only newly-created repos get the
policy. RepositoryCreationTemplatefrom the AWS provider isn't an
alternative here: it only applies to repos created via
pull-through-cache or replication, not toecr:CreateRepositoryAPI
calls.
Implementation
apps/webapp/app/env.server.ts— declare
DEPLOY_REGISTRY_ECR_DEFAULT_REPOSITORY_POLICYand the V4 fallback.apps/webapp/app/v3/registryConfig.server.ts— propagate
ecrDefaultRepositoryPolicytoRegistryConfig.apps/webapp/app/v3/getDeploymentImageRef.server.ts—
createEcrRepositoryaccepts the policy; if set, calls
SetRepositoryPolicyafterPutLifecyclePolicy.docs/self-hosting/env/webapp.mdx— documentation row added under
Deploy & Registry.
Verification
Verified end-to-end against a self-hosted Trigger.dev on EKS where the
ECR account is separate from the cluster account:- Without the env var (current
main): the new project's first run
pod stays inImagePullBackOffwith403 Forbidden. - With the env var set to a JSON granting
ecr:BatchGetImage/GetDownloadUrlForLayer/BatchCheckLayerAvailability
to the cluster account: a freshtrigger.dev deploy --env prodfollowed
by ahello-worldrun completes in ~5s end-to-end on the first try.
Manually also confirmed that existing repos are untouched (the call only
fires insidecreateEcrRepository, which only runs when
DescribeRepositoriesreturnedRepositoryNotFoundException).Out of scope
- Chart values surface for this — operators already pass the existing
ECR vars viawebapp.extraEnvVars, so this follows the same pattern.
Happy to add a first-class chart field in a follow-up if that's the
preferred direction. - IAM-policy validation in the webapp — we forward the JSON verbatim to
AWS and surface AWS's error messages on misuse, matching how
DEPLOY_REGISTRY_ECR_TAGSis handled today.
This is a draft pending CI / CodeRabbit pass — happy to iterate on
direction (e.g., split into per-action env vars, or extend the chart
values schema) if any of the above choices feels off.
Co-authored-by: nicktrn 55853254+nicktrn@users.noreply.github.com
下载附件
- Mirrors the shape of the sibling vars (