Aqua Security’s Image Assurance Policies are how you enforce security standards on your container images throughout their lifecycle. Think of them as the ultimate gatekeepers, ensuring only compliant images get deployed.
Here’s a simple policy in action. Let’s say we want to block any image that has high or critical vulnerabilities, and we want to ensure it’s signed by a trusted source.
apiVersion: security.aqua.io/v1
kind: ImageAssurancePolicy
metadata:
name: my-app-policy
namespace: default
spec:
clusterWide: false
description: "Policy for my-app to enforce vulnerability and signing checks."
project: "my-project"
selectors:
- image: "my-registry/my-app:*"
steps:
- name: "Vulnerability Scan"
description: "Scan for high and critical vulnerabilities."
properties:
vulnerability:
maxSeverity: "critical"
failOnCRITICAL: true
failOnHIGH: true
failOnLOW: false
failOnNEGLIGIBLE: false
- name: "Image Signing Check"
description: "Ensure image is signed by a trusted key."
properties:
imageSignature:
required: true
trustedPublicKeys:
- "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA41o...\n-----END PUBLIC KEY-----"
This policy, my-app-policy, targets images from my-registry/my-app with any tag. It has two steps: first, a vulnerability scan that will fail if any critical or high vulnerabilities are found. Second, it requires the image to be signed, and specifically checks that signature against a predefined trusted public key. If either of these checks fail, Aqua will prevent the image from being deployed to a Kubernetes cluster where this policy is enforced.
The core problem Image Assurance Policies solve is the "it works on my machine" syndrome, but for security. Developers might build images with good intentions, but without automated checks, vulnerabilities creep in, or untrusted images get deployed. Policies bring consistency and enforcement.
Internally, Aqua Security’s scanner analyzes image layers, comparing installed packages and detected artifacts against vulnerability databases. For signing, it leverages tools like Notary or Sigstore, verifying the digital signature against a known, trusted public key. When a deployment attempt is made, Aqua intercepts the admission request (via its Kubernetes admission controller) and runs the relevant policy checks. If any step fails, the admission request is denied, and the deployment is blocked.
You control these policies via selectors, which specify which images the policy applies to. These selectors can be based on image name, registry, tags, or even labels. The steps define the actual security checks. You can have steps for vulnerabilities, image configuration (like exposed ports or USER directives), secrets detection, malware scanning, and more. Each step has configurable properties to fine-tune its behavior. For instance, you can adjust maxSeverity or decide whether to failOnLOW vulnerabilities.
A common point of confusion is how signing actually works in practice with these policies. Aqua doesn’t just look for a signature; it looks for a signature that can be cryptographically verified using the keys you provide in the trustedPublicKeys field. This means you need a robust image signing pipeline upstream that uses the corresponding private key to sign your images before they reach your registry. Aqua then acts as the verifier at deployment time, ensuring the signature is valid and was created by the holder of the private key associated with your trusted public key.
The next concept you’ll likely grapple with is how to integrate these policies with your CI/CD pipelines for automated signing and scanning before images even reach your registry.