- Introduced `sink-detect.js` with various security sink detection patterns categorized by type (e.g., command injection, SQL injection, file operations). - Implemented functions to build a lookup map for fast sink detection and to match sink calls against known patterns. - Added `package-lock.json` for dependency management.
328 lines
9.5 KiB
JSON
328 lines
9.5 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://stellaops.io/schemas/policy-pack.schema.json",
|
|
"title": "Stella Ops Policy Pack",
|
|
"description": "Schema for validating Stella Ops policy pack YAML files",
|
|
"type": "object",
|
|
"required": ["apiVersion", "kind", "metadata", "spec"],
|
|
"properties": {
|
|
"apiVersion": {
|
|
"type": "string",
|
|
"pattern": "^policy\\.stellaops\\.io/v[0-9]+$",
|
|
"description": "API version for the policy pack format",
|
|
"examples": ["policy.stellaops.io/v1"]
|
|
},
|
|
"kind": {
|
|
"type": "string",
|
|
"enum": ["PolicyPack", "PolicyOverride"],
|
|
"description": "Type of policy document"
|
|
},
|
|
"metadata": {
|
|
"$ref": "#/$defs/Metadata"
|
|
},
|
|
"spec": {
|
|
"$ref": "#/$defs/PolicySpec"
|
|
}
|
|
},
|
|
"$defs": {
|
|
"Metadata": {
|
|
"type": "object",
|
|
"required": ["name", "version"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$",
|
|
"minLength": 2,
|
|
"maxLength": 63,
|
|
"description": "Unique identifier for the policy pack"
|
|
},
|
|
"version": {
|
|
"type": "string",
|
|
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9]+)?$",
|
|
"description": "Semantic version of the policy pack"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"maxLength": 500,
|
|
"description": "Human-readable description"
|
|
},
|
|
"labels": {
|
|
"type": "object",
|
|
"additionalProperties": { "type": "string" },
|
|
"description": "Key-value labels for categorization"
|
|
},
|
|
"annotations": {
|
|
"type": "object",
|
|
"additionalProperties": { "type": "string" },
|
|
"description": "Key-value annotations for custom metadata"
|
|
},
|
|
"parent": {
|
|
"type": "string",
|
|
"description": "Parent policy pack name (for overrides)"
|
|
},
|
|
"environment": {
|
|
"type": "string",
|
|
"enum": ["development", "staging", "production", "all"],
|
|
"description": "Target environment for this policy"
|
|
}
|
|
}
|
|
},
|
|
"PolicySpec": {
|
|
"type": "object",
|
|
"properties": {
|
|
"settings": {
|
|
"$ref": "#/$defs/PolicySettings"
|
|
},
|
|
"rules": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/PolicyRule" },
|
|
"description": "List of policy rules"
|
|
},
|
|
"ruleOverrides": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/RuleOverride" },
|
|
"description": "Overrides for parent policy rules"
|
|
},
|
|
"additionalRules": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/PolicyRule" },
|
|
"description": "Additional rules to add on top of parent"
|
|
}
|
|
}
|
|
},
|
|
"PolicySettings": {
|
|
"type": "object",
|
|
"properties": {
|
|
"defaultAction": {
|
|
"type": "string",
|
|
"enum": ["allow", "warn", "block"],
|
|
"default": "warn",
|
|
"description": "Default action for unmatched findings"
|
|
},
|
|
"unknownsThreshold": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"default": 0.05,
|
|
"description": "Maximum ratio of packages with unknown metadata (0.0-1.0)"
|
|
},
|
|
"requireSignedSbom": {
|
|
"type": "boolean",
|
|
"default": true,
|
|
"description": "Require cryptographically signed SBOM"
|
|
},
|
|
"requireSignedVerdict": {
|
|
"type": "boolean",
|
|
"default": true,
|
|
"description": "Require cryptographically signed policy verdict"
|
|
},
|
|
"minimumVexTrustScore": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"default": 0.5,
|
|
"description": "Minimum trust score for VEX source acceptance"
|
|
}
|
|
}
|
|
},
|
|
"PolicyRule": {
|
|
"type": "object",
|
|
"required": ["name", "action"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$",
|
|
"description": "Unique rule identifier"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Human-readable rule description"
|
|
},
|
|
"priority": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"maximum": 1000,
|
|
"default": 50,
|
|
"description": "Rule priority (higher = evaluated first)"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["finding", "aggregate"],
|
|
"default": "finding",
|
|
"description": "Rule type: per-finding or aggregate"
|
|
},
|
|
"match": {
|
|
"$ref": "#/$defs/RuleMatch",
|
|
"description": "Conditions that must match for rule to apply"
|
|
},
|
|
"unless": {
|
|
"$ref": "#/$defs/RuleUnless",
|
|
"description": "Conditions that exempt from this rule"
|
|
},
|
|
"require": {
|
|
"$ref": "#/$defs/RuleRequire",
|
|
"description": "Requirements that must be met"
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"enum": ["allow", "warn", "block"],
|
|
"description": "Action to take when rule matches"
|
|
},
|
|
"log": {
|
|
"type": "boolean",
|
|
"default": false,
|
|
"description": "Whether to log when rule matches"
|
|
},
|
|
"logLevel": {
|
|
"type": "string",
|
|
"enum": ["minimal", "normal", "verbose"],
|
|
"default": "normal"
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Message template with {variable} placeholders"
|
|
}
|
|
}
|
|
},
|
|
"RuleMatch": {
|
|
"type": "object",
|
|
"properties": {
|
|
"always": {
|
|
"type": "boolean",
|
|
"description": "Always match (for default rules)"
|
|
},
|
|
"severity": {
|
|
"oneOf": [
|
|
{ "type": "string", "enum": ["CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"] },
|
|
{
|
|
"type": "array",
|
|
"items": { "type": "string", "enum": ["CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"] }
|
|
}
|
|
],
|
|
"description": "CVE severity to match"
|
|
},
|
|
"reachability": {
|
|
"type": "string",
|
|
"enum": ["reachable", "unreachable", "unknown"],
|
|
"description": "Reachability status"
|
|
},
|
|
"kev": {
|
|
"type": "boolean",
|
|
"description": "Match CISA KEV vulnerabilities"
|
|
},
|
|
"environment": {
|
|
"type": "string",
|
|
"description": "Target environment"
|
|
},
|
|
"isDirect": {
|
|
"type": "boolean",
|
|
"description": "Match direct dependencies only"
|
|
},
|
|
"hasSecurityContact": {
|
|
"type": "boolean",
|
|
"description": "Whether package has security contact"
|
|
},
|
|
"unknownsRatio": {
|
|
"$ref": "#/$defs/NumericComparison",
|
|
"description": "Aggregate: ratio of unknown packages"
|
|
},
|
|
"hasException": {
|
|
"type": "boolean",
|
|
"description": "Whether finding has exception"
|
|
}
|
|
}
|
|
},
|
|
"RuleUnless": {
|
|
"type": "object",
|
|
"properties": {
|
|
"vexStatus": {
|
|
"type": "string",
|
|
"enum": ["not_affected", "affected", "fixed", "under_investigation"],
|
|
"description": "VEX status that exempts from rule"
|
|
},
|
|
"vexJustification": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": [
|
|
"vulnerable_code_not_present",
|
|
"vulnerable_code_cannot_be_controlled_by_adversary",
|
|
"inline_mitigations_already_exist",
|
|
"vulnerable_code_not_in_execute_path",
|
|
"component_not_present"
|
|
]
|
|
},
|
|
"description": "VEX justifications that exempt from rule"
|
|
},
|
|
"vexTrustScore": {
|
|
"$ref": "#/$defs/NumericComparison",
|
|
"description": "Minimum VEX trust score for exemption"
|
|
}
|
|
}
|
|
},
|
|
"RuleRequire": {
|
|
"type": "object",
|
|
"properties": {
|
|
"signedSbom": {
|
|
"type": "boolean",
|
|
"description": "Require signed SBOM"
|
|
},
|
|
"signedVerdict": {
|
|
"type": "boolean",
|
|
"description": "Require signed verdict"
|
|
},
|
|
"exceptionApproval": {
|
|
"type": "boolean",
|
|
"description": "Require exception approval"
|
|
},
|
|
"exceptionExpiry": {
|
|
"type": "object",
|
|
"properties": {
|
|
"maxDays": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 365
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"RuleOverride": {
|
|
"type": "object",
|
|
"required": ["name"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Name of rule to override"
|
|
},
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable or disable the rule"
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"enum": ["allow", "warn", "block"],
|
|
"description": "Override action"
|
|
},
|
|
"log": {
|
|
"type": "boolean"
|
|
},
|
|
"logLevel": {
|
|
"type": "string",
|
|
"enum": ["minimal", "normal", "verbose"]
|
|
}
|
|
}
|
|
},
|
|
"NumericComparison": {
|
|
"type": "object",
|
|
"properties": {
|
|
"gt": { "type": "number" },
|
|
"gte": { "type": "number" },
|
|
"lt": { "type": "number" },
|
|
"lte": { "type": "number" },
|
|
"eq": { "type": "number" }
|
|
}
|
|
}
|
|
}
|
|
}
|