Policy drafts
Describe an access rule in plain language and get a Cedar draft, checked against the schema, your policy tests and live policies, active only once approved.
- Draft a Cedar policy from a plain description
- Read a draft's validation, test results, examples and diff
- Approve, reject or revert a draft
- Keep a policy test suite every draft must pass
Writing Cedar by hand is error-prone, and a wrong policy can lock owners out of an agent or quietly grant too much. Policy drafts let an administrator describe the rule in plain language, for example "contractors may not promote any agent outside working hours". Liyagent drafts one Cedar statement and proves it before anything is enforced.
Open Governance › Policy drafts (/policydrafts).
How a draft is checked
- Draft. Choose Draft policy, give the policy a name and describe the rule (up to 2,000 characters). One call goes through the model gateway, which is told the schema's entity types and actions and the policies already stored. To adjust the result, edit the Cedar and draft again: an edited draft is evaluated as written, with no model call.
- Validate. The draft is validated strictly against the Cedar schema. Any schema warning, such as an unknown action or attribute, makes it invalid.
- Test. The draft is run against your policy test suite (below), with the policy set as the draft would leave it.
- Examples. It is run against example requests generated from this instance. The page shows the allow and deny cases the draft matches.
- Diff. It is compared with the policies in force: what each principal gains and loses, the findings, and whether it locks the owners out of an agent.
A draft is stored with that evidence. Nothing is enforced.
Approve and activate
Nothing is active until someone chooses Approve and activate (POST /api/policy-drafts/{id}/approve). Approval runs every check again against the policy set as it is at that moment, and is refused when:
- the policy changed since the draft was made (draft it again),
- the draft fails validation or a test, or
- it would lock the owners out of an agent.
An approved draft is saved through the ordinary policy write, as the approver, with every gate that write has. Choose Reject to close a draft without activating it. Both take an optional reason (up to 500 characters).
Four eyes
TICKETIQ_POLICY_DRAFT_FOUR_EYES (default true) separates drafting from activating. It is adaptive:
| Situation | Who may activate |
|---|---|
| Setting on, two or more accounts can approve policy changes in the tenant | Someone other than the drafter |
| Setting on, exactly one account can approve | That admin may activate their own draft with an explicit reason. It is recorded on the draft and audited as four_eyes_unavailable |
| Setting off | The drafter may approve their own draft |
| Agent change control is on (any tier) | Someone other than the drafter, whatever the setting says |
An account counts as an approver when it is enabled and holds policy.create or policy.update in the tenant. Each draft in the API carries four_eyes and four_eyes_mode (required, unavailable or off) so you can see which rule applies.
A draft is never activated without an explicit approval in any mode.
Revert
Revert (POST /api/policy-drafts/{id}/revert) restores the policy an active draft replaced, or removes the policy it created. It is refused if the policy has changed again since the draft was activated.
Draft statuses are draft, active, rejected and reverted.
Policy tests
The Policy tests suite is a list of requests and the answer each must get. Every draft is run against it, and approval re-runs it.
| Field | Meaning |
|---|---|
name | A label for the test |
principal_type, principal_id | Who is asking, for example User and alice |
action | The Cedar action |
resource_type, resource_id | What is acted on |
context | Optional request context |
expect | allow or deny |
GET /api/policy-tests runs each test against the policy set as it is now and returns its result.
Routes and permissions
| Task | Endpoint | Permission |
|---|---|---|
List drafts (optional ?status=) | GET /api/policy-drafts | policy.list |
| Read a draft | GET /api/policy-drafts/{id} | policy.list |
| Create a draft | POST /api/policy-drafts | policy.create or policy.update |
| Approve and activate | POST /api/policy-drafts/{id}/approve | policy.create or policy.update |
| Reject | POST /api/policy-drafts/{id}/reject | policy.create or policy.update |
| Revert | POST /api/policy-drafts/{id}/revert | policy.update |
| List tests with results | GET /api/policy-tests | policy.list |
| Add a test | POST /api/policy-tests | policy.create or policy.update |
| Delete a test | DELETE /api/policy-tests/{id} | policy.update |
Activating also needs the permission the policy write itself asks for (create for a new policy, update for an existing one).
Audit
Each step is in the audit log: policy.draft.create, policy.draft.activate, policy.draft.reject, policy.draft.revert, policy.draft.refused, policy.save, policy.test.create and policy.test.delete, plus four_eyes_unavailable when a sole admin activates their own draft.
Drafts and tests are stored per tenant, under row-level security.