Coding agents
Hand a new access rule to your coding agent — it lands in the access model as policies and tests, with no application code.
This walkthrough continues Getting started. There you protected an endpoint and the access model made the decisions. Here a new access rule ships end to end — and your coding agent does the authoring. The application code does not change at all.
The rule arrives
A new requirement: the accounting department must be able to edit invoices.
Try it first. The user below carries a department attribute and no role at all:
curl -X PATCH http://localhost:3000/invoices/inv-1 \
-H 'x-user: {"id":"u-77","department":"accounting"}'{"message":"You do not have permission to perform this action","error":"Forbidden","statusCode":403}Denied — no policy grants invoices:edit to this user. In a conventional codebase this is where someone opens the invoice controller and adds an if. Here the rule becomes policies and tests in the access model, and authoring them is a job for your coding agent.
Hand it to your agent
Paste this into your coding agent, in the repository of your application:
The accounting department (user attribute department = "accounting") must be able
to edit invoices. Use the arkveil CLI.No setup is required, and the prompt carries no methodology. The CLI is built to be discovered: arkveil --help teaches an agent the commands and the working rules — author rules in the access model instead of application code, inspect before writing, validate formulas, cover every change with tests including the access that must stay denied, and finish with a green arkveil tests run-all.
What the agent does
A typical session, reconstructed from a real run. The agent inspects before it writes:
arkveil trees all # the current model: targets, actions, tests
arkveil schemas get user # user attributes: id, role, region, department
arkveil formula parse --context ACTION_PERMISSION --dsl 'user.department = "accounting"'The rule covers editing only, and no existing target scopes invoices:edit alone. So the agent extends the model — a target, a policy, and two tests:
arkveil targets create --parent <action-policies-root> --type ACTION --mode INDIVIDUAL \
--title "Edit invoice" --action-code invoices:edit
arkveil policies create <target-node-id> --type PERMISSION --status ENABLED \
--title "Accounting edits invoices" \
--condition 'user.department = "accounting"'
arkveil tests create --parent <tests-root> --name "Accounting can edit an invoice" \
--status ENABLED --selector-type ACTION_SET --action-code invoices:edit \
--user '{"id":"u-77","department":"accounting"}' --expected-access GRANTED
arkveil tests create --parent <tests-root> --name "Accounting cannot issue an invoice" \
--status ENABLED --selector-type ACTION_SET --action-code invoices:issue \
--user '{"id":"u-77","department":"accounting"}' --expected-access DENIEDThen it verifies the whole model, not just its own change:
arkveil tests run-all16 runs, all PASSEDThe fourteen seeded tests still pass — the agent widened access for one department and broke nothing else. The negative test pins the boundary that must stay closed.
See the change land
Repeat the request that was denied:
curl -X PATCH http://localhost:3000/invoices/inv-1 \
-H 'x-user: {"id":"u-77","department":"accounting"}'{"id":"inv-1","status":"updated"}Granted — and the application was not rebuilt, redeployed, or edited. The decision is explainable, down to the policy that granted it:
arkveil eval explain -a invoices:edit --user '{"id":"u-77","department":"accounting"}'action: invoices:edit
granted: GRANTED
granting policies: 96368751-2b52-44ec-a90b-adbf7eea0c73
candidate policies: 5Notice what the user object never contained: a role. The condition reasons over user.department, and role is just another attribute in the model — this is attribute-based access control, not a role table with extra steps.
Review it like code
The agent's change is not a diff scattered across controllers. It is four named artifacts — a target, a policy, two tests — visible in arkveil trees all and in Arkveil Studio, where a human can read the condition, trace decisions against it, and approve or adjust. Coding agents author the model, humans approve it, and the runtime enforces it.
Next steps
-
Access model — the concepts behind everything the agent just touched.
-
SDK — the TypeScript SDK packages and how to integrate them.
-
CLI — the full command reference your agent is using.
-
Policy tests — the lifecycle behind agent-authored tests, GENERATED to ENABLED.