Skip to content

Latest commit

 

History

History
265 lines (203 loc) · 8.41 KB

policy-packs.md

File metadata and controls

265 lines (203 loc) · 8.41 KB
title Policy Packs
description Complete reference for Policy Pack manifests, Policies, target dimensions, assertions, linking, and messages.

A Policy Pack is a named, versioned collection of portable Policies. It defines governance, not architecture semantics. It contributes no Concepts, Contexts, Relations, or Rules.

Policy source evaluates facts of a Form. It never reads raw Terraform or OpenTofu values directly.

Complete example

policy_pack "network-baseline" {
  version = "0.1.0"
}

policy "subnet-has-network-context" {
  target {
    concept  = rf.concept.subnet
    rules    = [aws.rule.subnet]
    dialects = ["aws"]
  }

  assert = exists(
    contexts(rf.context.network, rf.concept.virtual-network)
  )

  message = "Each subnet must declare its virtual network."
}

Canonical Policy ID is network-baseline.policy.subnet-has-network-context.

policy_pack block

Property Contract
Placement Top level of a Policy Pack source root
Cardinality Exactly one per source root
Labels Exactly one required Pack name
Attributes version
Nested blocks None

Parameters

Name Type Required Default Constraints
Label Identifier Yes None Lowercase kebab case, 1-64 bytes
version Static string Yes None Exact MAJOR.MINOR.PATCH

A Policy Pack may contain zero Policies. Source files and directories do not create sub-packs or namespaces.

policy block

Property Contract
Placement Top level of a Policy Pack source root
Cardinality Zero or more
Labels Exactly one required Policy name
Attributes assert, message
Nested blocks Exactly one target

Parameters

Name Type Required Default Constraints
Label Identifier Yes None Lowercase kebab case, 1-64 bytes; unique in Pack
assert Policy assertion Yes None Must statically produce Boolean
message Static string Yes None Nonempty valid UTF-8, at most 1,024 bytes
target Block Yes None Exactly one, unlabeled

Message is attached to each confirmed violation. It is not a Policy assertion or runtime template and cannot interpolate target data. Native syntax still accepts the constant string-expression variants described under Expressions.

target block

target {
  concept  = rf.concept.subnet
  rules    = [aws.rule.subnet, google.rule.vpc-subnetwork]
  dialects = ["aws", "google"]
}
Property Contract
Placement Inside policy
Cardinality Exactly one
Labels Forbidden
Attributes concept, rules, dialects
Nested blocks None

Parameters

Name Type Required Default Constraints
concept Qualified Concept reference Conditionally No Concept filter At least concept or rules is required
rules Static nonempty list of qualified Rule references Conditionally No Rule filter 1-1,024 unique entries; at least concept or rules is required
dialects Static nonempty list of owner strings No No owner filter 1-1,024 unique valid Dialect owners; rf forbidden

Each dialects item is a static string expression, not a semantic reference. Direct quoted strings are canonical:

dialects = ["aws", "google"]

This is invalid:

dialects = [aws, google]

A constant expression is accepted but normalized by compilation:

dialects = [true ? "aws" : "google"]

Target intersection

Dimensions combine as logical AND. Entries inside one list combine as logical OR.

For the target above, a Representation must:

  1. have Concept rf.concept.subnet;
  2. have Rule aws.rule.subnet OR google.rule.vpc-subnetwork;
  3. have Rule owner aws OR google.

concept and rules may appear together. When rules is present, the linker rejects POLICY_TARGET_CONTRADICTORY if none of the listed Rules can satisfy optional concept and dialects filters. Without explicit rules, the linker does not infer contradiction from the absence of current implementations: a valid Concept target, with or without dialects, may select zero representations and have outcome no_target. dialects alone is invalid because it does not define a semantic target.

The target selects interpreted instances in the selected stage. A failed or indeterminate interpretation whose candidate Rule could satisfy the target is also selected for an indeterminate evaluation. An instance with no applicable Rule cannot satisfy a Rule, Concept, or Dialect target dimension. See Policy target selection.

Assertions

assert uses closed Policy expression grammar:

assert = exists(contexts(rf.context.network))
assert = length(relations(aws.relation.subscribes-to)) >= 1
assert = (
  exists(contexts(rf.context.runtime, rf.concept.kubernetes-cluster)) &&
  !exists(contributions(aws.rule.s3-bucket-versioning))
)

Accepted result types:

Expression Type
true, false Boolean
exists(query) Boolean
length(query) Number
! Boolean Boolean
Boolean && or || Boolean Boolean
Same-type Boolean or number ==, != Boolean
Number <, <=, >, >= number Boolean

Bare queries, traversals, strings, and arbitrary calls are invalid. See Expressions and Built-ins.

Portable source and linking

Policy Pack source stores qualified references but no semantic versions or digests. Before evaluation, Rootform links source against one validated Form's semantics:

Save a Form from plan JSON first. The saved plan pairs with the export and supplies reference traversals; the Policy Pack then links against the semantics recorded in that Form. Run these commands from the Rootform repository with the displayed Pack saved at policy-reference/pack.rf.hcl:

rootform run examples/playground/commerce-platform/head/plan.json \
  --plan-file examples/playground/commerce-platform/head/plan.tfplan \
  --no-serve -o analysis.json --color always
rootform compile policy-pack ./policy-reference \
  --semantics analysis.json --output network-baseline.json
Policy Pack compiled

Policy Pack    network-baseline@0.1.0
Form           analysis.json
Semantic pins  2
Destination    network-baseline.json

The first command writes analysis.json, a Form. The second prints the Pack identity, semantic-pin count, and output path. Exit 0 means linking succeeded; an unknown reference or incompatible semantic identity fails instead. Keep the plan inputs and Form internal: outputs omit sensitive values but still reveal topology and names.

Linking:

  1. resolves every owner, Concept, Context, Relation, and Rule;
  2. validates target intersections;
  3. derives exact owner kind, version, and semantic digest pins, including referenced Dialects' RF Vocabulary dependencies;
  4. writes deterministic compiled Policy Pack JSON.

A compiled pack can be evaluated offline without the Dialect sources that produced the Form. Its pins must exactly match the Form. Mismatch produces POLICY_SEMANTICS_MISMATCH; Rootform never relinks silently.

Unrelated semantic owners are not pinned.

See compile policy-pack for CLI flags and Evaluation for outcomes.

Zero targets

A valid Policy may select zero representations in one architecture. It is then no_target, not passed. A selected Policy without targets prevents an overall compliant result.

Rejected syntax

This Policy has only an owner filter:

policy_pack "invalid" {
  version = "0.1.0"
}

policy "dialect-only" {
  target {
    dialects = ["aws"]
  }

  assert  = true
  message = "This target is incomplete."
}

It produces POLICY_INVALID because concept or nonempty rules is required.

Unqualified semantic references such as concept.subnet produce POLICY_REFERENCE_UNQUALIFIED. Empty rules or dialects lists, duplicate entries, empty message, extra target block, or non-Boolean assertion also fail compilation.