Reference repos.yaml

repos.yaml

Every key of teriac server's repos.yaml: repos and their switches, project rules, permissions, approvals, policies, channels, people, drift schedules and dashboard users.

repos.yaml is teriac server's rule file. It lives on the server (TERIAC_REPOS_CONFIG, default /data/repos.yaml) or in the Helm chart's repos value, so a pull request can't change it. teriac checks it at start-up and refuses to start, with the line at fault, if anything is wrong.

A complete example

policies:                                  # every repo
  mode: audit
  override: [team:security]
  rules:
    - { name: no-public-s3, resource: aws_s3_bucket_acl, deny_if: { attribute: acl, in: [public-read, public-read-write] } }

channels:
  infra-alerts: { type: slack, channel: "#infra-drift", token_env: TERIAC_SLACK_TOKEN }

people:
  - { name: Bob Martins, github: bob-m, slack: U04BOBM }

dashboard:
  users:
    - { username: alice, password_hash: "scrypt$…", role: admin }

repos:
  - id: github.com/acme/infra
    require_apply_project: true
    apply_requirements: [mergeable]
    two_person_rule: true
    plan_drafts: false
    comment_mode: update
    policies: { mode: enforce }            # stricter than the server-wide audit
    projects:
      - match: prod/**
        permissions:
          apply: [team:platform-admins]
          apply_destroy: [admin]
          force_unlock: []
        approvals:
          - { from: team:platform-admins, count: 2 }
      - match: "**"
        approvals: [{ from: write, count: 1 }]
    drift:
      - { name: prod-nightly, projects: ["prod/**"], schedule: "0 6 * * 1-5", timezone: Europe/Berlin, notify: [infra-alerts] }

  - id: github.com/acme/*                  # every other acme repo, with defaults

Top level

Key Type
repos list Repos teriac may act on, with their rules. Required, unless TERIAC_REPO_ALLOWLIST is set
policies object Policy checks for every repo
channels map Named chat channels for drift alerts
people list Code identities → chat identities
dashboard.users list Dashboard username/password sign-in
risk object Risk score settings.
freezes object Change freezes.
protected object Protected resources.
secret_scan object Leaked-secret scan.
break_glass object Emergency access.
summary object Weekly chat summary.

repos[]

Key Default
id required One repo (github.com/acme/infra) or a glob (github.com/acme/*). A repo uses only the first entry that matches; entries don't combine, so list exact repos before globs and give each everything it needs
projects [] Project rules, see below
apply_requirements [] approved, mergeable, undiverged
require_apply_project false Refuse a bare teriac apply
two_person_rule false The PR author can't apply
autoplan true Plan on every push
plan_drafts false Also autoplan draft PRs
allow_targets true Allow -t targeted plans
allow_extra_args false Allow teriac plan -- -var=x
allow_state_changes true Allow import, taint, untaint, state rm, state mv, force-unlock
allow_repo_config true Read the repo's teriac.yaml
allow_repo_schedules true Read drift schedules from teriac.yaml
ack_reaction server setting Reaction on a picked-up command, or none
progress_reply server setting Spinning "Running…" reply
comment_mode server setting new or update
policies Extra rules, or a stricter mode, for this repo
drift [] Drift schedules. Needs an exact id, not a glob
reapprove_on_change true A code change needs a fresh approval.
keep_approval_on_rebase false A rebase that doesn't change the PR's code keeps approvals.
stale_base warn off, warn or block when the base branch changed a project's files.
verify_plan true Apply only the exact plan file that was reviewed.
risk, freezes, protected, secret_scan, policies This repo's safety settings, combined with the server-wide ones (see safety settings).

repos[].projects[]

Key
match required Glob on the project's folder or name. The first rule that matches applies
permissions Map of permission → principals, see below
approvals List of { from: <principal>, count: <n> }; all must be met
apply_requirements approved, mergeable, undiverged
two_person_rule The PR author can't apply this project

Permissions

Key Covers Default Unset? Uses
plan plans, validate, providers, fmt, state list write
apply applies write
apply_destroy applies that delete or replace maintain
unlock releasing another PR's lock maintain
state_read state show, show, output write plan
state_write import, taint, untaint write apply
state_remove state rm, state mv, force-unlock maintain apply_destroy

Single commands: state_list, state_show, show, output, validate, providers, fmt, import, taint, untaint, state_rm, state_mv, force_unlock. Unset uses its group; [] means nobody.

Principals

read, write, maintain, admin (at least that repo role), team:<name> or team:<org>/<name>, user:<login>, codeowners, anyone.

policies

Key
mode off, audit, enforce A repo can only make it stricter
override principals Who may teriac apply -p <project> --override
rules[] name, resource, actions, projects, deny_if, require, message
commands[] name, run (a list; {plan_json} is replaced with the plan file), severity
builtin [security] Turn on the built-in AWS security rules.
disable rule names Turn single built-in rules off.

Rules and commands take severity: low, medium, high (default) or critical.

Conditions: { attribute: <dot.path>, equals | in | matches | exists: … }. See Policy checks.

channels

channels:
  <name>: { type: slack | teams | discord | googlechat | webhook, … }
Key
type slack, teams, discord, googlechat or webhook
channel Slack channel ID or name (with token_env)
token_env Env var holding a Slack bot token
webhook_url_env Env var holding a webhook URL. Required for every type but Slack-with-token

people[]

Key
name Display name
github GitHub login
emails Commit emails
slack Slack member ID, e.g. U0123ABC
teams Teams UPN, e.g. alice@acme.onmicrosoft.com
discord Discord user ID

repos[].drift[]

Key Default
name Label
projects required Names, folders or globs
branch default branch
schedule required Cron
timezone UTC IANA name
notify required Channel names
notify_when changed or always
include_pending true Report merged-but-unapplied changes
fix_pr false Open a PR that updates code to match what's running; needs Contents: write.

Safety settings

New in 0.2.0.

risk, freezes, protected, secret_scan and policies go at the top of repos.yaml (every repo) or in a repo entry (that repo only). Lists add up (freezes, protected, policies.rules, risk.stateful_types); secret_scan, policies.mode and risk.size_limits can only get stricter; anything else set on a repo wins for that repo. break_glass and summary are server-wide only. Details and examples are in Risk and guardrails and Emergency access and reports.

Key Fields
risk production (globs), stateful_types, size_limits: { medium, high }, extra_approval: { medium | high | critical: { from, count } }, each applying at its level and above
freezes A list of windows: name, projects, schedule + hours (1 to 336) or from + to, timezone (default UTC), override (default nobody)
protected A list: resources (address globs, match inside modules), projects, override (default nobody)
secret_scan mode: redact (default), fail, off; patterns[]: name, regex
break_glass grantors (admin, user:<name or email>, group:<SSO group>), max_hours (default 4, at most 72), notify
summary schedule (cron), timezone, notify, days (default 7, 1 to 90)

dashboard.users[]

Key
username required
password_hash required, from node packages/server/src/hash-password.ts (starts with scrypt$)
role admin or viewer
name Display name, optional