HDF CLI User Story Examples
Each section walks through a real user workflow for one CLI command. Run these after building the CLI:
cd hdf-cli && go build -o hdf ./cmd/hdf && cd ..Fixture files used throughout:
RESULTS=hdf-converters/converters/cyclonedx-to-hdf/fixtures/input/dropwizard-vulns.json
SARIF=hdf-converters/converters/sarif-to-hdf/fixtures/input/minimal.json
NESSUS=hdf-converters/converters/nessus-to-hdf/fixtures/input/sample.nessus
BASELINE=hdf-schema/test/fixtures/minimal-baseline.json1. Converting Security Tool Output to HDF
Story: A security engineer receives a CycloneDX vulnerability report and needs to convert it to HDF for their compliance dashboard.
# Auto-detect format and convert
hdf convert $RESULTS -o /tmp/example-hdf-results.json
# Validate the output
hdf validate /tmp/example-hdf-results.json
# Convert with explicit format
hdf convert --from cyclonedx $RESULTS -o /tmp/example-hdf-explicit.json
# Stamp a componentId during conversion
hdf convert $RESULTS -o /tmp/example-hdf-stamped.json --component-id "aaaaaaaa-1111-2222-3333-444444444444"
# Apply labels during conversion
hdf convert $RESULTS -o /tmp/example-hdf-labeled.json --labels "env=prod,system=Portal"
# Verify the output with hdf list
hdf list /tmp/example-hdf-labeled.json --detail components
# Convert Nessus (XML format)
hdf convert $NESSUS -o /tmp/example-hdf-nessus.json
hdf validate /tmp/example-hdf-nessus.jsonExpected: Each conversion produces valid HDF with components[], embedded SBOM for CycloneDX, and labels/componentId when flags are used.
2. Validating HDF Documents
Story: Before submitting an HDF document for compliance review, an engineer validates it against the schema.
# Validate results (auto-detect type)
hdf validate /tmp/example-hdf-results.json
# Validate with explicit type
hdf validate --type results /tmp/example-hdf-results.json
# Validate with wrong type — should fail with type-specific error
hdf validate --type system /tmp/example-hdf-results.json
# Expected: "Ensure the file conforms to the HDF system schema"
# Validate JSON output
hdf validate --json /tmp/example-hdf-results.json
# Validate invalid file — errors include line numbers for file input
echo '{
"baselines": "not an array",
"components": [],
"statistics": {}
}' > /tmp/example-hdf-invalid.json
hdf validate /tmp/example-hdf-invalid.json
# Expected: "line 2: baselines: Invalid type..."
# Validate invalid file with JSON output — line numbers in error objects
hdf validate --json /tmp/example-hdf-invalid.jsonExpected: Valid docs pass, wrong-type gives schema-specific error message, invalid JSON fails with clear errors including line numbers.
3. Listing HDF Document Contents
Story: An analyst wants to see what's in an HDF file without opening it in a JSON editor.
# Summary of results file
hdf list /tmp/example-hdf-results.json
# List requirements
hdf list /tmp/example-hdf-results.json --detail requirements
# List components
hdf list /tmp/example-hdf-results.json --detail components
# JSON output
hdf list /tmp/example-hdf-results.json --detail components --jsonExpected: Results summary shows baselines/components/status counts. Detail sections list individual items.
4. Querying Requirements
Story: A security engineer wants to find all failing critical requirements.
# Query by status
hdf query /tmp/example-hdf-results.json --status failed
# Query by severity
hdf query /tmp/example-hdf-results.json --severity critical
# Query by NIST control
hdf query /tmp/example-hdf-results.json --nist AC-3
# Free text search
hdf query /tmp/example-hdf-results.json --search "injection"
# JSON output
hdf query /tmp/example-hdf-results.json --status failed --json
# Combined filters
hdf query /tmp/example-hdf-results.json --status failed --nist SI-10Expected: Filters return matching requirements. JSON mode outputs structured data.
5. Comparing Scans Over Time
Story: A team wants to see what changed between two scans of the same system.
# Convert two different fixtures for comparison
hdf convert hdf-converters/converters/cyclonedx-to-hdf/fixtures/input/minimal-vulns.json -o /tmp/example-hdf-diff-old.json
hdf convert $RESULTS -o /tmp/example-hdf-diff-new.json
# Temporal diff (results documents)
hdf diff /tmp/example-hdf-diff-old.json /tmp/example-hdf-diff-new.json
# JSON output
hdf diff /tmp/example-hdf-diff-old.json /tmp/example-hdf-diff-new.json --json
# System drift diff
echo '{"name":"Sys","components":[{"name":"App","type":"application","componentId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}]}' > /tmp/example-hdf-sys-v1.json
echo '{"name":"Sys","components":[{"name":"App","type":"application","componentId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","description":"added"},{"name":"Cache","type":"application","componentId":"11111111-2222-3333-4444-555555555555"}],"dataFlows":[{"from":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","to":"11111111-2222-3333-4444-555555555555","protocol":"TCP","port":6379}]}' > /tmp/example-hdf-sys-v2.json
hdf diff /tmp/example-hdf-sys-v1.json /tmp/example-hdf-sys-v2.json
# Summary only
hdf diff /tmp/example-hdf-sys-v1.json /tmp/example-hdf-sys-v2.json --statExpected: Temporal diff shows requirement-level changes (fixed, regressed). System diff shows component and data flow changes.
6. Managing System Documents
Story: A system owner bootstraps a system document from scan results, then updates it.
# Create system from results (input file is positional)
hdf system create /tmp/example-hdf-results.json --name "Dropwizard Prod" \
--owner "platform-team@agency.gov" --description "Production Dropwizard" \
-o /tmp/example-hdf-system.json
# View system info (shows auto-generated systemId, owner, components)
hdf system info /tmp/example-hdf-system.json
# Update owner
hdf system set /tmp/example-hdf-system.json --owner "new-team@agency.gov"
# Unset optional field
hdf system set /tmp/example-hdf-system.json --unset description
# Try to unset required field — should fail
hdf system set /tmp/example-hdf-system.json --unset nameExpected: System documents have auto-generated systemId, owner, components. Set/unset work. Required fields are protected.
Story: A build pipeline records its artifact's components in the system document — one BOM, or several in one invocation.
# Add one component from a BOM (auto-detected; --from asserts a format if given)
hdf system add-component sbom.cdx.json --system /tmp/example-hdf-system.json --component-name AuthService
# Add SEVERAL BOMs at once (single write). --component-name-prefix namespaces the
# subjects and numbers unnamed ones continuously across the whole batch.
hdf system add-component app.cdx.json model.spdx.json --system /tmp/example-hdf-system.json \
--component-name-prefix build42-
# --from, when given, is ONE uniform assertion applied to every file (never a
# per-file/CSV list). Omit it to detect each file independently.
hdf system add-component a.cdx.json b.cdx.json --system /tmp/example-hdf-system.json --from cyclonedxExpected: Every component from every file is added in a single write. The batch is all-or-nothing — if any file cannot be parsed or built, all failures are reported and the system document is left unchanged (nothing partially added). This is deliberately stricter than hdf validate's per-file continue-and-report, because add-component mutates shared state. With multiple files, --component-name is rejected (it names a single component); use --component-name-prefix.
7. Labels and Component IDs
Story: A DevSecOps pipeline stamps labels and component IDs onto HDF output.
# Set labels
cp /tmp/example-hdf-results.json /tmp/example-hdf-label-test.json
hdf label set /tmp/example-hdf-label-test.json env=production system=Portal
hdf label show /tmp/example-hdf-label-test.json
# Remove a label
hdf label remove /tmp/example-hdf-label-test.json env
# Stamp componentId
hdf label set /tmp/example-hdf-label-test.json --component-id "deadbeef-1234-5678-9abc-def012345678"
# Generate unique componentIds
hdf label set /tmp/example-hdf-label-test.json --generate-component-idExpected: Labels are applied/removed on components[]. componentId is stamped correctly.
8. Applying Amendments (Waivers)
Story: An ISSM applies a waiver to a failing requirement.
# Create a minimal amendments doc
cat > /tmp/example-hdf-amendments.json << 'EOF'
{
"name": "Q1 Waivers",
"overrides": [
{
"type": "waiver",
"requirementId": "GHSA-5p34-5m6p-p58g",
"status": "passed",
"reason": "Compensating control in place",
"appliedBy": {"type": "email", "identifier": "issm@agency.gov"},
"appliedAt": "2026-03-27T00:00:00Z",
"expiresAt": "2026-09-27T00:00:00Z"
}
]
}
EOF
hdf validate --type amendments /tmp/example-hdf-amendments.json
# Apply amendments to results
hdf amend apply --results /tmp/example-hdf-results.json \
--amendments /tmp/example-hdf-amendments.json \
-o /tmp/example-hdf-amended.json
# Update amendments metadata
hdf amend set /tmp/example-hdf-amendments.json --amendment-id "550e8400-e29b-41d4-a716-446655440000"Expected: Amendments validate. Apply modifies effectiveStatus on matching requirements.
9. Generating InSpec Profiles
Story: A developer generates an InSpec profile stub from a DISA STIG.
# Generate from XCCDF benchmark XML (auto-detected)
hdf generate inspec-profile hdf-generators/test/fixtures/stig-rhel9-benchmark.xml /tmp/example-hdf-profile/
ls /tmp/example-hdf-profile/controls/ | head -5
# Verify with cinc-auditor
cinc-auditor check /tmp/example-hdf-profile/
# Generate from HDF Baseline JSON
# hdf generate inspec-profile $BASELINE /tmp/example-hdf-profile-json/
# Generate with explicit source type
# hdf generate inspec-profile benchmark.xml /tmp/example-hdf-profile/ -s xccdf
# Override metadata
# hdf generate inspec-profile benchmark.xml /tmp/example-hdf-profile/ --maintainer "MITRE SAF" --license Apache-2.0Expected: Profile directory with controls/ (named SV-xxx.rb) and inspec.yml. cinc-auditor reports Valid: true. (Note that cinc-auditor will print warnings for each requirement in the baseline, since the InSpec testfiles it generates only contain baseline metadata, and no actual executable test code.)
10. Assessment Plans
Story: A security engineer creates and manages assessment plans.
# Create a plan from a system document
hdf plan create /tmp/example-hdf-system.json -o /tmp/example-hdf-plan.json
hdf validate --type plan /tmp/example-hdf-plan.json
# Create a standalone plan (no system document required)
hdf plan create --name "RHEL9 Assessment" --baseline RHEL9-STIG -o /tmp/example-hdf-standalone-plan.json
# View plan info
hdf plan info /tmp/example-hdf-plan.json
# Update plan metadata
hdf plan set /tmp/example-hdf-plan.json --description "Monthly compliance scan"
hdf plan set /tmp/example-hdf-plan.json --system-ref portal-prod.hdf-system.json
hdf plan set /tmp/example-hdf-plan.json --version "1.0.0"Expected: Plans have auto-generated planId UUID. Create works from system file or standalone with --name/--baseline. Set updates fields in place.
11. Evidence Packages (Full Document Chain)
Story: A compliance officer builds the full document chain (system → plan → results → evidence) and verifies completeness.
# --- Step 1: Create a system document ---
cat > /tmp/example-hdf-system.json << 'EOF'
{
"systemId": "aaaaaaaa-1111-2222-3333-444444444444",
"name": "Portal Prod",
"components": [
{"name": "WebTier", "type": "application", "baselineRefs": ["RHEL9-STIG"]},
{"name": "DatabaseTier", "type": "application", "baselineRefs": ["PostgreSQL-STIG"]}
]
}
EOF
hdf validate --type system /tmp/example-hdf-system.json
# --- Step 2: Create an assessment plan from the system ---
hdf plan create /tmp/example-hdf-system.json -o /tmp/example-hdf-plan.json
hdf validate --type plan /tmp/example-hdf-plan.json
# Plan should have 2 assessments: RHEL9-STIG, PostgreSQL-STIG
# --- Step 3: Create results for each baseline ---
cat > /tmp/example-hdf-rhel9-results.json << 'EOF'
{
"baselines": [{"name": "RHEL9-STIG", "requirements": [
{"id": "SV-257777", "title": "Vendor support", "descriptions": [{"label": "default", "data": "check"}],
"impact": 0.7, "tags": {}, "results": [{"status": "passed", "codeDesc": "check", "startTime": "2026-03-30T00:00:00Z"}]}
]}],
"statistics": {"duration": 12.5}
}
EOF
hdf validate --type results /tmp/example-hdf-rhel9-results.json
cat > /tmp/example-hdf-postgres-results.json << 'EOF'
{
"baselines": [{"name": "PostgreSQL-STIG", "requirements": [
{"id": "SV-233512", "title": "Access control", "descriptions": [{"label": "default", "data": "check"}],
"impact": 0.5, "tags": {}, "results": [{"status": "passed", "codeDesc": "check", "startTime": "2026-03-30T00:00:00Z"}]}
]}],
"statistics": {"duration": 8.2}
}
EOF
hdf validate --type results /tmp/example-hdf-postgres-results.json
# --- Step 4: Build the evidence package ---
# --results is repeatable and supports globs
hdf evidence build \
--system /tmp/example-hdf-system.json \
--results /tmp/example-hdf-rhel9-results.json \
--results /tmp/example-hdf-postgres-results.json \
-o /tmp/example-hdf-evidence.json
# Or with a glob:
# hdf evidence build --system /tmp/example-hdf-system.json --results "/tmp/example-hdf-*-results.json" -o /tmp/example-hdf-evidence.json
# Or with positional args (shell-expanded):
# hdf evidence build --system /tmp/example-hdf-system.json /tmp/scans/*.json -o /tmp/example-hdf-evidence.json
# Link the evidence package to the plan
hdf evidence set /tmp/example-hdf-evidence.json --plan-ref example-hdf-plan.json
# --- Step 5: Verify checksums ---
hdf evidence verify /tmp/example-hdf-evidence.json --checksums-only
# --- Step 6: Verify completeness against the plan ---
hdf evidence verify /tmp/example-hdf-evidence.json
# Checks that every baseline in the plan has a corresponding results document.
# --- Other evidence commands ---
hdf evidence info /tmp/example-hdf-evidence.json
hdf evidence set /tmp/example-hdf-evidence.json --package-id "550e8400-e29b-41d4-a716-446655440000"
hdf evidence set /tmp/example-hdf-evidence.json --description "Quarterly ATO evidence bundle"
hdf validate --type evidence-package /tmp/example-hdf-evidence.jsonExpected:
- Each document validates against its schema at creation time.
- Plan has 2 assessments derived from system components.
- Evidence build accepts multiple
--resultsflags, globs, and positional args. evidence verify --checksums-only: all SHA-256 checksums match.evidence verify(default): completeness check reports missing baselines.evidence set --plan-ref: links evidence to the assessment plan.evidence info: displays package name, preparer, timestamp, systemRef, contents list with checksum status, and completeness summary.
12. Compliance Thresholds (CI/CD Gates)
Story: A CI pipeline enforces compliance regression detection.
# Generate a threshold from HDF results
hdf generate threshold hdf-schema/test/fixtures/minimal-v2.json -o /tmp/example-hdf-threshold.yaml
# View the generated threshold
cat /tmp/example-hdf-threshold.yaml
# Validate the same results against the threshold (should pass)
hdf validate threshold hdf-schema/test/fixtures/minimal-v2.json -T /tmp/example-hdf-threshold.yaml
# Generate with control IDs included
hdf generate threshold hdf-schema/test/fixtures/minimal-v2.json --include-controls
# Inline threshold validation (CI one-liner)
hdf validate threshold hdf-schema/test/fixtures/minimal-v2.json -I "{compliance.min: 40}"
# Inline threshold that should fail (compliance too high)
hdf validate threshold hdf-schema/test/fixtures/minimal-v2.json -I "{compliance.min: 90}" || echo "Expected failure"Expected:
- Generate produces YAML with compliance, passed, failed sections.
- Validate with -T: exit 0 when results meet threshold.
- --include-controls: adds control ID lists under each status/severity.
- Inline -I: parses
{key: value}format, exit 0 on pass, exit 1 on fail. - Round-trip: generate → validate against same file always passes.
13. Fetching Results from APIs
Story: A security engineer pulls findings from an API.
# Check fetch help
hdf fetch --helpExpected: Help text shows available API sources. (Actual API calls require credentials/endpoints.)