Home/Blog/Post

Two lines to close your CI's supply-chain door

setup-upwarden is now on the GitHub Marketplace — the google-github-actions/auth for software supply-chain security. Keyless OIDC, every dependency fetch authenticated, attributed, and policy-enforced.

Your CI installs other people’s code on every run. npm ci, pip install, mvn — each one reaches out to a public registry, pulls down whatever the range resolves to, and runs it with your secrets, your tokens, and your network access. Most of the time nobody is watching that traffic. It isn’t authenticated, it isn’t attributed to a build, and no policy stands between a freshly-published package and your runner.

That’s an unguarded door. Today we’re shipping the two lines that close it.

setup-upwarden is now live on the GitHub Marketplace (v1.0.0). Think of it as the google-github-actions/auth for software supply-chain security: drop it into a workflow, and every dependency fetch flows through the Upwarden proxy — authenticated, attributed, and policy-enforced — with no hand-rolled OIDC dance and no bundled JavaScript to trust.

The two-line fix

permissions:
  id-token: write   # let the Action mint a short-lived token from your OIDC identity
  contents: read

steps:
  - uses: upwarden-io/setup-upwarden@v1
    with:
      ecosystem: npm   # npm | pip | maven
  # From here on, npm / pip / mvn install through the Upwarden proxy.
  - run: npm ci

That permissions: block is deliberately minimal — id-token: write so the Action can prove your workflow’s identity, contents: read for the checkout, nothing more. Least privilege is the point of an auth Action, so we show it in every example.

Keyless OIDC — no stored registry credentials

Package managers aren’t OIDC-aware. npm and pip know how to send a bearer token; they don’t know how to perform an OIDC exchange. So setup-upwarden does it for them: it reads your CI’s OIDC identity and mints a short-lived, per-run token automatically, then points your package managers at the proxy using it.

There’s no registry password sitting in a secret. Nothing to rotate, nothing to leak, nothing to copy into the next repo. The token is minted for that run and expires with it.

To be precise — and this is a security tool, so precision matters — there is a token on the wire. It has to be: that’s how the proxy authenticates the request. The win isn’t “no tokens.” The win is that the token is ephemeral and derived from your CI identity, not a long-lived credential you stored and now have to guard. We’d rather tell you exactly what’s on the wire than sell you a “zero credentials” claim that isn’t true.

If your CI can’t issue an OIDC identity, there’s a second mode: Static auth, where a key is used directly. Keyless OIDC is the primary, recommended path; Static is the fallback for environments that need it. That’s the whole taxonomy — two modes, no surprises.

What you actually get

Once installs run through the proxy, three things become true of every fetch:

  • Authenticated — the request carries a verifiable, per-run identity, not anonymous registry traffic.
  • Attributed — each fetch is tied back to the repository and workflow that made it, so “what pulled this package?” has an answer.
  • Policy-enforced — your org’s rules (blocklists, publish cooldowns, quarantine of unknown versions) are applied before the package reaches the build, not flagged after it’s already installed.

And because every fetch is authenticated and attributed, it shows up in the Upwarden dashboard — per-repository and per-unit — so you can see what your CI is actually pulling instead of guessing.

Auditable by design

A lot of GitHub Actions ship a compiled dist/index.js — an opaque bundle you’re asked to trust inside your most privileged environment. setup-upwarden is a composite action: the steps it runs are written in plain YAML you can read in the repo. Nothing is minified, nothing is hidden. For a tool whose job is to make your supply chain trustworthy, that felt non-negotiable. Pin it to a commit SHA, read exactly what it does, and rely on immutable releases that can’t be silently re-pointed once published.

Try it

Two lines in a workflow. Keyless. Auditable. Every dependency fetch through the front door instead of around it.