Your GitHub Actions Job Deserves a Real Identity | Riptides<br>-->
Toggle Menu
Talk to us<br>Start Free
ALL POSTS<br>Non-Human Identity Your GitHub Actions Job Deserves a Real Identity
Written By<br>Nándor Krácser
Published On<br>Jun 29, 2026
Every day, engineers paste AWS keys and API tokens into GitHub secrets. They rotate them when they remember, audit them when something breaks, and quietly hope no one with push access ever decides to print them in a workflow log. This is the state of CI security in 2026, and it’s not good enough.
GitHub’s OIDC support for AWS helped. Instead of a static key, your workflow can exchange a short-lived token for an IAM role. But it only covers AWS, and it tells you nothing about what your job actually did once it had those credentials. The deeper problem remains: CI jobs are stateless, ephemeral workloads with no persistent identity . They borrow credentials rather than earning them. And because they’re treated as second-class citizens in your security model, nobody really knows what they’re talking to.
Every entity. Not just the services.
Modern non-human identity practice is straightforward in principle: every non-human actor in your system (every pod, every VM, every service) gets a cryptographic identity. You don’t hand a service an API key and hope for the best; you issue it a short-lived certificate, bind it to what it actually is, and enforce policy from there. This is what SPIFFE was designed for, and it’s how Riptides works across your production fleet.
CI jobs are the conspicuous exception. A GitHub Actions job has write access to your source code, your artifact stores, your signing keys, and your deployment targets. It runs arbitrary code from your dependency graph on every pull request. In terms of blast radius, a compromised job is at least as dangerous as a compromised production service, often more so. Yet most teams treat it as outside the identity model entirely: give it some secrets, hope the workflow file doesn’t leak them, move on.
The gap isn’t technical. It’s that no one built the bridge.
This isn’t a GitHub Actions problem. It’s a CI problem. Jenkins jobs, GitLab pipelines, CircleCI workflows: they all run code, call services, and handle secrets, and almost none of them have a cryptographic identity. GitHub Actions happens to have the best building block available today (the OIDC token), which is why we started there. But the principle is the same everywhere: if a process touches your infrastructure, it should have an identity.
One thing the AI era hasn’t changed: CI is still there. Whether your engineers write every line by hand or vibe-code entire features in an afternoon, the pipeline that builds, tests, and ships that code runs the same way it always did. The surface area of CI isn’t shrinking. If anything, faster iteration means more runs, more secrets in play, more opportunities for a compromised dependency to slip through unnoticed.
Workload identity for CI
Riptides gives every workload (whether it’s a Kubernetes pod, a bare-metal server, or a GitHub Actions job) a SPIFFE x509 identity issued from your control plane. That identity is cryptographically bound to what the job actually is: which repository it came from, which workflow triggered it, which branch, which actor.
When a GitHub Actions job starts, it presents a GitHub OIDC token to the Riptides control plane. The control plane verifies it against GitHub’s public JWKS, checks the claims against your Verifier policy (repository owner, environment, ref, whatever you care about), and issues a short-lived x509 SVID. From that point on, the job has a real identity, not a borrowed credential.
Two things that change
Secretless credential injection. Once the job has a workload identity, Riptides enforces your policy at the network layer. You define which workloads are allowed to call which services, and what credentials to inject when they do. The job runs aws s3 cp s3://my-bucket/config.json .: no access key in the environment, no secret in the workflow, no IAM role assumption in the code. The kernel module intercepts the outbound TLS connection, verifies the workload identity, injects the right credentials on the wire, and wraps everything in mTLS. The application never knew anything happened.
This is the same credential injection Riptides uses for production workloads. Your CI jobs now work exactly like your services: identity-first, secretless, policy-enforced.
Full connection visibility. Every TCP connection a job makes (to S3, to your internal API, to your deployment target, to anything) is tracked with full workload identity context. Which workflow. Which repository. Which actor. Which ref. Whether it was allowed or denied by policy. You get the same network observability in CI that you have across the rest of your fleet.
This matters more than it sounds. A supply chain compromise doesn’t announce itself. A malicious dependency that phones home during a build looks like normal...