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
- Marketplace listing: github.com/marketplace/actions/setup-upwarden
- Learn more: upwarden.io
Two lines in a workflow. Keyless. Auditable. Every dependency fetch through the front door instead of around it.