Files
git.stella-ops.org/docs/policy/starter-guide.md
StellaOps Bot 56e2dc01ee Add unit tests for AST parsing and security sink detection
- Created `StellaOps.AuditPack.Tests.csproj` for unit testing the AuditPack library.
- Implemented comprehensive unit tests in `index.test.js` for AST parsing, covering various JavaScript and TypeScript constructs including functions, classes, decorators, and JSX.
- Added `sink-detect.test.js` to test security sink detection patterns, validating command injection, SQL injection, file write, deserialization, SSRF, NoSQL injection, and more.
- Included tests for taint source detection in various contexts such as Express, Koa, and AWS Lambda.
2025-12-23 09:23:42 +02:00

390 lines
10 KiB
Markdown

# Starter Policy Pack Guide
This guide covers the StellaOps starter policy pack (`starter-day1`), a production-ready policy designed for organizations beginning their software supply chain security journey.
## Quick Start
Install and activate the starter policy in under 5 minutes:
```bash
# Install the starter policy pack
stellaops policy install starter-day1
# Validate a policy file
stellaops policy validate policies/starter-day1.yaml
# Simulate policy against a scan
stellaops policy simulate --policy policies/starter-day1.yaml --scan <scan-id>
```
## Overview
The starter policy implements a sensible security posture:
| What | Action | Rationale |
|------|--------|-----------|
| Reachable HIGH/CRITICAL vulnerabilities | **Block** | Highest risk - exploitable code paths |
| Reachable MEDIUM vulnerabilities | **Warn** | Moderate risk - review recommended |
| Unreachable vulnerabilities | **Allow** (logged) | Low risk - no exploitable path |
| VEX-covered vulnerabilities | **Allow** | Evidence-based exception |
| Unknowns > 5% of packages | **Block** | Quality gate for metadata coverage |
| Unsigned SBOM (production) | **Block** | Integrity requirement |
| Unsigned verdict (production) | **Block** | Compliance attestation |
## Rule-by-Rule Explanation
### Rule 1: Block Reachable HIGH/CRITICAL
```yaml
- name: block-reachable-high-critical
description: "Block deployments with reachable HIGH or CRITICAL vulnerabilities"
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"
```
**What it does**: Blocks any deployment containing HIGH or CRITICAL severity vulnerabilities where the vulnerable code is reachable (can be executed).
**VEX bypass**: If a VEX statement marks the vulnerability as `not_affected` with proper justification, the block is bypassed. Valid justifications:
- `vulnerable_code_not_present` - The vulnerable function isn't compiled in
- `vulnerable_code_cannot_be_controlled_by_adversary` - Input cannot reach vulnerable code
- `inline_mitigations_already_exist` - Application-level mitigations in place
### Rule 2: Warn on Reachable MEDIUM
```yaml
- name: warn-reachable-medium
description: "Warn on reachable MEDIUM severity vulnerabilities"
match:
severity: MEDIUM
reachability: reachable
unless:
vexStatus: not_affected
action: warn
message: "Reachable MEDIUM vulnerability {cve} should be reviewed"
```
**What it does**: Generates a warning (but allows deployment) for MEDIUM severity reachable vulnerabilities.
**When to upgrade**: If your security posture matures, consider changing `action: warn` to `action: block`.
### Rule 3: Allow Unreachable
```yaml
- name: ignore-unreachable
description: "Allow unreachable vulnerabilities but log for awareness"
match:
reachability: unreachable
action: allow
log: true
message: "Vulnerability {cve} is unreachable - allowing"
```
**What it does**: Allows vulnerabilities where static analysis proves the code cannot be reached.
**Logging**: Even allowed findings are logged for audit purposes.
### Rule 4: Unknowns Budget
```yaml
- name: fail-on-unknowns
description: "Block if too many packages have unknown metadata"
type: aggregate
match:
unknownsRatio:
gt: ${settings.unknownsThreshold}
action: block
message: "Unknown packages exceed threshold ({unknownsRatio}% > {threshold}%)"
```
**What it does**: Blocks deployment if more than 5% of packages lack sufficient metadata for analysis.
**Why**: High unknowns ratio indicates poor SBOM quality or unsupported package ecosystems.
### Rules 5-6: Signed Artifacts (Production)
```yaml
- name: require-signed-sbom-prod
match:
environment: production
require:
signedSbom: true
action: block
message: "Production deployment requires signed SBOM"
- name: require-signed-verdict-prod
match:
environment: production
require:
signedVerdict: true
action: block
message: "Production deployment requires signed verdict"
```
**What they do**: Require cryptographically signed SBOM and verdict attestations for production environments.
**Why**: Ensures integrity and non-repudiation of security assessments.
### Rule 7: Default Allow
```yaml
- name: default-allow
description: "Allow everything not matched by above rules"
match:
always: true
action: allow
```
**What it does**: Explicit default action for any finding not matched by prior rules.
## Environment Overrides
The starter policy supports environment-specific overrides:
### Development (`overrides/development.yaml`)
```yaml
apiVersion: policy.stellaops.io/v1
kind: PolicyOverride
metadata:
name: starter-day1-dev
parent: starter-day1
environment: development
spec:
settings:
defaultAction: warn # Never block in dev
unknownsThreshold: 0.20 # Allow more unknowns (20%)
ruleOverrides:
- name: block-reachable-high-critical
action: warn # Downgrade to warn
- name: require-signed-sbom-prod
enabled: false # Disable signing requirements
- name: require-signed-verdict-prod
enabled: false
```
### Staging (`overrides/staging.yaml`)
```yaml
apiVersion: policy.stellaops.io/v1
kind: PolicyOverride
metadata:
name: starter-day1-staging
parent: starter-day1
environment: staging
spec:
settings:
unknownsThreshold: 0.10 # 10% unknowns budget
ruleOverrides:
- name: require-signed-sbom-prod
enabled: false # No signing in staging
```
### Production (Default)
Production uses the base policy with all rules enabled.
## Customization Guide
### Adjusting Severity Thresholds
To block MEDIUM vulnerabilities too:
```yaml
ruleOverrides:
- name: warn-reachable-medium
action: block
```
### Changing Unknowns Budget
To allow 10% unknowns:
```yaml
settings:
unknownsThreshold: 0.10
```
### Adding Custom Rules
Insert rules before `default-allow`:
```yaml
rules:
# ... existing rules ...
# Custom: Block specific CVE
- name: block-specific-cve
match:
cve: CVE-2024-1234
action: block
message: "CVE-2024-1234 is explicitly blocked by policy"
- name: default-allow
match:
always: true
action: allow
```
### Source Allowlists
Trust only specific VEX sources:
```yaml
settings:
vexSources:
allowlist:
- redhat-csaf
- canonical-usn
- vendor-security
requireTrustScore: 0.7
```
## Troubleshooting
### "Reachable HIGH vulnerability must be remediated"
**Cause**: A HIGH/CRITICAL vulnerability exists in code that can execute.
**Solutions**:
1. Update the affected package to a fixed version
2. Create a VEX statement if the vulnerability doesn't apply:
```bash
stellaops vex create --cve CVE-2024-1234 --status not_affected \
--justification vulnerable_code_not_present
```
3. Apply a temporary exception (with approval):
```yaml
exceptions:
- cve: CVE-2024-1234
expires: 2025-02-01
approver: security-team
reason: "Patch scheduled for next sprint"
```
### "Unknown packages exceed threshold"
**Cause**: Too many packages lack metadata for vulnerability analysis.
**Solutions**:
1. Ensure SBOMs are complete with package versions
2. Check for unsupported package ecosystems
3. Temporarily increase threshold in non-production:
```yaml
settings:
unknownsThreshold: 0.15
```
### "Production deployment requires signed SBOM"
**Cause**: Attempting production deployment without signed SBOM.
**Solutions**:
1. Sign SBOM during build:
```bash
stellaops sbom sign --sbom sbom.json --key-id <key>
```
2. Verify signing is configured in CI/CD pipeline
### Rule Not Matching as Expected
Use simulation mode to debug:
```bash
stellaops policy simulate --policy policy.yaml --scan <scan-id> --verbose
```
Check:
- Rule order (first match wins)
- Severity casing (use uppercase: HIGH, CRITICAL)
- Reachability values (reachable, unreachable, unknown)
## Migration Path to Custom Policies
### Step 1: Start with Starter Policy
Deploy `starter-day1` as-is to establish baseline.
### Step 2: Monitor and Tune
Review policy decisions for 2-4 weeks:
- Which rules trigger most?
- Which findings need exceptions?
- What patterns emerge?
### Step 3: Create Overlays
Add overlays for organization-specific needs:
```yaml
apiVersion: policy.stellaops.io/v1
kind: PolicyOverride
metadata:
name: acme-corp-policy
parent: starter-day1
spec:
ruleOverrides:
- name: block-reachable-high-critical
unless:
# Add company-specific VEX sources
vexSource:
- acme-security-team
```
### Step 4: Graduate to Custom Policy
When ready, fork the starter policy and customize fully:
```bash
# Export starter policy as starting point
stellaops policy pull --from registry.stellaops.io/policies/starter-day1:1.0.0 \
--output ./my-custom-policy/
# Modify as needed
vim ./my-custom-policy/base.yaml
# Validate changes
stellaops policy validate ./my-custom-policy/
# Push to your registry
stellaops policy push --policy ./my-custom-policy/base.yaml \
--to myregistry.example.com/policies/acme-policy:1.0.0 --sign
```
## CLI Reference
| Command | Description |
|---------|-------------|
| `stellaops policy validate <path>` | Validate policy against schema |
| `stellaops policy install <name>` | Install policy pack |
| `stellaops policy list-packs` | List available policy packs |
| `stellaops policy simulate --policy <path> --scan <id>` | Simulate policy evaluation |
| `stellaops policy push --policy <path> --to <ref>` | Push to OCI registry |
| `stellaops policy pull --from <ref>` | Pull from OCI registry |
| `stellaops policy export-bundle --policy <path> --output <file>` | Create offline bundle |
| `stellaops policy import-bundle --bundle <file>` | Import offline bundle |
## See Also
- [Policy DSL Reference](dsl.md)
- [VEX Trust Model](vex-trust-model.md)
- [Policy Governance](governance.md)
- [Scoring Profiles](scoring-profiles.md)