Policy Studio API and Rule Syntax

Policy Studio turns plain-English policy intent into K4 lattice rules: an author describes what they want (“block critical vulnerabilities in production unless a vendor VEX says not affected”), and the API parses that intent, generates lattice-compatible rules, and synthesizes test cases. This guide documents the Policy Studio API, the rule and lattice syntax, and the bundle and attestation formats.

Audience: policy authors and integrators building AI-assisted policy authoring on top of Stella Ops.

Implementation status: parse and generate are live; validate and compile are reserved and currently return 501 Not Implemented (see Current Runtime Status).

Overview

Policy Studio enables:

  1. Natural Language → Policy Intent: Parse human intent from plain English
  2. Intent → Lattice Rules: Generate K4 lattice-compatible rules
  3. Validation: Planned HTTP stage; currently returns 501 Not Implemented
  4. Test Synthesis: Auto-generate test cases for policy validation
  5. Compilation: Planned HTTP stage; currently returns 501 Not Implemented

Current Runtime Status

API Endpoints

Parse Natural Language

Convert natural language to structured policy intent.

POST /v1/advisory-ai/policy/studio/parse
Content-Type: application/json

{
  "input": "Block all critical vulnerabilities in production services unless they have a vendor VEX stating not affected",
  "defaultScope": "production"
}

Response:

{
  "intent": {
    "intentId": "intent-20251226-001",
    "intentType": "OverrideRule",
    "originalInput": "Block all critical vulnerabilities in production services unless they have a vendor VEX stating not affected",
    "conditions": [
      {
        "field": "severity",
        "operator": "equals",
        "value": "critical",
        "connector": "and"
      },
      {
        "field": "scope",
        "operator": "equals",
        "value": "production",
        "connector": "and"
      },
      {
        "field": "has_vex",
        "operator": "equals",
        "value": false,
        "connector": null
      }
    ],
    "actions": [
      {
        "actionType": "set_verdict",
        "parameters": {
          "verdict": "block",
          "reason": "Critical vulnerability without VEX exception"
        }
      }
    ],
    "scope": "production",
    "scopeId": null,
    "priority": 100,
    "confidence": 0.92,
    "alternatives": null,
    "clarifyingQuestions": null
  },
  "success": true,
  "modelId": "claude-sonnet-4-20250514",
  "parsedAt": "2025-12-26T10:30:00Z"
}

Clarifying Questions

When intent is ambiguous, the API returns clarifying questions:

{
  "intent": {
    "intentId": "intent-20251226-002",
    "intentType": "ThresholdRule",
    "confidence": 0.65,
    "clarifyingQuestions": [
      "Should this rule apply to all environments or just production?",
      "What should happen when the threshold is exceeded: block or escalate?"
    ],
    "alternatives": [
      { "...alternative interpretation 1..." },
      { "...alternative interpretation 2..." }
    ]
  },
  "success": true
}

Generate Rules

Convert policy intent to K4 lattice rules.

POST /v1/advisory-ai/policy/studio/generate
Content-Type: application/json

{
  "intentId": "intent-20251226-001"
}

Response:

{
  "rules": [
    {
      "ruleId": "rule-20251226-001",
      "name": "block-critical-no-vex",
      "description": "Block critical vulnerabilities in production without VEX exception",
      "latticeExpression": "Present ∧ ¬Mitigated ∧ severity=critical ∧ scope=production → Block",
      "conditions": [
        { "field": "severity", "operator": "equals", "value": "critical" },
        { "field": "scope", "operator": "equals", "value": "production" },
        { "field": "has_vex", "operator": "equals", "value": false }
      ],
      "disposition": "Block",
      "priority": 100,
      "scope": "production",
      "enabled": true
    }
  ],
  "success": true,
  "warnings": [],
  "intentId": "intent-20251226-001",
  "generatedAt": "2025-12-26T10:30:00Z"
}

Validate Rules

Check rules for conflicts and issues.

POST /v1/advisory-ai/policy/studio/validate
Content-Type: application/json

{
  "ruleIds": ["rule-20251226-001", "rule-20251226-002"],
  "existingRuleIds": ["rule-existing-001", "rule-existing-002"]
}

Response:

{
  "type": "https://stellaops.dev/problems/policy-studio/validate-not-implemented",
  "title": "Policy Studio stage not implemented",
  "status": 501,
  "detail": "Policy Studio validate is not wired to durable generated-rule storage yet. Parse and generate are available; validate remains unavailable in this runtime."
}

Compile Policy Bundle

Bundle validated rules into a signed policy package once durable generated-rule storage lands. The current runtime fails closed instead of returning a fabricated bundle.

POST /v1/advisory-ai/policy/studio/compile
Content-Type: application/json

{
  "ruleIds": ["rule-20251226-001"],
  "bundleName": "production-security-policy",
  "description": "Production bundle candidate"
}

Response:

{
  "type": "https://stellaops.dev/problems/policy-studio/compile-not-implemented",
  "title": "Policy Studio stage not implemented",
  "status": 501,
  "detail": "Policy Studio compile is not wired to durable generated-rule storage yet. Parse and generate are available; bundle compilation remains unavailable in this runtime."
}

Policy Intent Types

TypeDescriptionExample
OverrideRuleOverride default verdict“Block all critical CVEs”
EscalationRuleEscalate findings“Escalate CVSS ≥9.0 to security team”
ExceptionConditionBypass rules“Except internal-only services”
MergePrecedencePriority ordering“VEX takes precedence over CVSS”
ThresholdRuleAutomatic thresholds“Allow max 10 high-severity per service”
ScopeRestrictionScope limits“Only apply to production”

Rule Syntax

Lattice Expression Format

Rules use K4 lattice logic:

<atoms> → <disposition>

Security Atoms

AtomMeaning
PresentVulnerability is present in artifact
AppliesVulnerability applies to this context
ReachableVulnerable code is reachable
MitigatedMitigation exists (VEX, WAF, etc.)
FixedFix is available
MisattributedFalse positive

Operators

OperatorSymbolExample
ANDPresent ∧ Reachable
ORFixed ∨ Mitigated
NOT¬¬Mitigated
ImpliesPresent → Block

Dispositions

DispositionMeaning
BlockFail the build/gate
WarnWarning only
AllowPass with no action
ReviewRequire human review
EscalateEscalate to security team

Examples

# Block critical unmitigated vulnerabilities
Present ∧ Reachable ∧ ¬Mitigated ∧ severity=critical → Block

# Allow if vendor says not affected
Present ∧ Mitigated ∧ vex_status=not_affected → Allow

# Escalate CVSS ≥9.0
Present ∧ cvss_score>=9.0 → Escalate

# Warn on high severity with fix available
Present ∧ severity=high ∧ Fixed → Warn

Condition Fields

FieldTypeValues
severitystringcritical, high, medium, low, none
cvss_scorenumber0.0 - 10.0
reachablebooleantrue, false
has_vexbooleantrue, false
vex_statusstringnot_affected, affected, fixed, under_investigation
has_fixbooleantrue, false
fix_versionstringVersion string
scopestringproduction, staging, development
age_daysnumberDays since disclosure
exploit_availablebooleantrue, false
in_kevbooleanIn CISA KEV catalog

Condition Operators

OperatorDescriptionExample
equalsExact matchseverity equals critical
not_equalsNot equalscope not_equals development
greater_thanGreater thancvss_score greater_than 7.0
less_thanLess thanage_days less_than 30
greater_or_equalcvss_score greater_or_equal 9.0
less_or_equalcvss_score less_or_equal 3.9
containsString containscomponent contains lodash
inIn listseverity in [critical, high]
not_inNot in listscope not_in [development, test]

Test Case Format

Generated Test Cases

Policy Studio auto-generates test cases:

{
  "testCases": [
    {
      "testId": "test-001",
      "type": "positive",
      "description": "Critical unmitigated vulnerability should be blocked",
      "input": {
        "severity": "critical",
        "reachable": true,
        "has_vex": false,
        "scope": "production"
      },
      "expectedDisposition": "Block",
      "matchedRuleId": "rule-20251226-001"
    },
    {
      "testId": "test-002",
      "type": "negative",
      "description": "Critical vulnerability with VEX should not match block rule",
      "input": {
        "severity": "critical",
        "reachable": true,
        "has_vex": true,
        "vex_status": "not_affected",
        "scope": "production"
      },
      "expectedDisposition": "Allow",
      "shouldNotMatch": "rule-20251226-001"
    },
    {
      "testId": "test-003",
      "type": "boundary",
      "description": "CVSS exactly at threshold",
      "input": {
        "cvss_score": 9.0,
        "severity": "critical"
      },
      "expectedDisposition": "Escalate"
    },
    {
      "testId": "test-004",
      "type": "conflict",
      "description": "Input matching multiple conflicting rules",
      "input": {
        "severity": "high",
        "reachable": true,
        "has_fix": true
      },
      "possibleDispositions": ["Warn", "Block"],
      "conflictingRules": ["rule-001", "rule-002"]
    }
  ]
}

Test Types

TypePurposeAuto-Generated
positiveShould match rule and produce expected dispositionYes
negativeShould NOT match rule (boundary conditions)Yes
boundaryEdge cases at thresholdsYes
conflictTriggers multiple rulesYes
manualUser-defined custom casesNo

Natural Language Examples

Override Rules

Input: "Block all critical vulnerabilities"
→ Present ∧ severity=critical → Block

Input: "Allow vulnerabilities with VEX not_affected status"
→ Present ∧ vex_status=not_affected → Allow

Input: "Block exploitable vulnerabilities older than 30 days"
→ Present ∧ exploit_available=true ∧ age_days>30 → Block

Escalation Rules

Input: "Escalate anything in the KEV catalog to security team"
→ Present ∧ in_kev=true → Escalate

Input: "Escalate CVSS 9.0 or above"
→ Present ∧ cvss_score>=9.0 → Escalate

Exception Conditions

Input: "Except for development environments"
→ Adds: ∧ scope!=development to existing rules

Input: "Unless there's a VEX from the vendor"
→ Adds: ∧ ¬(has_vex=true ∧ vex_status=not_affected)

Threshold Rules

Input: "Allow maximum 5 high-severity vulnerabilities per service"
→ Creates threshold counter with Block when exceeded

CLI Commands

# Parse natural language
stella policy parse "Block all critical CVEs in production"

# Generate rules from intent
stella policy generate intent-20251226-001

# Validate rules
stella policy validate rules.yaml

# Run test cases
stella policy test rules.yaml --cases tests.yaml

# Compile bundle
stella policy compile rules.yaml \
  --name production-policy \
  --version 1.0.0 \
  --sign

# Apply policy
stella policy apply bundle-20251226-001.tar.gz

Configuration

policyStudio:
  # Maximum conditions per rule
  maxConditionsPerRule: 10

  # Auto-generate test cases
  autoGenerateTests: true

  # Test case types to generate
  testTypes:
    - positive
    - negative
    - boundary
    - conflict

  # Minimum test coverage
  minTestCoverage: 0.80

  # Require human approval for production policies
  requireApproval:
    production: true
    staging: false
    development: false

  # Number of approvers required
  requiredApprovers: 2

  # Sign compiled bundles
  signBundles: true

Policy Bundle Format

Compiled policy bundles are tar.gz archives:

production-policy-1.0.0.tar.gz
├── manifest.json          # Bundle metadata
├── rules/
│   ├── rule-001.yaml      # Individual rule files
│   ├── rule-002.yaml
│   └── ...
├── tests/
│   ├── test-001.yaml      # Test cases
│   └── ...
├── signature.dsse.json    # DSSE signature
└── checksums.sha256       # File checksums

Manifest Schema

{
  "bundleId": "bundle-20251226-001",
  "bundleName": "production-security-policy",
  "version": "1.0.0",
  "createdAt": "2025-12-26T10:30:00Z",
  "createdBy": "policy-studio",
  "rules": [
    {
      "ruleId": "rule-001",
      "name": "block-critical",
      "file": "rules/rule-001.yaml"
    }
  ],
  "testCount": 15,
  "coverage": 0.92,
  "signed": true,
  "signatureKeyId": "stellaops-policy-signer-2025"
}

Attestation Format

Policy drafts are attested using DSSE:

{
  "_type": "https://stellaops.org/attestation/policy-draft/v1",
  "bundleId": "bundle-20251226-001",
  "bundleName": "production-security-policy",
  "version": "1.0.0",
  "authority": "Validated",
  "rules": {
    "count": 5,
    "ruleIds": ["rule-001", "rule-002", "..."]
  },
  "validation": {
    "valid": true,
    "conflictCount": 0,
    "testsPassed": 15,
    "coverage": 0.92
  },
  "model": {
    "modelId": "claude-sonnet-4-20250514",
    "parseConfidence": 0.95
  },
  "createdAt": "2025-12-26T10:30:00Z"
}

Error Handling

Parse Errors

{
  "success": false,
  "error": "ambiguous_intent",
  "message": "Could not determine whether 'block' means verdict or action",
  "suggestions": [
    "Try: 'Set verdict to block for critical vulnerabilities'",
    "Try: 'Fail the build for critical vulnerabilities'"
  ]
}

Validation Errors

{
  "valid": false,
  "conflicts": [
    {
      "severity": "error",
      "description": "Rule A and Rule B have contradicting dispositions for the same conditions"
    }
  ]
}

Compilation Errors

{
  "success": false,
  "error": "compilation_failed",
  "message": "Cannot compile bundle with unresolved conflicts",
  "unresolvedConflicts": 2
}