You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The IAM roles GitHub Actions assumes are trusted with a repo-wide wildcard subject rather than one scoped to the workflows that need them. The trust condition does not distinguish a deploy workflow on main from any other workflow in the repository, so the deploy roles for both dev and demo are reachable from a broader set of contexts than the deploy path itself.
Filed as hardening, not as a live incident: the wildcard has not been exploited, nothing is currently mis-assuming these roles, and the practical reach is limited to people who already have write access (see Scope).
The two active roles hold permissions appropriate to deployment — including the ability to update ECS services and to read individual SSM parameters. That is correct for the deploy path. The issue is only that the trust condition does not confine them to it.
lif-github-actions is separately worth attention: it trusts two repositories that were consolidated into lif-core (see the workspace CLAUDE.md on repo lineage) and currently has no attached managed policy. A role trusting retired repos should be removed rather than left dormant.
Why it is worth fixing now
Today the exposure is bounded mostly by accident rather than by design — no current workflow abuses it, and the contexts that could are limited to actors who already hold write access. Both of those are properties of how the repo happens to be used, not guarantees the trust policy provides.
It is also load-bearing for the design of #1288. That issue proposes a task-definition drift check, and the obvious shortcut is to hand PR CI the existing deploy role — which the wildcard permits with no IAM change. That shortcut should not be taken, and this issue is why.
Proposed remediation
Replace the wildcard subject with scoped conditions. Trust the specific contexts that deploy — for example the main ref and/or a named GitHub Environment — rather than repo:LIF-Initiative/lif-core:*. GitHub's OIDC subject supports ref, environment, and job_workflow_ref claims for exactly this.
Prefer a GitHub Environment as the boundary. Binding deploy roles to an Environment also gets required reviewers and branch restrictions for free, which is a stronger control than a ref match alone.
Not remotely exploitable by an anonymous party. Workflows triggered by pull_requestfrom a fork are not issued an OIDC token at all, which excludes the untrusted case.
The realistic reach is someone who can already push a branch to this repository — i.e. already trusted. This is privilege-shaping within a trusted group, not an external hole.
No evidence of misuse; this is a configuration review finding.
Note on venue
lif-core is a public repository and private vulnerability reporting is currently disabled, so this write-up is deliberately limited to the misconfiguration class and its remediation. It contains no exploitation steps. If the team wants to track specifics — exact permission inventories, or which contexts can reach what — enable private vulnerability reporting (Settings → Security) or move that detail to a private tracker, and link it from here rather than pasting it in.
Summary
The IAM roles GitHub Actions assumes are trusted with a repo-wide wildcard subject rather than one scoped to the workflows that need them. The trust condition does not distinguish a deploy workflow on
mainfrom any other workflow in the repository, so the deploy roles for both dev and demo are reachable from a broader set of contexts than the deploy path itself.Filed as hardening, not as a live incident: the wildcard has not been exploited, nothing is currently mis-assuming these roles, and the practical reach is limited to people who already have write access (see Scope).
Current state
Three roles trust this GitHub org via OIDC:
lif-github-actions-devrepo:LIF-Initiative/lif-core:*lif-github-actions-demorepo:LIF-Initiative/lif-core:*lif-github-actionsrepo:LIF-Initiative/lif-metadata-repository:*,repo:LIF-Initiative/lif-main:*The two active roles hold permissions appropriate to deployment — including the ability to update ECS services and to read individual SSM parameters. That is correct for the deploy path. The issue is only that the trust condition does not confine them to it.
lif-github-actionsis separately worth attention: it trusts two repositories that were consolidated intolif-core(see the workspaceCLAUDE.mdon repo lineage) and currently has no attached managed policy. A role trusting retired repos should be removed rather than left dormant.Why it is worth fixing now
Today the exposure is bounded mostly by accident rather than by design — no current workflow abuses it, and the contexts that could are limited to actors who already hold write access. Both of those are properties of how the repo happens to be used, not guarantees the trust policy provides.
It is also load-bearing for the design of #1288. That issue proposes a task-definition drift check, and the obvious shortcut is to hand PR CI the existing deploy role — which the wildcard permits with no IAM change. That shortcut should not be taken, and this issue is why.
Proposed remediation
mainref and/or a named GitHub Environment — rather thanrepo:LIF-Initiative/lif-core:*. GitHub's OIDC subject supportsref,environment, andjob_workflow_refclaims for exactly this.lif-github-actions, or re-point it if either predecessor repo is genuinely still deploying.paths:filters miss packaged bricks — a brick-only change merges green and never rebuilds the image (9 of 11 services affected) #1171 and CF/CI: add a PR-time guard for stale per-project uv.lock files (crash-looped a service in #1125, nearly again in #1174) #1209 were held to: prove the control by observing it deny, not only by observing the happy path pass.Scope / severity
pull_requestfrom a fork are not issued an OIDC token at all, which excludes the untrusted case.Note on venue
lif-coreis a public repository and private vulnerability reporting is currently disabled, so this write-up is deliberately limited to the misconfiguration class and its remediation. It contains no exploitation steps. If the team wants to track specifics — exact permission inventories, or which contexts can reach what — enable private vulnerability reporting (Settings → Security) or move that detail to a private tracker, and link it from here rather than pasting it in.Related
CLAUDE.md— repo lineage explaining whylif-metadata-repository/lif-mainare retired