paybondpaybond
Sign in

Org policy inheritance

Org-level base policies that tenants extend with overlays — shared spend rules across business units with tenant isolation.

Organizations can publish org base policies that tenant overlays extend. Each business unit keeps a local paybond.policy.yaml overlay while inheriting shared side-effecting tool definitions, evidence presets, and spend caps from the platform operator.

Tenant isolation remains absolute: overlays never merge policies from another org, and tenants cannot widen org allowed_tools or raise org spend caps.

Inheritance model

Org base policy (platform-published)
        +
Tenant overlay (paybond.policy.yaml)

Effective policy (per tenant, Gateway-resolved)

Gateway resolves the merged effective policy so tenants cannot bypass org constraints by editing local files alone. Kit middleware consumes the effective policy the same way as a flat v1 policy file.

Schema v2

Org base policies use version: 2 without an extends block:

version: 2
name: acme-agent-spend-v1
default_deny: true

tools:
  travel.book_hotel:
    side_effecting: true
    max_spend_cents: 20000
    evidence_preset: cost_and_completion

intent:
  policy_binding:
    template_id: completion_budget_v1
  allowed_tools:
    - travel.book_hotel

Tenant overlays declare what they extend and what they override:

version: 2
name: acme-travel-tenant-east
extends:
  org_policy_id: acme-agent-spend-v1
  org_id: org_acme_corp

default_deny: true

overrides:
  tools:
    travel.book_hotel:
      max_spend_cents: 15000  # stricter than org default
  intent:
    budget:
      max_spend_usd: 150

tools:
  acme.internal.approve_po:
    side_effecting: true
    evidence_preset: cost_and_completion

Merge rules (deterministic):

FieldRule
toolsUnion; tenant wins on spend/evidence conflicts; cannot remove org-required side-effecting tools
default_denyTenant may only make stricter (true wins)
intent.allowed_toolsIntersection when org defines an allowlist; tenant may narrow, not widen
evidence_presetTenant may swap only within org-approved catalog subset

For offline CI, add extends.base_policy pointing at a checked-in org base file. Production should use Gateway effective resolution.

Multi-team topology

A typical multi-team layout publishes one org base and attaches per-business-unit overlays. Each team keeps its own paybond.policy.yaml; Gateway resolves a distinct effective policy per tenant credential.

org_acme_corp
├── org base: acme-agent-spend-v1          (platform operator)
├── tenant travel-east                     (stricter hotel cap and east approval tool)
├── tenant travel-west                     (lower regional budget and concierge tool)
└── tenant procurement                     (procurement spend focus and vendor gate)
TeamOverlay focusEffective change vs org base
Travel EastRegional travel agentstravel.book_hotel cap 15000¢ (org 20000¢); allowed_tools narrowed to hotel and search and east approval
Travel WestSmaller regional budgettravel.book_hotel cap 10000¢; budget $75 (org $200); allowed_tools narrowed to hotel and search and west concierge
ProcurementRFQ workflowsprocurement.submit_rfq cap 75000¢ (org 100000¢); budget $175; allowed_tools narrowed to RFQ and search and vendor gate

The org base publishes a superset intent.allowed_tools list (all team-specific tools pre-approved by the platform operator). Each team overlay narrows that list to the tools its agents may execute — tenants cannot add tools outside the org allowlist.

Runnable reference: examples/enterprise-multi-team-policy/ (org base YAML and three team overlays and validate.sh).

Travel East overlay (excerpt)

version: 2
name: acme-travel-east
extends:
  org_policy_id: acme-agent-spend-v1
  org_id: org_acme_corp
  base_policy: ../../org-agent-spend-v1.yaml
default_deny: true

overrides:
  tools:
    travel.book_hotel:
      max_spend_cents: 15000
  intent:
    budget:
      currency: usd
      max_spend_usd: 150
    allowed_tools:
      - travel.book_hotel
      - search.web
      - acme.east.approve_travel

tools:
  acme.east.approve_travel:
    side_effecting: true
    evidence_preset: cost_and_completion

Procurement and Travel West follow the same extends shape with different overrides and tenant-only tools blocks.

Gateway resolution behavior

Gateway is authoritative for effective policy in production. Tenant overlays submitted at bind time or via POST /v1/org-policies/{policy_id}/effective are merged server-side against the latest org base head — local file edits alone cannot bypass org constraints.

Tenant cannot widen org allowlist. If the org base defines intent.allowed_tools, a tenant overlay may only narrow the list (intersection). Adding a tool outside the org allowlist fails merge:

# ❌ Rejected at merge — widens org allowlist
overrides:
  intent:
    allowed_tools:
      - travel.book_hotel
      - payments.wire   # not in org base

Gateway and Kit offline merge return policy.cannot_widen_allowed_tools for this case.

Tenant cannot raise org spend caps. Overrides that increase max_spend_cents or intent.budget.max_spend_usd above the org base are rejected with policy.cannot_raise_spend_cap / policy.cannot_raise_budget_cap.

Tenant cannot disable org-required side-effecting tools. Setting side_effecting: false on an org-mandated tool fails with policy.cannot_disable_org_side_effecting_tool.

Org tools remain in the effective registry. Merge unions org and tenant tools; narrowing allowed_tools restricts which registered tools may execute under default_deny, but org-defined tool entries stay in the merged document.

Poll-friendly digest checks: pass ?digest=<sha256:...> to POST /v1/org-policies/{policy_id}/effective to receive { unchanged: true, ... } when the merged effective policy has not changed since the last bind.

CLI workflow

Platform operator: scaffold org base

paybond policy init-org \
  --policy-id acme-agent-spend-v1 \
  --out org-agent-spend-v1.yaml \
  --operation travel.book_hotel \
  --evidence-preset cost_and_completion \
  --max-spend-cents 20000

Review the file, then publish via Gateway (requires platform operator credentials or PAYBOND_ORG_POLICY_PUBLISH_SECRET):

curl -X PUT \
  "https://api.paybond.ai/v1/admin/org-policies/acme-agent-spend-v1?org_id=org_acme_corp" \
  -H "Authorization: Bearer $PAYBOND_ORG_POLICY_PUBLISH_SECRET" \
  -H "Content-Type: application/json" \
  --data-binary @org-agent-spend-v1.json

See Gateway API — org policy inheritance.

Tenant: scaffold overlay

paybond policy extend \
  --extends org_acme_corp/acme-agent-spend-v1 \
  --out paybond.policy.yaml

Optional tenant-only tool:

paybond policy extend \
  --extends org_acme_corp/acme-agent-spend-v1 \
  --operation acme.internal.approve_po \
  --evidence-preset cost_and_completion \
  --out paybond.policy.yaml

For local merge in CI, pin the org base file:

paybond policy extend \
  --extends org_acme_corp/acme-agent-spend-v1 \
  --base-policy ./org-agent-spend-v1.yaml \
  --out paybond.policy.yaml

Validate merged policy (server)

paybond login
paybond policy validate-tools \
  --file paybond.policy.yaml \
  --remote \
  --resolve-inheritance \
  --format json

The response includes effective_policy_digest and merge_report when inheritance resolves successfully.

CI validation

Validate effective merged policies before deploy — not just overlay syntax.

Offline gate (no secrets)

Pin extends.base_policy in each overlay to a checked-in org base file. paybond policy validate-tools --local-only loads the overlay, merges via base_policy, and validates the resulting v1 effective document:

cd examples/enterprise-multi-team-policy

paybond policy validate-tools \
  --file teams/travel-east/paybond.policy.yaml \
  --local-only --format json

paybond policy validate-tools \
  --file teams/procurement/paybond.policy.yaml \
  --local-only --format json

# Or all teams:
./validate.sh

Use --strict (or PAYBOND_POLICY_STRICT=1) when the effective policy should declare every side-effecting tool in intent.allowed_tools — typical for flat v1 policies or overlays that inherit the full org allowlist without narrowing. When a team narrows allowed_tools, org side-effecting tools remain in the merged tools registry (see Gateway resolution behavior); use non-strict local validation in that case and rely on middleware default_deny and narrowed allowed_tools at runtime.

GitHub Actions pattern (monorepo kit job):

- name: Validate multi-team overlays
  run: |
    cd examples/enterprise-multi-team-policy
    chmod +x validate.sh
    ./validate.sh

The kit test suite also locks merge behavior: kit/ts/tests/policy/enterprise-multi-team.test.ts.

Sandbox registry gate (with credentials)

When the org base is published to Gateway, validate each team overlay against the live org head:

export PAYBOND_API_KEY=pb_test_sandbox_...
paybond policy validate-tools \
  --file teams/travel-east/paybond.policy.yaml \
  --remote --resolve-inheritance --format json

--resolve-inheritance requires remote mode. The response includes effective_policy_digest, merge_report, and Harbor registry checks (template_head_mismatch, etc.).

Pre-commit

paybond policy validate-tools --file paybond.policy.yaml --local-only

For tenant overlays in a multi-team repo, run validation per overlay path in CI — see examples/enterprise-multi-team-policy/validate.sh.

Kit API

TypeScript:

import { PaybondPolicy } from "@paybond/kit/policy";

const { policy, report, effectivePolicyDigest } = await PaybondPolicy.loadEffective({
  overlay: "./paybond.policy.yaml",
  gateway: paybond.harbor,
});
const registry = policy.toToolRegistry();

Offline merge (best-effort CI):

const { policy } = await PaybondPolicy.mergeLocal({
  base: "./org-agent-spend-v1.yaml",
  overlay: "./paybond.policy.yaml",
});

Python parity:

from paybond_kit.policy import PaybondPolicy, resolve_policy_effective_remote

result = await resolve_policy_effective_remote(overlay_doc, gateway_client)
policy = PaybondPolicy.from_document(result.effective_policy)

Examples

Multi-team reference (org base and three business-unit overlays):

Merge unit fixtures under kit/policy/examples/:

  • org-base-acme-agent-spend-v1.json — org base
  • tenant-overlay-acme-travel-east.json — tenant overlay with overrides