Skip to content

fix(ci): deploy-all.yml declares no permissions, so called deploy workflows cannot obtain an OIDC token #1665

Description

@cristim

Found during the independent review of PR #1657. Pre-existing, and identical before and after that PR — filed rather than folded in. One line to fix.

What

.github/workflows/deploy-all.yml declares no permissions: block — not at workflow level, and not on any of its four caller jobs (deploy-aws-lambda :118, deploy-aws-fargate :132, deploy-gcp :144, deploy-azure :156), each of which invokes a reusable workflow via uses:.

  deploy-aws-lambda:
    name: Deploy AWS Lambda
    needs: determine-deployment
    if: needs.determine-deployment.outputs.deploy-aws-lambda == 'true'
    uses: ./.github/workflows/deploy-aws-lambda.yml     # <- no permissions:
    with:
      environment: ${{ needs.determine-deployment.outputs.environment }}

Why it matters

A called workflow's permissions: block cannot escalate beyond the caller's — the caller's GITHUB_TOKEN permissions are the ceiling, and the effective set is the intersection. id-token: write is never in the default GITHUB_TOKEN set; it must be requested explicitly.

So when deploy-aws-lambda.yml (or any of the other three) is invoked through deploy-all.yml, it very likely cannot obtain an OIDC token at all, and configure-aws-credentials / azure/login / google-github-actions/auth fails. The multi-cloud "deploy everything" path is the one most likely to be used for a real release, and it is the one that cannot authenticate.

Dispatching deploy-aws-lambda.yml directly still works — that path requests its own permissions and is not capped by a caller.

Not caused by #1657

Worth stating explicitly so nobody bisects to it: deploy-aws-lambda.yml previously declared permissions: id-token: write at workflow level and #1657 moved it to job level. Both forms are equally subject to the caller-intersection cap, so the deploy-all.yml path was already broken before that change and is no more or less broken after it. The defect is entirely in the caller.

Fix

Add the permission to each caller job in deploy-all.yml:

  deploy-aws-lambda:
    ...
    permissions:
      id-token: write
      contents: read
    uses: ./.github/workflows/deploy-aws-lambda.yml

Repeat for the other three. Prefer per-job over a workflow-level block, so determine-deployment and notify — neither of which authenticates — do not receive id-token: write; that is the same least-privilege split #1657 applied inside deploy-aws-lambda.yml, and it avoids recreating the ungated-credentialed shape tracked in LeanerCloud/cloud-commitments-platform#140.

Verification note

I have not confirmed this empirically — doing so means dispatching a real multi-cloud deploy. It is inferred from documented GitHub behaviour (reusable-workflow permission intersection, and id-token being absent from the default token). Worth a cheap confirmation on a dev-only dispatch before or alongside the fix.

Related: #1657 / #1649, LeanerCloud/cloud-commitments-platform#140 (ungated credentialed jobs in the sibling deploy workflows), #1646.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions