Writing your first Policy
This guide will walk you through creating your first Sentrie policy step by step. For full syntax, validation, and how multiple tag lines are indexed, see the Policy metadata reference.
Basic Policy Structure
Section titled “Basic Policy Structure”A Sentrie policy file consists of exactly one namespace and at least one policy:
- Namespace: A container for related policies.
- Policy: A named collection of rules.
A policy consists of (in this order; see Policy metadata and Policies):
- Metadata (optional):
title,description,version, and one or moretagstring literals for humans and tooling—they do not affect evaluation. - Facts: Input data for the policy (before any
useif you import modules). - Rules: Individual decision logic.
- Exports: Rules that are exported to make them available for external evaluation.
Create a Policy Pack
Section titled “Create a Policy Pack”mkdir my-first-policy-packcd my-first-policy-packsentrie init my-first-policy-packDefine a Namespace
Section titled “Define a Namespace” namespace com/example/user_managementDefine a Policy
Section titled “Define a Policy”namespace com/example/user_management
policy user_access { -- policy content goes here }Define a Shape
Section titled “Define a Shape”namespace com/example/user_management
shape User { role: string status: string }
policy user_access { -- policy content goes here}Optional policy metadata
Section titled “Optional policy metadata”You can document the policy for registries, search, and teammates with metadata lines at the top of the policy body (still inside policy { ... }). Values are plain string literals only; they are not used when rules run. You can repeat tag with different keys. See Policy metadata for ordering with fact, use, and the rest of the body.
namespace com/example/user_management
shape User { role: string status: string}
policy user_access { -- policy content goes here title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
-- facts and rules go below}Add Facts
Section titled “Add Facts”namespace com/example/user_management
shape User { role: string status: string}
policy user_access { title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
fact user: User as currentUser fact context?: Context as ctx default {"environment": "production"}}Add your first rule
Section titled “Add your first rule”namespace com/example/user_management
shape User { role: string status: string}
policy user_access { title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
fact user: User as currentUser fact context?: Context as ctx default {"environment": "production"}
rule allow_admin = { yield user.role == "admin" }}Add your second rule
Section titled “Add your second rule”namespace com/example/user_management
shape User { role: string status: string}
policy user_access { title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
fact user: User as currentUser fact context?: Context as ctx default {"environment": "production"}
rule allow_admin = { yield user.role == "admin" }
rule allow_user = { yield user.role == "user" and user.status == "active" }}Composing Rules
Section titled “Composing Rules”Lets use the output of the allow_admin rule to update the allow_user rule.
namespace com/example/user_management
shape User { role: string status: string}
policy user_access { title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
fact user: User as currentUser fact context?: Context as ctx default {"environment": "production"}
rule allow_admin = { yield user.role == "admin" }
rule allow_user = { yield user.role == "user" and user.status == "active" yield allow_admin or user.role == "user" and user.status == "active" }}Export Rules
Section titled “Export Rules”namespace com/example/user_management
shape User { role: string status: string}
policy user_access { title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
fact user: User as currentUser fact context?: Context as ctx default {"environment": "production"}
rule allow_admin = { yield user.role == "admin" }
rule allow_user = { yield allow_admin or user.role == "user" and user.status == "active" }
export decision of allow_admin export decision of allow_user}Complete Example
Section titled “Complete Example”Here’s a complete policy that checks user access:
namespace com/example/user_management
shape User { role: string status: string}
policy user_access { title "User access" description "Admin and active-user access for the user management example." version "1.0.0" tag "domain" = "user_management" tag "tier" = "example"
fact user: User as currentUser fact context?: Context as ctx default {"environment": "production"}
rule allow_admin = { yield user.role == "admin" }
rule allow_user = { yield allow_admin or user.role == "user" and user.status == "active" }
export decision of allow_admin export decision of allow_user}Next Steps
Section titled “Next Steps”Now that you’ve written your first policy, learn how to run your policy to see it in action.