Implementing Custom Security Policies

Implementing Custom Security Policies

Both Trivy and Snyk support custom policies that enforce organization-specific security requirements:

# custom-policies/container-security.rego
package container.security

import future.keywords.if
import future.keywords.in

# Deny containers running as root
deny[msg] {
    input.kind == "Deployment"
    container := input.spec.template.spec.containers[_]
    has_security_context := container.securityContext
    not container.securityContext.runAsNonRoot == true
    msg := sprintf("Container '%s' should not run as root. Set securityContext.runAsNonRoot to true", [container.name])
}

# Require resource limits
deny[msg] {
    input.kind == "Deployment"
    container := input.spec.template.spec.containers[_]
    not container.resources.limits.memory
    msg := sprintf("Container '%s' must specify memory limits", [container.name])
}

deny[msg] {
    input.kind == "Deployment"
    container := input.spec.template.spec.containers[_]
    not container.resources.limits.cpu
    msg := sprintf("Container '%s' must specify CPU limits", [container.name])
}

# Enforce image signing
deny[msg] {
    input.kind == "Deployment"
    container := input.spec.template.spec.containers[_]
    image := container.image
    not image_is_signed(image)
    msg := sprintf("Image '%s' must be signed with cosign", [image])
}

image_is_signed(image) {
    # Check if image has required annotations
    input.metadata.annotations["cosign.sigstore.dev/signature"]
}

# Require specific labels
required_labels := {
    "app.kubernetes.io/name",
    "app.kubernetes.io/version",
    "app.kubernetes.io/component",
    "app.kubernetes.io/managed-by",
    "security.company.com/scan-status"
}

deny[msg] {
    input.kind == "Deployment"
    missing := required_labels - {label | input.metadata.labels[label]}
    count(missing) > 0
    msg := sprintf("Deployment missing required labels: %v", [missing])
}

# Vulnerability threshold policies
deny[msg] {
    vuln := input.Results[_].Vulnerabilities[_]
    vuln.Severity == "CRITICAL"
    msg := sprintf("Critical vulnerability found: %s in %s", [vuln.VulnerabilityID, vuln.PkgName])
}

warn[msg] {
    vuln := input.Results[_].Vulnerabilities[_]
    vuln.Severity == "HIGH"
    count([v | v := input.Results[_].Vulnerabilities[_]; v.Severity == "HIGH"]) > 5
    msg := "More than 5 HIGH severity vulnerabilities found"
}

# Custom compliance rules
pci_compliance[msg] {
    vuln := input.Results[_].Vulnerabilities[_]
    vuln.Severity in ["CRITICAL", "HIGH"]
    age := time.now_ns() - time.parse_rfc3339_ns(vuln.PublishedDate)
    age_days := age / (24 * 60 * 60 * 1000000000)
    age_days > 30
    msg := sprintf("PCI-DSS violation: Unpatched %s vulnerability older than 30 days: %s", 
                   [vuln.Severity, vuln.VulnerabilityID])
}