Skip to content

POLICIES

Write a rule, watch it, then let it refuse

A policy is one rule your organization writes down: no runs outside office hours, no more than fifty operations an hour, nobody spends more than $5 a week. EKKA checks it before a plan runs, before a permission is issued, and before a plan is created.

The idea to hold onto: a new rule watches before it blocks. Every rule starts advisory. It is checked, every time it is crossed is recorded, and the work goes through. You look at what it would have stopped, and only then do you give it teeth.

You need the setup from the quickstart

Signed in, an organization, and a running Enclave. If you have not done that yet, start with Build your first agent.


What EKKA can check for you

Each kind of rule takes its own values. Ask the CLI rather than guessing, because the list grows and the field names come from the server:

ekka policy types

Every field it prints is exactly what --field takes, and amounts say which unit they are in.


1 · Write a draft

A draft enforces nothing. Write it as many times as it takes.

ekka policy draft corp.office-hours \
  --type time-window@1 \
  --field days=mon,tue,wed,thu,fri \
  --field start_local=09:00 \
  --field end_local=18:00 \
  --field timezone=Asia/Kolkata \
  --outcome refuse

EKKA answers with what it will do, which at this point is nothing:

✓ Drafted corp.office-hours. It enforces nothing yet.
  • Breaking this is RECORDED and allowed through. This rule does not stop
    anything yet: draft it again with --binding and publish to make it refuse.

A timezone is a place, not an abbreviation

Write America/New_York, not EST. EST is a fixed offset that ignores daylight saving, so a New York rule written that way is an hour wrong for eight months of the year. EKKA refuses the abbreviation and tells you the name to use instead.

2 · Put it in force

Drafting and enacting are two commands on purpose. The gap between them is where a review happens.

ekka policy publish corp.office-hours

From here the rule is frozen. Changing it drafts the next version, and this one stays readable forever, because a refusal recorded last March has to be explainable against what the rule said in March.

3 · Watch it before you trust it

ekka policy list
NAME               KIND           STATUS  WHEN BROKEN   VERSION
corp.office-hours  time-window@1  active  records only  1

records only is the important column. The rule is live and being checked on every run. Nothing is being stopped. Every time it is crossed is on your audit chain:

ekka audit list

Leave it here for a week. This is the whole point of the advisory period: you find out what the rule would have refused before it refuses anything.

4 · Give it teeth

When the recorded firings look right, publish the same rule with --binding:

ekka policy draft corp.office-hours \
  --type time-window@1 \
  --field days=mon,tue,wed,thu,fri \
  --field start_local=09:00 \
  --field end_local=18:00 \
  --field timezone=Asia/Kolkata \
  --outcome refuse --binding

ekka policy publish corp.office-hours

The wording changes, and so does the listing:

✓ corp.office-hours version 2 is in force.
  • Breaking this stops the action and says which rule stopped it.
NAME               KIND           STATUS  WHEN BROKEN  VERSION
corp.office-hours  time-window@1  active  refuses      2

Now a run outside those hours is refused, and the refusal names the rule:

The rule 'corp.office-hours' does not allow this run.

ekka plan run exits non-zero, so a script or a CI job sees the failure.

5 · Turn it off in one command

ekka policy disable corp.office-hours

The rule stops enforcing immediately. It is never deleted: a refusal recorded before today names it, and the record has to be able to show what it said.


The three outcomes

--outcome says what EKKA does when the rule is broken.

Outcome What happens
refuse Stops the action and says which rule stopped it. Needs --binding.
determine Records that the rule was crossed, for someone to judge later. Does not stop the action.
notify Lets the action through and emails your organization's owners.

A notify rule emails once a day per rule, not once per run

A rule that fires on every overnight run would otherwise send a hundred messages about one situation. Every single firing is still on your audit chain.


Reading a rule back

ekka policy show corp.office-hours

It prints the values as stored, the version, whether it is in force, and its fingerprint. --json carries the same, including binding_mode (what the rule asks for) and will_refuse (whether it actually stops things).


What a policy is not

A policy is not a Grant. A Grant says what an agent is permitted to touch at all; a policy is a rule layered over the permissions you already granted. An agent with no Grant is refused whether or not you have written a single policy. See How governance works for Grants.

Policies come from your Charter, the principles your organization has adopted. Read them with ekka charter show.