Skip to content

Configuration Reference

Full reference for governance.yaml.

Config file resolution

Files are checked in order (first match wins):

  1. $PI_GOV_GOVERNANCE_CONFIG environment variable
  2. .pi/governance.yaml in the current working directory
  3. ~/.pi/agent/governance.yaml
  4. Built-in defaults

When loaded from a file, pi-governance watches for changes and automatically reloads. See Config hot-reload.

Full schema

yaml
auth:
  provider: env | local | oidc # Identity provider
  env:
    user_var: PI_GOV_USER # Env var for username (default)
    role_var: PI_GOV_ROLE # Env var for role (default)
    org_unit_var: PI_GOV_ORG_UNIT # Env var for org unit (default)
  local:
    users_file: ./users.yaml # Path to local users YAML

policy:
  engine: yaml | oso # Policy engine type (default: yaml)
  yaml:
    rules_file: ./governance-rules.yaml # Path to role definitions
  oso:
    polar_files: # Paths to Polar policy files
      - ./policies/base.polar
      - ./policies/tools.polar

templates:
  directory: ./templates/ # Custom prompt template directory
  default: project-lead # Fallback template name

hitl:
  default_mode: autonomous | supervised | dry_run # Default: supervised
  approval_channel: cli | webhook # Default: cli
  timeout_seconds: 300 # Range: 10-3600 (default: 300)
  webhook:
    url: ${GOVERNANCE_WEBHOOK_URL} # Required if approval_channel is webhook

audit:
  sinks: # One or more audit destinations
    - type: jsonl
      path: ~/.pi/agent/audit.jsonl # Default JSONL sink
    - type: webhook
      url: ${AUDIT_WEBHOOK_URL}
    - type: postgres
      connection: ${AUDIT_DB_URL}

dlp: # Data Loss Prevention (optional)
  enabled: false # Off by default
  mode: audit # Global: audit | mask | block
  on_input: block # Override for inputs
  on_output: mask # Override for outputs
  masking:
    strategy: partial # partial | full | hash
    show_chars: 4
    placeholder: '***'
  severity_threshold: low # low | medium | high | critical
  built_in:
    secrets: true
    pii: true
  custom_patterns:
    - name: internal_key
      pattern: 'grwnd_[a-zA-Z0-9]{32}'
      severity: critical
      action: block # Per-pattern override
  allowlist:
    - pattern: 'EXAMPLE_KEY_.*'
    - pattern: '127\.0\.0\.1'
  role_overrides:
    admin:
      enabled: false # Admin skips DLP
    analyst:
      mode: block # Strict for analysts

org_units: # Per-org-unit overrides (optional)
  compliance:
    hitl:
      default_mode: dry_run
    policy:
      extra_polar: ./policies/compliance.polar
      extra_rules: ./rules/compliance.yaml

Section reference

auth

FieldTypeDefaultDescription
providerstringenvIdentity provider type
env.user_varstringPI_GOV_USEREnv var for user ID
env.role_varstringPI_GOV_ROLEEnv var for role
env.org_unit_varstringPI_GOV_ORG_UNITEnv var for org unit
local.users_filestring./users.yamlPath to local users file

policy

FieldTypeDefaultDescription
enginestringyamlyaml or oso
yaml.rules_filestring./governance-rules.yamlPath to YAML role definitions
oso.polar_filesstring[][base.polar, tools.polar]Paths to Polar policy files

templates

FieldTypeDefaultDescription
directorystring./templates/Custom template directory
defaultstringproject-leadFallback template name

hitl

FieldTypeDefaultDescription
default_modestringsupervisedExecution mode
approval_channelstringclicli or webhook
timeout_secondsnumber300Approval timeout (10-3600)
webhook.urlstringWebhook URL for remote approvals

audit

FieldTypeDefaultDescription
sinksarray[{type: jsonl, path: ...}]Array of sink configs
sinks[].typestringjsonl, webhook, or postgres
sinks[].pathstring~/.pi/agent/audit.jsonlFile path (jsonl only)
sinks[].urlstringEndpoint (webhook only)
sinks[].connectionstringDSN (postgres only)

dlp

FieldTypeDefaultDescription
enabledbooleanfalseEnable DLP scanning
modestringauditaudit, mask, or block
on_inputstringOverride action for tool inputs
on_outputstringOverride action for tool outputs
masking.strategystringpartialpartial, full, or hash
masking.show_charsnumber4Chars to show (partial only)
masking.placeholderstring***Replacement text
severity_thresholdstringlowMinimum severity to act on
built_in.secretsbooleantrueEnable built-in secret patterns
built_in.piibooleantrueEnable built-in PII patterns
custom_patternsarray[]Additional regex patterns
custom_patterns[].namestringPattern identifier
custom_patterns[].patternstringRegex pattern string
custom_patterns[].severitystringlow/medium/high/critical
custom_patterns[].actionstringPer-pattern action override
allowlistarray[]Patterns to exclude from detection
role_overridesobjectPer-role DLP config overrides

Environment variable substitution

Any string value containing ${VAR_NAME} is resolved from environment variables at load time. If the variable is not set, it resolves to an empty string.

yaml
audit:
  sinks:
    - type: webhook
      url: ${AUDIT_WEBHOOK_URL} # Resolved from process.env

Config hot-reload

When config is loaded from a file (not built-in defaults), pi-governance watches the file for changes using fs.watch(). On change:

  1. The file is re-read and parsed
  2. The new config is validated against the Typebox schema
  3. If valid, the policy engine and bash classifier are recreated
  4. A config_reloaded audit event is logged
  5. If invalid, the current config is kept and a warning is shown

Changes are debounced (500ms) to avoid rapid reloads. The watcher is cleaned up on session shutdown.

Validation

All config files are validated against a Typebox schema at load time. Invalid configs throw a ConfigValidationError with detailed field-level messages:

Invalid governance config at .pi/governance.yaml:
  /policy/engine: Expected "yaml" | "oso"
  /hitl/timeout_seconds: Expected number >= 10

Released under the Apache-2.0 License.