Verify Image Signature with Sigstore Cosign
This page describes the support for validating images using Sigstore
Cosign with Styra. DAS users can configure a cosign
Policy Library
snippet with parameters similar to the ones supported by the cosign
CLI tool.
The OPA Webhook then performs cosign validation on AdmissionReview objects that
contain any image references.
The Policy Snippet leverages an API hosted on the Styra Local Plane
sidecar to perform the cosign
validation.
This experimental policy snippet is under active development and is expected to change in both behavior and interface. Changes will likely require manual migration.
Details
Prevents deployment of containers without a valid signature that is verified using Cosign according to user configuration. The configuration (see sample and schema below) may define, for each registry host and each image path within a registry host, the Cosign verification parameters used to verify the signature of the image. In addition, the configuration may define for each registry host the image paths that are allowed without verification. All other images are prohibited from running.
A glob pattern may be used as an image path configuration to match a range of image paths.
Parameters
-
verification_config
- Type: Rego reference to an object (example:
data.cosign_config
). - A sample object and JSON schema are given below.
- This value must be a Rego reference (such as
data.cosign_config
referring to a datasource orcosign_config
referring to a variable) rather than an inline Rego object.- ✅ Correct usage example:
cosign_config := {
"allow_with_verification": { ... },
"allow_without_verification": { ... }
}
parameters := {
"verification_config": cosign_config
} - ❌ Incorrect usage example:
parameters := {
"verification_config": {
"allow_with_verification": { ... },
"allow_without_verification": { ... }
}
}
- ✅ Correct usage example:
- Type: Rego reference to an object (example:
-
Required Parameters: verification_config
Resource Types
- Verifications: Pod, Deployment, ReplicaSet, Job, DaemonSet
Cosign verification_config
object sample
{
"allow_with_verification": {
"docker.io": {
"ubuntu/nginx": {
"certificate-identity": "maintainer@example.com",
"certificate-oidc-issuer": "https://github.com/login/oauth"
},
"openpolicyagent/opa": {
"certificate-identity-regexp": ".*@example.com",
"certificate-oidc-issuer-regexp": "https://github.com.*"
}
},
"ecr.io": {
"xyz/busybox": {
"key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFlyx6GRM389JvhDuFEoWC5Mkyeaa\nGsdZQ5Qcw1rmV8I9s+tfh8MMhHtzsGnDg0QMOG2wRPblwVWlT5RfCyDMfg==\n-----END PUBLIC KEY-----",
"insecure-ignore-tlog": true,
"insecure-ignore-sct": true
}
},
"gcr.io": {
"xyz/*": {
"key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFlyx6GRM389JvhDuFEoWC5Mkyeaa\nGsdZQ5Qcw1rmV8I9s+tfh8MMhHtzsGnDg0QMOG2wRPblwVWlT5RfCyDMfg==\n-----END PUBLIC KEY-----"
}
}
},
"allow_without_verification": {
"docker.io": [
"ubuntu",
"ubuntu/*"
],
"ecr.io": [
"xyz/*"
],
"gcr.io": [
"my-proj-*/base-*-image"
]
}
}
The usage of the Cosign verification parameters generally correspond to their CLI behavior.
An exception is the key
parameter; this parameter currently requires a string
containing a public key given in a PEM format (as shown in the sample
object above).
If an image path matches both the configuration in allow_with_verification
and the configuration in allow_without_verification
, the verification
behavior is defined by the configuration in allow_with_verification
. For
instance, in the sample verification_config
above, the image
docker.io/ubuntu/nginx
would match both the ubuntu/nginx
path in
allow_with_verification
and the ubuntu/*
path pattern in
allow_without_verification
. In this case, the image will be verified
according to the verification parameters in the allow_with_verification
; the
configuration in allow_without_verification
has no effect for this image.
It is highly recommended that all image path patterns under a single image
registry host name be mutually exclusive. In case an image path matches more
than one verification configuration, only one verification will be attempted,
with no guarantee on which verification configuration is used applied. For
example, in the sample configuration below, there is no guarantee whether
docker.io/ubuntu/nginx
would be verified as signed by "alice@example.com" or
by "bob@example.com".
{
"allow_with_verification": {
"docker.io": {
"ubuntu/nginx": {
"certificate-identity": "alice@example.com",
"certificate-oidc-issuer": "https://github.com/login/oauth"
},
"ubuntu/*": {
"certificate-identity": "bob@example.com",
"certificate-oidc-issuer": "https://github.com/login/oauth"
}
}
}
}
Known Limitations of Cosign Validation Snippet v0_0_1
- The snippet does not produce accurate results in Styra DAS Editor's
Preview and Validate mode as it relies on communication with an
in-cluster Styra Local Plane (SLP) container. It can produce correct output in
Decision Replay mode if the underlying HTTP call to SLP isn't altered.
Nevertheless, it is safer to rely on the decisions emitted from in-cluster
OPAs to estimate the impact of this snippet. For this reason, it is
recommended to verify this snippet as a
Monitor
rule before promoting it toEnforce
. - The snippet does not support Repository Authentication. The SLP container is expected to be bootstrapped in an in-cluster environment where it can reach the repository where the Cosign artifact signatures are stored.
- There is no support for priority between multiple image pattern matches.
- The snippet supports key-based or keyless verifications only. It does not support verification with a Certificate or Certificate Chain.
- The cosign verification API embedded in SLP may timeout if the workload
contains a large number of images. During testing, the likelihood of this
scenario increased if more than 8 containers were referenced in the
workload. In this scenario, the snippet will raise a violation with "SLP
not available" and OPA will record a
DENIED
decision. - Additionally, a timeout may also occur between the Kubernetes API and the OPA Validating Webhook. Based on the configuration of the OPA Validating Webhook, it may either Fail Open or Fail Close the decision. Depending on the sequencing, this timeout may not be recorded in OPA, may not be recorded by OPA, however, it should be present in the Audit Logging for the Kubernetes cluster.
Cosign verification_config
JSON schema
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "Verification config",
"type": "object",
"properties": {
"allow_with_verification": {
"title": "Config to allow images with verification",
"description": "Each property key is a string that specifies the applicable image registry host (e.g. docker.io). Each property value is an object that specifies the image paths within this registry host to allow with the configured verification.",
"type": "object",
"additionalProperties": {
"title": "Config for each image registry host",
"type": "object",
"additionalProperties": {
"title": "Config for each image path within a registry",
"description": "Each property key is a string (glob pattern supported) that specifies the applicable image path. Each property value is an object that specifies the Cosign parameters to use in verifying an image satisfying this path (pattern).",
"type": "object",
"minProperties": 1,
"properties": {
"key": {
"type": "string"
},
"certificate-identity": {
"type": "string"
},
"certificate-oidc-issuer": {
"type": "string",
"format": "uri"
},
"certificate-identity-regexp": {
"type": "string"
},
"certificate-oidc-issuer-regexp": {
"type": "string"
},
"insecure-ignore-tlog": {
"type": "boolean"
},
"insecure-ignore-sct": {
"type": "boolean"
}
},
"additionalProperties": false
}
}
},
"allow_without_verification": {
"title": "Config to allow images without verification",
"type": "object",
"additionalProperties": {
"title": "Config for each image registry host",
"description": "Each property key is a string that specifies the applicable image registry host (e.g. docker.io). Each property value is an array that specifies within its registry host the collection of applicable image paths to allow without verification.",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
}
},
"minProperties": 1,
"additionalProperties": false
}