Files
git.stella-ops.org/docs/modules/policy/dsl-grammar-specification.md

6.3 KiB

Stella Policy DSL Grammar Specification

Version: stella-dsl@1.0
Status: Implemented
Last Updated: 2026-02-15

Overview

The Stella Policy DSL is a domain-specific language for defining release policies that control software deployment decisions. Policies are evaluated against signal contexts to produce deterministic verdicts.

File Extension

Policy files use the .stella extension.

Lexical Structure

Comments

// Single-line comment

/*
 * Multi-line comment
 */

Keywords

Reserved keywords (case-sensitive):

Keyword Description
policy Policy declaration
syntax Syntax version declaration
metadata Policy metadata block
settings Policy settings block
profile Profile declaration
rule Rule declaration
when Rule condition
then Rule action (condition true)
else Rule action (condition false)
and Logical AND
or Logical OR
not Logical NOT
true Boolean true
false Boolean false
null Null literal
in Membership operator
map Map literal
env Environment binding

Operators

Operator Description
== Equality
!= Inequality
< Less than
<= Less than or equal
> Greater than
>= Greater than or equal
:= Definition
=> Arrow (lambda/map)
. Member access
, Separator
: Key-value separator
= Assignment

Literals

Strings

"hello world"
"escaped \"quotes\""

Numbers

42
3.14
-1
0.5

Booleans

true
false

Arrays

[1, 2, 3]
["a", "b", "c"]

Identifiers

Identifiers start with a letter or underscore, followed by letters, digits, or underscores:

identifier
_private
signal_name
cvss_score

Grammar (EBNF)

document        = policy-header "{" body "}" ;

policy-header   = "policy" string-literal "syntax" string-literal ;

body            = { metadata-block | settings-block | profile | rule } ;

metadata-block  = "metadata" "{" { key-value } "}" ;

settings-block  = "settings" "{" { key-value } "}" ;

key-value       = identifier ":" literal ;

profile         = "profile" identifier "{" { profile-item } "}" ;

profile-item    = map-item | env-item | scalar-item ;

map-item        = "map" identifier "=>" expression ;

env-item        = "env" identifier "=>" string-literal ;

scalar-item     = identifier ":=" expression ;

rule            = "rule" identifier [ "(" priority ")" ] "{" rule-body "}" ;

priority        = number-literal ;

rule-body       = when-clause then-clause [ else-clause ] ;

when-clause     = "when" expression ;

then-clause     = "then" "{" { action } "}" ;

else-clause     = "else" "{" { action } "}" ;

action          = action-name [ "(" { argument } ")" ] ;

action-name     = identifier ;

argument        = expression | key-value ;

expression      = or-expression ;

or-expression   = and-expression { "or" and-expression } ;

and-expression  = unary-expression { "and" unary-expression } ;

unary-expression = [ "not" ] primary-expression ;

primary-expression = literal
                   | identifier
                   | member-access
                   | "(" expression ")"
                   | comparison ;

comparison      = primary-expression comparison-op primary-expression ;

comparison-op   = "==" | "!=" | "<" | "<=" | ">" | ">=" | "in" ;

member-access   = identifier { "." identifier } ;

literal         = string-literal
                | number-literal
                | boolean-literal
                | array-literal
                | null-literal ;

string-literal  = '"' { character } '"' ;

number-literal  = [ "-" | "+" ] digit { digit } [ "." digit { digit } ] ;

boolean-literal = "true" | "false" ;

array-literal   = "[" [ expression { "," expression } ] "]" ;

null-literal    = "null" ;

Example Policy

policy "Production Release Policy" syntax "stella-dsl@1" {
    metadata {
        author: "security-team@example.com"
        version: "1.2.0"
        description: "Governs production releases"
    }
    
    settings {
        default_action: "block"
        audit_mode: false
    }
    
    profile production {
        env target => "prod"
        map severity_threshold := 7.0
    }
    
    rule critical_cve_block (100) {
        when cvss.score >= 9.0 and cve.reachable == true
        then {
            block("Critical CVE is reachable")
            notify("security-oncall")
        }
    }
    
    rule high_cve_warn (50) {
        when cvss.score >= 7.0 and cvss.score < 9.0
        then {
            warn("High severity CVE detected")
        }
        else {
            allow()
        }
    }
    
    rule sbom_required (80) {
        when not sbom.present
        then {
            block("SBOM attestation required")
        }
    }
}

Signal Context

Policies are evaluated against a signal context containing runtime values:

Signal Type Description
cvss.score number CVSS score of vulnerability
cve.reachable boolean Whether CVE is reachable
cve.id string CVE identifier
sbom.present boolean SBOM attestation exists
sbom.format string SBOM format (cyclonedx, spdx)
artifact.digest string Artifact content digest
artifact.tag string Container image tag
environment string Target environment
attestation.signed boolean Has signed attestation

Compilation

The DSL compiles to a content-addressed IR (Intermediate Representation):

  1. Tokenize: Source → Token stream
  2. Parse: Tokens → AST
  3. Compile: AST → PolicyIrDocument
  4. Serialize: IR → Canonical JSON
  5. Hash: JSON → SHA-256 checksum

The checksum provides deterministic policy identity for audit and replay.

CLI Commands

# Lint a policy file
stella policy lint policy.stella

# Compile to IR JSON
stella policy compile policy.stella --output policy.ir.json

# Get deterministic checksum
stella policy compile policy.stella --checksum-only

# Simulate with signals
stella policy simulate policy.stella --signals context.json

See Also