Skip to content

Documentation

The short version lives here. Reference material — the policy engine, the threat model, DataHub integration — is in the repository, next to the code it describes.

Before you start

What you need

Requirements
Python3.11 or later, managed by uv
uvThe only hard prerequisite — the plugin's hook shim uses it
Claude Code2.1.x
DataHubOSS/Core. datahub docker quickstart needs ~8 GB RAM and 13 GB disk
OSmacOS or Linux

Step 1

Install the plugin

/plugin marketplace add AmirmLotfy/zence
/plugin install zence@zence
You are prompted for your DataHub URL and token at enable time. The token goes to your system keychain, never to a file.

Step 2

Describe the boundary

zence init --client "Northstar Commerce" \
           --domain "urn:li:domain:northstar-commerce"
Run this in each client repository.

This writes .zence/policy.yaml in audit mode: every decision is evaluated and recorded, nothing is blocked. Watch it for a few days, then switch to enforce. Blocking a team’s work on day one is how a guardrail gets uninstalled.

Step 3

Check that it works

zence doctor          # uv, workspace, token, catalog reachability
zence status          # which boundary this repository is bound to
zence inspect northstar.marketing_leads

zence evaluate --tool Write --file models/x.sql \
  --content "SELECT email FROM bluepeak.patient_contacts"
`evaluate` runs the real engine over a hypothetical call, so you can test a policy without provoking a violation. Its exit code carries the verdict — 0 allow, 6 deny, 7 ask — so CI can assert a rule still fires.

Reference

The twelve built-in rules

Inherited automatically. A workspace rule sharing an id replaces the built-in one, so a single rule can be retuned without forking all of them.

Built-in policy rules
RuleDecisionFires on
ZR-001denyCross-client asset carrying PII
ZR-002askCross-client read of an unclassified asset
ZR-003denyWrite to another client's asset
ZR-004askMutation in production
ZR-005denyDestructive operation in production
ZR-006askAsset marked deprecated in DataHub
ZR-007askSensitive asset with no owner recorded
ZR-008askChange reaching a critical downstream asset
ZR-009allowIn-boundary read in a permitted environment
ZR-010allowIn-boundary code generation, nothing sensitive
ZR-011askUnresolvable asset during a write
ZR-014denyEdit to Zence or hook configuration

ZR-012 and ZR-013 are reserved for exception semantics — an active exception downgrading an ask, and an expired one having no effect. They live in the engine rather than the rule file, because putting a rule in a file that does not control the behaviour would be misleading.

Reference

Exceptions

exceptions:
  - rule_id: ZR-002
    scope:
      urn: "urn:li:dataset:(urn:li:dataPlatform:snowflake,shared.dim_date,PROD)"
    expires_at: "2026-12-31T23:59:59+02:00"
    approver: "you@example.com"
    reason: >-
      Shared date dimension. Lives in another domain for historical
      reasons and contains no client data.
Two constraints, both enforced at load time: the expiry is mandatory and must carry a timezone offset, and an exception may only target an ask rule. A deny cannot be waived in a policy file.