Skip to content

Policies#

A Buf policy is a YAML file that bundles lint, breaking, and plugins configuration so the same rules can apply across many workspaces. The pattern fits a central platform team that wants to define rules once and enforce them across every repository, instead of copy-pasting lint and breaking blocks into every buf.yaml.

Policies work in two modes:

  • Local: a buf.policy.yaml file referenced from each workspace’s buf.yaml. Available to every Buf CLI user.
  • Hosted: a policy published to the BSR and referenced by name from buf.yaml, optionally enforced at the instance, organization, or repository level. Available on Enterprise plans.

Policies require Buf CLI version 1.57.1 or later.

A policy file#

A policy file accepts a subset of the buf.yaml keys: lint, breaking, and plugins. The full key list lives in the buf.policy.yaml reference.

buf.policy.yaml
version: v2
lint:
  use:
    - STANDARD
    - TIMESTAMP_SUFFIX  # Provided by the plugin below.
breaking:
  use:
    - FILE
plugins:
  - plugin: plugin-timestamp-suffix
    options:
      timestamp_suffix: _time

The lint and breaking blocks behave the same way they do inside a buf.yaml. The plugins block declares custom Buf check plugins whose rules can be referenced from lint.use and breaking.use.

To turn off Buf’s built-in rules in a policy, set disable_builtin: true under lint or breaking. For the full reference, see buf.policy.yaml.

Use a local policy#

Reference one or more policy files from buf.yaml. Paths are relative to the buf.yaml:

buf.yaml
version: v2
policies:
  - policy: buf.policy.yaml
  # Multiple policies are allowed; paths are relative.
  # - policy: ../common/common.policy.yaml

buf lint and buf breaking then apply each referenced policy. Multiple policies don’t merge into a single combined config; each runs as its own check, and the resulting violations are combined into one report. A module’s own lint/breaking block in buf.yaml runs independently of any policy attached to the same workspace.

Publish a policy to the BSR#

Pushing a policy to the BSR makes it consumable by name from any workspace and enables instance-, organization-, and repository-level enforcement. Pushing requires an Enterprise instance.

Before pushing, prepare the policy file:

  1. Add a name field in the form <host>/<organization>/<policy-name>. The host is your BSR instance hostname.
  2. Replace any local plugin references with their published BSR names. Hosted policies can only reference plugins that are already published, so the BSR validates every plugin reference at push time and rejects the push if one isn’t published yet. Publish the plugin first; see Publishing a plugin.
buf.policy.yaml suitable for uploading to a BSR
 version: v2
+name: your-bsr-instance.example.com/acme/timestamp-policy
 lint:
   use:
     - STANDARD
     - TIMESTAMP_SUFFIX
 breaking:
   use:
     - FILE
 plugins:
-  - plugin: plugin-timestamp-suffix
+  - plugin: your-bsr-instance.example.com/acme/plugin-timestamp-suffix
     options:
       timestamp_suffix: _time

Push with buf policy push. On the first push, include --create and --create-visibility:

$ buf policy push buf.policy.yaml --create --create-visibility=public

Use a remote policy#

Reference the published policy by name in buf.yaml:

buf.yaml
 version: v2
 policies:
-  - policy: buf.policy.yaml
+  - policy: your-bsr-instance.example.com/acme/timestamp-policy

Pin the version and download the policy with buf policy update, which writes a policies: section into the workspace’s buf.lock alongside the existing module dependencies:

$ buf policy update

Subsequent buf lint and buf breaking runs read from buf.lock for the pinned policy.

Enforce policies on the BSR#

Beyond pull-style consumption from buf.yaml, the BSR can enforce a published policy at push time against the default label of matching repositories. This requires an Enterprise instance and a published policy.

The available scopes:

  • Instance: company-wide standards.
  • Organization: team-specific rules.
  • Repository: project-specific requirements.

A single repository can be subject to enforcement from any combination of these scopes; each enforcement runs as a separate check and the results are combined.

To configure enforcement:

  1. Open the Policy Enforcement settings on the scope you want (BSR instance admin panel, organization settings, or repository settings).
  2. Click Create Enforcement and select the policy (optionally pinned to a specific reference).
  3. Define a target. Targets identify the repositories the policy applies to in owner/module form, optionally followed by :label to scope to a specific label. Use * as a wildcard in either segment to match all repositories or all labels.
  4. Save.

When a commit fails policy enforcement on a push that would advance the default label, the BSR:

  • Records the failures with file path, line and column, error type, and message.
  • With the review flow enabled, marks the commit pending and waits for an approver. With review flow disabled, rejects the push outright with the check error.

To modify enforcement, return to the same scope’s Policy Enforcement panel, edit the policy or targets, and save.

When a commit fails policy checks#

  1. Read the error: open the commit in the BSR or the local CLI output.
  2. Fix the schema: update the .proto files to satisfy the rule, or open a review if the violation is intentional.
  3. Push: commit and push the fix.
  4. Verify: confirm the commit clears policy enforcement so labels can advance to it.