# Organization policy

How a policy is written, published, signed and applied by every zn-gate in the organization.

Source: https://usezn.com/docs/team/policy/

The organization policy is a list of rules about secrets: where they may be sent and how they are injected. Owners and admins edit it in **Policies** and publish a new version; every zn-gate in the organization picks it up.

## Rules

Each rule applies to one secret (by name, never by value; `PREFIX*` and `*` are allowed):

| Field | Meaning |
|---|---|
| `secret` | The secret's name, for example `STRIPE_API_KEY` |
| `agents` | Agents that may be offered a new host, for example `claude-code`, `codex`. A `deny` ignores this list |
| `mode` | Only `proxy` is applied (the most restrictive way); other values are ignored |
| `allowHosts` | Hosts the secret may be sent to |
| `allowCommands` | Commands that may receive the secret |
| `injectAt` | Where the secret is injected |
| `deny` | Block every use of the secret, by all agents on the machine |
| `warn` | Lets the use through within the rule's other limits, warns the developer and records it as Warned, for all agents on the machine. Set `warn` or `deny`, never both |
| `reason` | Shown to the developer when a Warn rule applies; for Block rules it is a note for admins |

How rules combine:

- **All matching rules apply, top to bottom; each can only restrict further.**
- **`deny` blocks. `warn` lets the use through, warns the developer and records it in the audit log.** A `deny` also applies to `secrets_render_file`, so a secret the policy blocks cannot be written to a file through that tool.
- Fields a rule sets only narrow the machine's local settings; fields it leaves out keep the local value. A new host needs the member's approval and is only offered while the policy is current (not once it has expired on a machine in strict mode); a host with a port is never offered; commands, modes and injectAt are never opened.

There is one policy for the whole organization, not one per agent. A `deny` or a `warn` applies to every agent on the machine, whatever `agents` says: the `agents` list only decides which agents are offered a new host.

## Three states

Each rule is in one of three states, chosen in the rule editor:

| State | On the member's machine | In the audit log |
|---|---|---|
| **Not blocked** (default) | The use goes through, with the local settings and any limits in the rule. | Allowed |
| **Warn** | The use goes through within the rule's limits; zn-gate warns the developer and records it. | Warned |
| **Block** | The use is stopped. | Blocked |

A warning is shown on the developer's machine; it does not stop the use. Every warned and blocked use appears in Team → Audit log, with metadata only (no values).

Warn rules apply wherever a block applies: `zn run`, `secrets_http_request`, `secrets_render_file`, and the restores of markers and tokens in the agent hooks. When a warned use goes ahead, the developer and the agent see this notice: `zn: your team policy would block STRIPE_API_KEY here (policy note: "..."). It was allowed and recorded for your organization.` An audit record with the decision `warn` is uploaded to your organization. A marker restored by the hooks follows the same rules: a secret that the policy blocks stays a marker and the hook says why, and a secret under a Warn rule is restored and recorded.

Warn rules need zn-gate 1.8.0 or later. On machines with an older zn-gate, a Warn rule acts as Not blocked: the use goes through within the rule's other limits, but no warning is shown and nothing is recorded as Warned. Ask members to update zn-gate.

In an organization with Warn rules, do not go back to zn-gate 1.7.1. It refuses a policy that contains Warn rules and applies only the local settings until the next policy sync downloads a copy it can read. Stay on 1.8.0 or later.

## Publishing

Publishing creates a new version. The dashboard validates it first. A blocked use is reported with `reason: policy:org_deny`, and a warned use is reported with `reason: policy:warn` and recorded in the audit log as **Warned**. The dashboard also refuses a rule that sets both `warn` and `deny`.

Publishing asks owners and admins for two-factor authentication. Changes proposed from a coding agent with an org admin token always wait for a person to approve them; see [Manage your team from your agent](https://usezn.com/docs/team/agents/).

## Signature and versions

- zn serves each policy signed with your organization's Ed25519 key. Every machine verifies it against the public key it pinned when it joined.
- A served policy is valid for 7 days. Machines check for a new version regularly and when you run `zn team sync`.
- A machine never accepts a version lower than the last one it accepted, a policy signed with an unknown key or one whose signature does not verify. It keeps the last valid policy and logs `policy:rejected`.

What happens without network, or when a policy expires, is in [Offline mode](https://usezn.com/docs/team/offline/).

## What the organization cannot do

zn-gate is a local guardrail, not an MDM. The organization policy works on top of zn-gate's built-in protections and cannot switch them off: credential files, `~/.zn` and the agents' own configuration stay protected whatever the policy says.
