Files
git.stella-ops.org/docs/modules/policy/guides/policy-import-export.md
2026-01-24 00:12:43 +02:00

6.2 KiB

Policy Import/Export Guide

This guide covers bidirectional policy exchange between Stella's native C# engine and OPA/Rego.

Overview

Stella supports two policy formats:

  • PolicyPack v2 (JSON): Canonical format with typed gates, environment overrides, and remediation hints.
  • OPA/Rego: Standard policy-as-code format for interoperability with OPA-based toolchains.

The C# gate engine remains primary. Rego is an export target for teams using OPA, and an import source for adopting external policies.

Formats

PolicyPack v2 (JSON)

Schema: policy.stellaops.io/v2

Structure:

{
  "apiVersion": "policy.stellaops.io/v2",
  "kind": "PolicyPack",
  "metadata": { "name": "...", "version": "1.0.0" },
  "spec": {
    "settings": { "defaultAction": "block", "deterministicMode": true },
    "gates": [...],
    "rules": [...]
  }
}

Key features:

  • Per-environment configuration overrides (production/staging/development thresholds)
  • Structured remediation hints with CLI command templates
  • Deterministic evaluation mode
  • SHA-256 content digest for integrity

OPA/Rego

Generated or imported Rego follows the deny-by-default pattern:

package stella.release

import rego.v1

default allow := false

deny contains msg if {
    not input.dsse.verified
    msg := "DSSE signature missing"
}

allow if { count(deny) == 0 }

remediation contains hint if {
    some msg in deny
    msg == "DSSE signature missing"
    hint := {"code": "DSSE_MISS", "fix": "...", "severity": "critical"}
}

CLI Commands

Export

Export a policy to JSON or Rego:

# Export to Rego
stella policy export --file policy.json --format rego --output-file release.rego

# Export with environment-specific thresholds
stella policy export --file policy.json --format rego --environment production

# Export without remediation hints
stella policy export --file policy.json --format json --include-remediation false

# Export to stdout (pipe-friendly)
stella policy export --file policy.json --format rego | opa check -

Import

Import a policy from JSON or Rego:

# Import and validate a JSON policy
stella policy import --file production-baseline.json

# Import with validation only (no persist)
stella policy import --file external-policy.rego --validate-only

# Dry-run to preview changes
stella policy import --file new-rules.json --dry-run

# Force format detection
stella policy import --file rules.txt --format rego

Validate

Validate a policy file:

# Basic validation
stella policy validate --file policy.json

# Strict mode (warnings become errors)
stella policy validate --file policy.json --strict

# JSON output for CI integration
stella policy validate --file policy.json --output json

Exit codes: 0 = valid, 1 = warnings, 2 = errors.

Evaluate

Evaluate a policy against evidence:

# Evaluate with table output
stella policy evaluate --policy baseline.json --input evidence.json

# With environment override
stella policy evaluate --policy baseline.json --input evidence.json --environment staging

# JSON output for programmatic use
stella policy evaluate --policy baseline.json --input evidence.json --output json

# CI mode (GitHub Actions annotations)
stella policy evaluate --policy baseline.json --input evidence.json --output ci

Exit codes: 0 = allow, 1 = warn, 2 = block.

Evidence Input Format

The evaluation input follows the canonical evidence JSON schema:

{
  "environment": "production",
  "subject": {
    "imageDigest": "sha256:abc...",
    "purl": "pkg:docker/myapp@1.0.0",
    "tags": ["env:prod"]
  },
  "dsse": { "verified": true, "signers": ["ca://fulcio/..."] },
  "rekor": { "verified": true, "logID": "...", "integratedTime": 1737480000 },
  "sbom": { "format": "cyclonedx-1.6", "canonicalDigest": "sha256:..." },
  "freshness": { "tstVerified": true, "timestamp": "2026-01-22T10:00:00Z", "maxAgeHours": 24 },
  "cvss": { "score": 7.5, "version": "3.1" },
  "reachability": { "status": "confirmed", "confidence": 0.85 },
  "confidence": 0.82
}

Remediation Hints

When a gate blocks, the CLI displays actionable fix suggestions:

Decision: BLOCK

Gate        Type                  Result  Reason
signature   SignatureRequiredGate  FAIL    Required signature missing
sbom        SbomPresenceGate      PASS    passed

Remediation:
  SIG_MISS: Required signature missing
    - Sign attestation with DSSE.
      $ stella attest attach --sign --image sha256:abc...
    - Anchor attestation in Rekor.
      $ stella attest attach --rekor --image sha256:abc...

Rego Import Behavior

When importing Rego files, the system:

  1. Parses deny rules and maps known patterns to native gates (CVSS comparisons, boolean checks).
  2. Extracts remediation rules into structured hints.
  3. Unknown patterns are preserved and evaluated via the embedded OPA evaluator.
  4. Validation reports which rules mapped natively vs. remain OPA-evaluated.

Determinism

All evaluations are deterministic:

  • Same policy + same input = same output (hash-verifiable)
  • No time-dependent logic in deterministic mode
  • outputDigest in evaluation results enables replay verification

API Endpoints

The Platform API exposes policy interop at /api/v1/policy/interop:

Method Path Description
POST /export Export policy to format
POST /import Import policy from format
POST /validate Validate policy document
POST /evaluate Evaluate policy against input
GET /formats List supported formats

Gate Types

Supported gate types with Rego translation:

Gate Type Rego Pattern Remediation Code
CvssThresholdGate input.cvss.score >= threshold CVSS_EXCEED
SignatureRequiredGate not input.dsse.verified SIG_MISS
EvidenceFreshnessGate not input.freshness.tstVerified FRESH_EXPIRED
SbomPresenceGate not input.sbom.canonicalDigest SBOM_MISS
MinimumConfidenceGate input.confidence < threshold CONF_LOW
UnknownsBudgetGate input.unknownsRatio > threshold UNK_EXCEED
ReachabilityRequirementGate not input.reachability.status REACH_REQUIRED