warnings fixes, tests fixes, sprints completions
This commit is contained in:
116
policies/secret-detection.rego
Normal file
116
policies/secret-detection.rego
Normal file
@@ -0,0 +1,116 @@
|
||||
# Secret Detection Policy - OPA Rego
|
||||
# Sprint: SPRINT_20260104_004_POLICY - Task PSD-010
|
||||
#
|
||||
# This Rego policy provides advanced logic for secret detection gates.
|
||||
# Use this for complex organizations that need conditional logic based on
|
||||
# environment, image source, or team ownership.
|
||||
#
|
||||
# Input schema (from ScanResult):
|
||||
# input.secrets.findings[] - Array of SecretFinding objects
|
||||
# input.secrets.bundle.version - Bundle version used for detection
|
||||
# input.secrets.maskApplied - Whether masking was applied
|
||||
# input.image.name - Full image name
|
||||
# input.image.registry - Registry domain
|
||||
# input.environment - Deployment environment (dev/staging/prod)
|
||||
|
||||
package stella.policy.secrets
|
||||
|
||||
import future.keywords.contains
|
||||
import future.keywords.if
|
||||
import future.keywords.in
|
||||
|
||||
default deny := []
|
||||
default warn := []
|
||||
|
||||
# Block any critical secrets in production
|
||||
deny contains msg if {
|
||||
input.environment == "production"
|
||||
finding := input.secrets.findings[_]
|
||||
finding.severity == "critical"
|
||||
msg := sprintf(
|
||||
"BLOCKED: Critical secret '%s' detected in production image %s. Rule: %s",
|
||||
[finding.ruleId, input.image.name, finding.ruleName]
|
||||
)
|
||||
}
|
||||
|
||||
# Block high-severity secrets with high confidence in all environments
|
||||
deny contains msg if {
|
||||
finding := input.secrets.findings[_]
|
||||
finding.severity == "high"
|
||||
finding.confidence == "high"
|
||||
msg := sprintf(
|
||||
"BLOCKED: High-confidence secret '%s' detected in %s. File: %s",
|
||||
[finding.ruleName, input.image.name, finding.filePath]
|
||||
)
|
||||
}
|
||||
|
||||
# Allow low-confidence findings in dev, but block in prod/staging
|
||||
deny contains msg if {
|
||||
input.environment in {"production", "staging"}
|
||||
finding := input.secrets.findings[_]
|
||||
finding.severity in {"high", "critical"}
|
||||
finding.confidence == "low"
|
||||
msg := sprintf(
|
||||
"BLOCKED: Low-confidence secret finding requires review before %s deployment. Rule: %s",
|
||||
[input.environment, finding.ruleName]
|
||||
)
|
||||
}
|
||||
|
||||
# Warn on medium severity secrets in any environment
|
||||
warn contains msg if {
|
||||
finding := input.secrets.findings[_]
|
||||
finding.severity == "medium"
|
||||
msg := sprintf(
|
||||
"WARNING: Medium-severity secret '%s' in %s. Consider adding to exceptions if legitimate.",
|
||||
[finding.ruleName, finding.filePath]
|
||||
)
|
||||
}
|
||||
|
||||
# Warn if secret count exceeds threshold (potential bulk exposure)
|
||||
warn contains msg if {
|
||||
count(input.secrets.findings) > 10
|
||||
msg := sprintf(
|
||||
"WARNING: High number of secrets detected (%d findings). Review for bulk credential exposure.",
|
||||
[count(input.secrets.findings)]
|
||||
)
|
||||
}
|
||||
|
||||
# Block export without masking
|
||||
deny contains msg if {
|
||||
input.context == "export"
|
||||
not input.secrets.maskApplied
|
||||
msg := "BLOCKED: Secrets must be masked before export. Enable masking in revelation policy."
|
||||
}
|
||||
|
||||
# Require bundle signature verification
|
||||
deny contains msg if {
|
||||
input.environment == "production"
|
||||
not input.secrets.bundle.verified
|
||||
msg := sprintf(
|
||||
"BLOCKED: Secret detection bundle '%s' signature verification failed.",
|
||||
[input.secrets.bundle.id]
|
||||
)
|
||||
}
|
||||
|
||||
# Warn on outdated bundle in production
|
||||
warn contains msg if {
|
||||
input.environment == "production"
|
||||
input.secrets.bundle.ageHours > 168 # 7 days
|
||||
msg := sprintf(
|
||||
"WARNING: Secret detection bundle is over 7 days old (version: %s). Update for latest rules.",
|
||||
[input.secrets.bundle.version]
|
||||
)
|
||||
}
|
||||
|
||||
# Allowlist: Skip checks for internal base images
|
||||
skip_secret_checks if {
|
||||
startswith(input.image.registry, "internal.registry.")
|
||||
input.image.isBaseImage
|
||||
}
|
||||
|
||||
# Allowlist: Skip low-severity in dev environment
|
||||
skip_warning[finding.id] if {
|
||||
input.environment == "development"
|
||||
finding := input.secrets.findings[_]
|
||||
finding.severity == "low"
|
||||
}
|
||||
Reference in New Issue
Block a user