Baselines & Tracking
Track security progress over time by comparing scans against a baseline. Show only new findings, celebrate fixes, and maintain visibility into existing issues.
What is a Baseline?
A baseline is a snapshot of your security findings at a point in time. It lets you:
- See only new issues — Focus on what changed, not legacy debt
- Track progress — See when issues are fixed
- Maintain awareness — Know existing issues without noise
Creating a Baseline
Create a baseline from your current scan:
oculum baseline create
This:
- Runs a full scan of your codebase
- Stores finding hashes in
.oculum/baseline.json - Records git commit and branch info
With Options
# Create baseline with specific depth
oculum baseline create --depth verified
# Create baseline for specific path
oculum baseline create ./src
# Quiet mode (no output)
oculum baseline create -q
Scanning Against Baseline
Show only new findings (not in baseline):
oculum scan --new
This compares current findings against the baseline and shows:
- New findings — Issues not in the baseline
- Fixed count — How many issues were resolved
- Existing count — How many baseline issues remain
Example Output
┌────────────────────────────────────────────────────────────────┐
│ Oculum Security Scan (Baseline Mode) │
│ Baseline: 2026-01-15 (abc1234) │
└────────────────────────────────────────────────────────────────┘
New findings: 2
Fixed since baseline: 3
Existing issues: 12
NEW FINDINGS:
HIGH: Unvalidated User Input
src/api/new-endpoint.ts:23
User input passed directly to prompt
MEDIUM: Missing Rate Limiting
src/api/new-endpoint.ts:1
No rate limiting on AI endpoint
Viewing Baseline Info
See what's in your current baseline:
oculum baseline show
Output:
Baseline Information:
Created: 2026-01-15T10:30:00Z
Git commit: abc1234
Git branch: main
Scan depth: verified
Findings:
Critical: 0
High: 5
Medium: 8
Low: 3
Info: 2
Total: 18
Clearing a Baseline
Remove the baseline to see all findings again:
oculum baseline clear
This deletes .oculum/baseline.json.
Baseline File Format
The baseline is stored in .oculum/baseline.json:
{
"version": 1,
"createdAt": "2026-01-15T10:30:00Z",
"gitCommit": "abc1234def567890",
"gitBranch": "main",
"scanDepth": "verified",
"findings": [
{
"hash": "a1b2c3d4e5f67890",
"path": "src/api/auth.ts",
"line": 42,
"category": "hardcoded_secret",
"severity": "high"
}
],
"summary": {
"critical": 0,
"high": 5,
"medium": 8,
"low": 3,
"info": 2,
"total": 18
}
}
Version Control
Recommended: Commit .oculum/baseline.json to version control.
This allows:
- Team members to use the same baseline
- CI to compare against the established baseline
- Tracking baseline changes over time
git add .oculum/baseline.json
git commit -m "Update security baseline"
CI/CD Integration
PR Checks: Show Only New Issues
# GitHub Actions
- name: Security Scan (new findings only)
run: |
oculum scan --new --fail-on high
This fails only if the PR introduces new high/critical issues.
Main Branch: Update Baseline
# After merging to main
- name: Update Baseline
if: github.ref == 'refs/heads/main'
run: |
oculum baseline create --depth verified
git add .oculum/baseline.json
git commit -m "Update security baseline" || true
git push
Complete Workflow
name: Security
on:
pull_request:
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# On PRs: Show only new findings
- name: Scan PR
if: github.event_name == 'pull_request'
run: oculum scan --new --fail-on high
# On main: Full scan and update baseline
- name: Scan Main
if: github.ref == 'refs/heads/main'
run: |
oculum scan --depth verified --fail-on high
oculum baseline create
Baseline Strategies
Strategy 1: Fresh Start
Best for new projects or major refactors:
# Fix all critical/high issues first
oculum scan --fail-on high
# Then create baseline
oculum baseline create
Strategy 2: Accept Legacy, Block New
Best for existing projects with security debt:
# Create baseline of current state
oculum baseline create
# From now on, only fail on new issues
oculum scan --new --fail-on high
Strategy 3: Gradual Improvement
Reduce baseline over time:
# Create initial baseline
oculum baseline create # 50 findings
# Fix issues, update baseline
# ... fix 10 issues ...
oculum baseline create # 40 findings
# Continue reducing
# Track progress in your issue tracker
Hash Stability
Baseline comparison uses finding hashes, which are stable across:
- Whitespace changes
- Minor formatting
- Line number changes (within reason)
Hashes change when:
- The actual vulnerable code changes
- The file is renamed/moved
- The detection category changes
Baseline Diff Details
The --new flag adds baseline information to the scan result:
{
"baselineDiff": {
"baselineCreatedAt": "2026-01-15T10:30:00Z",
"baselineCommit": "abc1234",
"newCount": 2,
"fixedCount": 3,
"existingCount": 12,
"fixedFindings": [
{
"hash": "x1y2z3...",
"category": "hardcoded_secret"
}
]
}
}
Best Practices
1. Create Baseline at Known-Good State
Don't baseline a "broken" state. Fix critical issues first:
oculum scan --fail-on critical # Fix these
oculum baseline create # Then baseline
2. Update Baseline Deliberately
Don't auto-update on every merge. Update when:
- Security debt is intentionally accepted
- Major fixes are completed
- Team reviews and approves the new state
3. Document Baseline Decisions
Keep notes on why certain findings are in the baseline:
git commit -m "Update baseline: accepted 3 low-severity config warnings per SECURITY-123"
4. Review Fixed Findings
Celebrate progress! When --new shows fixed findings, acknowledge the improvement.
Related
- Suppressing Findings — Handle false positives
- Incremental Scans — Scan only changed files
- CI/CD Setup — Pipeline integration