more audit work
This commit is contained in:
@@ -2,28 +2,92 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.io/schemas/policy-pack.schema.json",
|
||||
"title": "Policy Pack Schema",
|
||||
"description": "Schema for StellaOps policy pack definitions.",
|
||||
"description": "Schema for StellaOps policy packs and overrides.",
|
||||
"type": "object",
|
||||
"required": ["apiVersion", "kind", "metadata", "spec"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"description": "The name of the policy pack."
|
||||
"pattern": "^policy\\.stellaops\\.io/v[0-9]+$"
|
||||
},
|
||||
"version": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"description": "The version of the policy pack."
|
||||
"enum": ["PolicyPack", "PolicyOverride"]
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A description of the policy pack."
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"required": ["name", "version"],
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"version": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"parent": { "type": "string" },
|
||||
"environment": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": true
|
||||
},
|
||||
"rules": {
|
||||
"type": "array",
|
||||
"description": "The rules in the policy pack.",
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
"spec": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"rules": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/rule" }
|
||||
},
|
||||
"ruleOverrides": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/ruleOverride" }
|
||||
},
|
||||
"additionalRules": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/rule" }
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"required": ["name", "version"]
|
||||
"$defs": {
|
||||
"rule": {
|
||||
"type": "object",
|
||||
"required": ["name", "action"],
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"action": { "type": "string", "enum": ["allow", "warn", "block"] },
|
||||
"priority": { "type": "integer" },
|
||||
"description": { "type": "string" },
|
||||
"match": { "type": "object", "additionalProperties": true },
|
||||
"unless": { "type": "object", "additionalProperties": true },
|
||||
"require": { "type": "object", "additionalProperties": true },
|
||||
"message": { "type": "string" },
|
||||
"log": { "type": "boolean" },
|
||||
"enabled": { "type": "boolean" },
|
||||
"type": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": true
|
||||
},
|
||||
"ruleOverride": {
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"action": { "type": "string", "enum": ["allow", "warn", "block"] },
|
||||
"enabled": { "type": "boolean" }
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": { "properties": { "kind": { "const": "PolicyPack" } } },
|
||||
"then": { "properties": { "spec": { "required": ["rules"] } } }
|
||||
},
|
||||
{
|
||||
"if": { "properties": { "kind": { "const": "PolicyOverride" } } },
|
||||
"then": { "properties": { "metadata": { "required": ["parent", "environment"] } } }
|
||||
}
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
|
||||
@@ -1,118 +1,83 @@
|
||||
# Starter Day-1 Policy Pack
|
||||
# Sprint: SPRINT_20260104_004_POLICY - Task PSD-010
|
||||
#
|
||||
# This is a comprehensive starter policy for day-1 security controls.
|
||||
# It includes gates for vulnerabilities, secret detection, and SBOM quality.
|
||||
# Comprehensive starter policy for day-1 security controls.
|
||||
|
||||
name: starter-day1
|
||||
version: 1.0.0
|
||||
description: |
|
||||
Starter policy pack for day-1 security controls.
|
||||
Includes essential gates for vulnerabilities, secrets, and SBOM validation.
|
||||
apiVersion: policy.stellaops.io/v1
|
||||
kind: PolicyPack
|
||||
metadata:
|
||||
name: starter-day1
|
||||
version: 1.0.0
|
||||
description: |
|
||||
Starter policy pack for day-1 security controls.
|
||||
Includes essential gates for vulnerabilities, reachability, and metadata quality.
|
||||
|
||||
rules:
|
||||
# === VULNERABILITY GATES ===
|
||||
|
||||
- id: block-critical-cves
|
||||
description: Block images with critical vulnerabilities
|
||||
severity: critical
|
||||
when:
|
||||
signal: vuln.severity.critical
|
||||
operator: gt
|
||||
value: 0
|
||||
deny_message: |
|
||||
BLOCKED: Image contains critical vulnerabilities.
|
||||
Review CVEs and apply patches before deployment.
|
||||
spec:
|
||||
settings:
|
||||
defaultAction: warn
|
||||
unknownsThreshold: 0.05
|
||||
requireSignedSbom: true
|
||||
requireSignedVerdict: true
|
||||
|
||||
- id: block-kev-vulnerabilities
|
||||
description: Block images with Known Exploited Vulnerabilities
|
||||
severity: critical
|
||||
when:
|
||||
signal: vuln.kev.count
|
||||
operator: gt
|
||||
value: 0
|
||||
deny_message: |
|
||||
BLOCKED: Image contains Known Exploited Vulnerabilities (KEV).
|
||||
These vulnerabilities are actively being exploited in the wild.
|
||||
Immediate remediation required.
|
||||
rules:
|
||||
- name: block-reachable-high-critical
|
||||
description: "Block deployments with reachable HIGH or CRITICAL vulnerabilities"
|
||||
priority: 100
|
||||
match:
|
||||
severity:
|
||||
- CRITICAL
|
||||
- HIGH
|
||||
reachability: reachable
|
||||
unless:
|
||||
vexStatus: not_affected
|
||||
vexJustification:
|
||||
- vulnerable_code_not_present
|
||||
- vulnerable_code_cannot_be_controlled_by_adversary
|
||||
- inline_mitigations_already_exist
|
||||
action: block
|
||||
message: "Reachable {severity} vulnerability {cve} must be remediated or have VEX justification"
|
||||
|
||||
# === SECRET DETECTION GATES ===
|
||||
|
||||
- id: block-critical-secrets
|
||||
description: Block deployment when critical secrets are detected
|
||||
severity: critical
|
||||
when:
|
||||
signal: secret.severity.critical
|
||||
equals: true
|
||||
deny_message: |
|
||||
BLOCKED: Critical secrets detected (private keys, service account keys).
|
||||
Rotate exposed credentials and remove from container image.
|
||||
- name: warn-reachable-medium
|
||||
description: "Warn on reachable MEDIUM severity vulnerabilities"
|
||||
priority: 90
|
||||
match:
|
||||
severity: MEDIUM
|
||||
reachability: reachable
|
||||
unless:
|
||||
vexStatus: not_affected
|
||||
action: warn
|
||||
message: "Reachable MEDIUM vulnerability {cve} should be reviewed"
|
||||
|
||||
- id: block-high-secrets
|
||||
description: Block deployment when high-severity secrets are detected
|
||||
severity: high
|
||||
when:
|
||||
all:
|
||||
- signal: secret.severity.high
|
||||
equals: true
|
||||
- signal: secret.confidence.high
|
||||
equals: true
|
||||
deny_message: |
|
||||
BLOCKED: High-severity secrets detected with high confidence.
|
||||
These appear to be real credentials. Remediate before deployment.
|
||||
- name: allow-unreachable
|
||||
description: "Allow unreachable vulnerabilities but log for awareness"
|
||||
priority: 80
|
||||
match:
|
||||
reachability: unreachable
|
||||
action: allow
|
||||
log: true
|
||||
message: "Vulnerability {cve} is unreachable - allowing"
|
||||
|
||||
- id: warn-secret-findings
|
||||
description: Warn when any secrets are detected
|
||||
severity: medium
|
||||
when:
|
||||
signal: secret.has_finding
|
||||
equals: true
|
||||
warn_message: |
|
||||
WARNING: Secret detection found {{secret.count}} potential secret(s).
|
||||
Review findings and add legitimate patterns to the exception list.
|
||||
- name: fail-on-unknowns
|
||||
description: "Block if too many packages have unknown metadata"
|
||||
priority: 70
|
||||
type: aggregate
|
||||
match:
|
||||
unknownsRatio:
|
||||
gt: ${settings.unknownsThreshold}
|
||||
action: block
|
||||
message: "Unknown packages exceed threshold ({unknownsRatio}% > {threshold}%)"
|
||||
|
||||
# === SBOM QUALITY GATES ===
|
||||
|
||||
- id: require-sbom
|
||||
description: Require a valid SBOM for all images
|
||||
severity: high
|
||||
when:
|
||||
signal: sbom.present
|
||||
equals: false
|
||||
deny_message: |
|
||||
BLOCKED: No SBOM found for image.
|
||||
Generate an SBOM before deployment (CycloneDX or SPDX format).
|
||||
- name: block-kev
|
||||
description: "Block images with Known Exploited Vulnerabilities"
|
||||
priority: 60
|
||||
match:
|
||||
kev: true
|
||||
action: block
|
||||
message: "Known Exploited Vulnerabilities (KEV) must be remediated before deployment"
|
||||
|
||||
- id: warn-unknown-components
|
||||
description: Warn when SBOM contains many unknown components
|
||||
severity: medium
|
||||
when:
|
||||
signal: sbom.unknown_ratio
|
||||
operator: gt
|
||||
value: 0.2
|
||||
warn_message: |
|
||||
WARNING: Over 20% of SBOM components could not be identified.
|
||||
Consider improving build process for better provenance.
|
||||
|
||||
# === IMAGE CONFIGURATION GATES ===
|
||||
|
||||
- id: block-root-user
|
||||
description: Block images that run as root by default
|
||||
severity: high
|
||||
when:
|
||||
signal: image.runs_as_root
|
||||
equals: true
|
||||
deny_message: |
|
||||
BLOCKED: Image runs as root user.
|
||||
Configure a non-root USER in the Dockerfile.
|
||||
|
||||
- id: warn-old-base-image
|
||||
description: Warn when base image is outdated
|
||||
severity: medium
|
||||
when:
|
||||
signal: image.base_age_days
|
||||
operator: gt
|
||||
value: 90
|
||||
warn_message: |
|
||||
WARNING: Base image is over 90 days old.
|
||||
Consider updating to get latest security patches.
|
||||
- name: default-allow
|
||||
description: "Allow everything not matched by above rules"
|
||||
priority: 0
|
||||
match:
|
||||
always: true
|
||||
action: allow
|
||||
|
||||
20
policies/starter-day1/overrides/development.yaml
Normal file
20
policies/starter-day1/overrides/development.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
apiVersion: policy.stellaops.io/v1
|
||||
kind: PolicyOverride
|
||||
metadata:
|
||||
name: starter-day1-dev
|
||||
version: 1.0.0
|
||||
parent: starter-day1
|
||||
environment: development
|
||||
|
||||
spec:
|
||||
settings:
|
||||
defaultAction: warn
|
||||
unknownsThreshold: 0.20
|
||||
requireSignedSbom: false
|
||||
requireSignedVerdict: false
|
||||
|
||||
ruleOverrides:
|
||||
- name: block-reachable-high-critical
|
||||
action: warn
|
||||
- name: block-kev
|
||||
action: warn
|
||||
22
policies/starter-day1/overrides/production.yaml
Normal file
22
policies/starter-day1/overrides/production.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: policy.stellaops.io/v1
|
||||
kind: PolicyOverride
|
||||
metadata:
|
||||
name: starter-day1-prod
|
||||
version: 1.0.0
|
||||
parent: starter-day1
|
||||
environment: production
|
||||
|
||||
spec:
|
||||
settings:
|
||||
defaultAction: block
|
||||
unknownsThreshold: 0.05
|
||||
requireSignedSbom: true
|
||||
requireSignedVerdict: true
|
||||
|
||||
additionalRules:
|
||||
- name: require-approval-for-exceptions
|
||||
description: "Require approval for exceptions in production"
|
||||
action: block
|
||||
match:
|
||||
exceptionRequested: true
|
||||
message: "Exception approvals are required in production"
|
||||
12
policies/starter-day1/overrides/staging.yaml
Normal file
12
policies/starter-day1/overrides/staging.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: policy.stellaops.io/v1
|
||||
kind: PolicyOverride
|
||||
metadata:
|
||||
name: starter-day1-staging
|
||||
version: 1.0.0
|
||||
parent: starter-day1
|
||||
environment: staging
|
||||
|
||||
spec:
|
||||
settings:
|
||||
defaultAction: warn
|
||||
unknownsThreshold: 0.10
|
||||
Reference in New Issue
Block a user