It’s no secret that the software development life cycle is becoming more complex.
With a plethora of libraries, frameworks, and now AI coding agents and assistants, we can build far more ambitious software in a fraction of the time. This is fantastic! But with it come greater opportunities for accidental or malicious security bugs and vulnerabilities to sneak in undetected, with potentially devastating consequences for your users and their trust in your company.
One particularly memorable example of this is the SUNBURST attack, which in 2020 saw tens of thousands of SolarWinds customers including government and healthcare agencies impacted by a highly sophisticated backdoor, injected into the popular Orion software package at build-time.
Thankfully there is a growing ecosystem of tools around the problem of securing the software supply chain; from your laptop, through CI, all the way to the production environment.
These tools are built on a foundation of trust established with cryptographic signatures. In order to trust that the container image running in production is the same as when it left CI, or that the results of a vulnerability scan haven't been tampered with, we must sign them and securely distribute the key material needed to verify these signatures.
What is Sigstore?
Sigstore is a framework and suite of tools for signing software artifacts such as binaries and container images, as well as "attestations" of the software's origin, dependencies, build process, test results, and pretty much anything you can represent using the in-toto format.
There are a number of other projects in this space (e.g. Notary), but Sigstore is emerging as a leader and is the core technology behind GitHub's artifact attestation and npm's package provenance features.
It offers a novel solution to one of the hardest problems in artifact signing: key distribution. With traditional signing solutions, you typically need to create and distribute long-lived signing keys or certificates. Rotating and revoking these credentials is difficult, so teams frequently put it off until it's too late.
Sigstore takes a very different approach with its "keyless" mode, which leverages single-use certificates bound to an OIDC identity (e.g. a Google account or GitHub Actions token). In the same way Teleport removes static credentials from human and machine infrastructure access, Sigstore removes them from code signing and verification.
Sigstore also records its signatures in a public transparency log for auditability, which makes it possible to monitor for unauthorized use of your identity or a compromise of the Sigstore infrastructure itself.
Getting started with Sigstore is easy. To try it out locally, use cosign
to sign a container image. It will open a browser window for you to log in with your Google, Microsoft, or GitHub account, and push the signature up to your container registry.
$ cosign sign $IMAGE
Consumers can then check you really have signed the image with cosign verify
:
$ cosign verify $IMAGE \
--certificate-identity daniel.upton@goteleport.com \
--certificate-oidc-issuer https://accounts.google.com
Note that we didn't need to figure out how to share our public key.
What does this have to do with Machine & Workload Identity?
Teleport Machine & Workload Identity replaces static credentials with SPIFFE-compliant cryptographic identities and short-lived certificates, enabling secure, policy-based authentication and mutual TLS between workloads and services.
Using tbot
's SPIFFE Workload API, applications can obtain cryptographically verifiable identity documents called "SVIDs" (X.509 certificates or JWTs) which can be used to authenticate with other systems, or be exchanged for cloud credentials (for example, by using AWS Roles Anywhere or GCP Workload Identity Federation).
When an application requests a SVID, tbot
performs a process called workload attestation to discover information about it such as the container image and Kubernetes pod labels. Teleport can use this information to decide whether or not to issue the SVID.
Now, tbot
can also discover container image signatures as part of the attestation process, and they can be incorporated into the credential issuance decision.
In other words: by using the Sigstore integration, you can bake supply chain security into your workload identity. You could, for example, lock down access to your microservices, databases, or cloud accounts to only software built and signed in your trusted CI environment or that has passed a scan for CVEs and other common vulnerabilities. This massively reduces the surface for and potential impact of supply chain attacks.
Getting started
There are broadly three steps required to enable Teleport's Sigstore integration:
- Create a
SigstorePolicy
object that describes how and by whom artifacts must be signed and attested. - Call the
sigstore.policy_satisfied
function from yourWorkloadIdentity
rules to ensure the policy's requirements are met before issuing SVIDs. - Enable
tbot
's Sigstore attestor, which discovers image signatures for Kubernetes, Docker, and Podman workloads from an OCI registry.
Demo
Let's take a peek at how this looks in practice. To follow along, see the full example code here.
In this demo, we're going to use GitHub's attest-build-provenance
action to sign and publish a SLSA provenance attestation for our application, and we'll configure Teleport to only issue SVIDs to workloads running images with this attestation.
There are lots of other ways to use and configure Sigstore. For example, larger organizations may choose to run their own private certificate authority and transparency log. Similarly, if you're using a private GitHub repository, the attest-build-provenance
action will use GitHub's internal certificate and timestamp authorities, so your SigstorePolicy
object may differ.
Our application will use the AWS Go SDK to interact with an S3 bucket. Rather than a long-lived set of credentials, we'll use aws-spiffe-workload-helper
to fetch an X509-SVID from tbot
and exchange it for short-lived credentials using IAM Roles Anywhere.
First, let's take a look at the relevant part of our GitHub Actions workflow. We're building a Docker container image and pushing it to GitHub's container registry. The following step will generate and sign a provenance attestation and push it to the same registry:
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${ (env.REGISTRY )}/${( env.IMAGE_NAME )}
subject-digest: ${( steps.push.outputs.digest )}
push-to-registry: true
Next, we'll create a SigstorePolicy
which trusts signatures generated by GitHub Actions from the main
branch of any of our organization's repositories, and requires the SLSA provenance attestation from the previous step:
kind: sigstore_policy
version: v1
metadata:
name: github-provenance
spec:
keyless:
identities:
- issuer: https://token.actions.githubusercontent.com
subject_regex: ^https://github.com/asteroid-earth/(.*)/\.github/workflows/(.*)@refs/heads/main$
requirements:
attestations:
- predicate_type: https://slsa.dev/provenance/v1
Now, we'll require this policy to be satisfied in our WorkloadIdentity
rule.
Note: The expression uses the Teleport predicate language so you can combine it with other conditions using &&
and ||
operators.
kind: workload_identity
version: v1
metadata:
name: k8s-workload
spec:
spiffe:
id: /k8s/{( workload.kubernetes.pod_name )}
rules:
allow:
- expression: sigstore.policy_satisfied("github-provenance")
Finally, we'll enable the Kubernetes and Sigstore attestors in tbot
's workload-identity-api
service configuration:
services:
- type: workload-identity-api
listen: unix:/
Let's imagine we want to ship some changes to our application. Our pull request has been approved, so we merge it, and GitHub Actions builds a new image and tags it with the commit SHA - so far so good.
But uh-oh! Our registry has been compromised and an attacker swaps our image with their own, which exfiltrates our customer data out of S3. This is a serious issue... or at least it would be if it weren't for our SigstorePolicy
which prevents Teleport from issuing a SVID to the compromised container, and thereby stops it accessing S3 at all.
$ curl http://localhost:65050/
ERROR: operation error S3: ListObjects, get identity: get credentials: failed to refresh cached credentials,
process provider error: error in credential_process: exit status 1
We can see this reflected in the audit log as a "SPIFFE SVID Issued Failure" event:
{
"attributes": {
"workload": {
"kubernetes": {
"attested": true,
"container": {
"image": "ghcr.io/asteroid-earth/teleport-sigstore-demo:compromised",
"image_digest": "sha256:949c4203b29633e61c1a34b633fa3b88cb0c0696e8256ebbf5f3bb40448fc5b7"
}
},
"sigstore": {
"evaluated_policies": {
"github-provenance": {
"reason": "No attestation with predicate 'https://slsa.dev/provenance/v1' found",
"satisfied": false
}
},
"payload_count": 0
}
}
}
}
How it works
Let’s take a look under the hood at how signatures are generated and distributed, and then verified by Teleport when deciding whether to issue a SVID.

Cosign (or another Sigstore-compatible tool) generates a private key and certificate signing request. It sends the CSR and an OIDC identity token to Fulcio, Sigstore’s certificate authority.
Fulcio checks the identity token and issues a short-lived X.509 certificate, attesting the OIDC identity. Cosign uses the private key to sign the artifact and then throws private key away so it can’t be used again.
Cosign records the signature and other metadata in the Rekor transparency log.
It then uploads the signature, certificate, and proof of transparency log inclusion to an OCI registry.
At runtime, a workload process calls
tbot
’s SPIFFE Workload API to obtain a SVID.tbot
uses the local Kubernetes, Docker, or Podman API to discover which container image digest the workload is running.It then queries the OCI registry to find the relevant signatures and attestations.
tbot
includes these signatures in the information sent to the Teleport auth server when requesting a SVID.The auth server evaluates the
WorkloadIdentity
rule expression which calls thesigstore.policy_satisfied
function.The
SigstorePolicy
is used to determine the “trusted roots” that will be used to verify the signature. This includes Fulcio and Rekor’s certificate chains as well as any custom RFC 3161 timestamp authorities.If the required artifact signature and attestations are present and correct, the auth server issues the SVID and
tbot
returns it to the workload process.
Next Steps: Strengthen Your Supply Chain with Workload Identity
Modern software supply chains are only as secure as the workloads that build and deploy them. Eliminating static secrets and adopting cryptographic identity, especially with open standards like SPIFFE, is foundational to reducing risk and increasing automation across your CI/CD pipelines and service meshes.
Teleport Machine & Workload Identity makes it easy to provision and enforce identity for every non-human actor in your infrastructure. With native SPIFFE support, short-lived certificates, and granular access policies, you can secure service-to-service communication without managing secrets.