What does OWASP ZAP's accessControl add-on need from a person, and why can't a pipeline produce it?
answer
- somebody has to say what should happen
- marks are per user, per node
- unmarked nodes inherit from an ancestor
- the rules ride on the context
- no API action sets a rule
basics
~20 sThe accessControl add-on needs per-user ground truth: a person marks nodes of a context's site tree allowed or denied for each user. A pipeline can replay a marked-up context, but nothing in its API or plan surface can create one.
solid answer
~40 sThe add-on compares what a user can actually reach against what a person said that user should reach. That statement is `AccessRule`, which declares `ALLOWED`, `DENIED`, `UNKNOWN` and `INHERIT`, assigned per user against nodes of the context's site tree. Not every node needs marking — `inferRule` returns an explicit rule when there is one and otherwise takes the closest ancestor that has one, with the root fixed at `UNKNOWN`, so you mark the tree where its shape and your authorisation model disagree. The marks are context data: persisted with the session and written out by `exportContextData`, so CI can reuse them. What CI cannot do is create them — the add-on's API exposes `scan`, `writeHTMLreport` and two progress views, and it registers no automation-framework job.
code
java · 6 linespublic enum AccessRule {
ALLOWED,
DENIED,
UNKNOWN,
INHERIT
}go deeper
Recall that this add-on does not work out who should see what — a person tells it, per user, and the add-on then checks whether reality matches. That dependency is the whole point of the question.
Explain the rule set and the inference: four values, assigned per user against site-tree nodes, with an unmarked node taking the closest explicitly marked ancestor's rule and the root fixed at unknown.
Show the automation boundary. The marks are context data you can export, commit and import, but nothing in the add-on's API or job surface creates them, so a scheduled run consumes a human artefact.
Own the recurring cost. A capability that depends on a curated statement of intent needs an owner, a review cadence and a rule for what happens when the application's routes outgrow it.
## What the add-on is for The access-control testing add-on answers a question a scan cannot ask on its own: *is this user able to reach something this user should not reach?* To answer it, something has to say what "should" means. The add-on's design is refreshingly blunt about that — the statement comes from a person, and the add-on holds it as data. ## The rule set `AccessRule` declares four values: `ALLOWED`, `DENIED`, `UNKNOWN` and `INHERIT`. They are assigned **per user** against nodes of the context's site tree, so the same node can be allowed for one user and denied for another, which is the whole point. The fourth value is the one that makes this usable, and it is the part usually described wrongly. It is often said that a person must mark *every* node. They must not: - `inferRule` first looks for a rule set explicitly on the node, and returns it unless that rule is `INHERIT`. - Otherwise it walks the node's ancestors and takes the rule of the **closest ancestor that has an explicit one**. - The root is fixed at `UNKNOWN`, so if no ancestor was ever marked, the node comes out `UNKNOWN`. So the marking effort is proportional to how far your site's **tree shape** diverges from your **authorisation model**. Mark a branch once and everything under it follows. If your URLs group by capability, this is quick; if permissions cut across the tree, it is not — and that, incidentally, is a useful thing to learn about your own application. ## Where the marks live The rules are **context data**, not run configuration: | operation | what it does | |---|---| | `persistContextData` | writes the serialized rules into the session under an access-control-rule context data type | | `loadContextData` | reads them back when the session is opened | | `exportContextData` | writes them into an exported context file | | `importContextData` | reads them back out of one and reloads the context's site tree | That has a pleasant consequence for a pipeline: a marked-up context is **portable**. Export it, commit it, import it in CI, and a scheduled run can use a person's ground truth without that person being present. ## Why a pipeline still cannot produce it The reusability above is the good news and it invites an overstatement, so be precise about what is missing. The add-on's API component exposes: 1. `scan` — start an access-control scan for a context and the users you name. 2. `writeHTMLreport` — write the result out. 3. Two views that report the scan's progress and status. There is **no action that sets a rule**, and the add-on registers no automation-framework job. So the honest split is: - **Replayable:** running the scan, collecting the result — fully automatable. - **Not replayable:** producing the statement of what each user should be allowed to reach. A person does that once, in a session or an exported context, and the pipeline consumes it. This is also why the capability drifts. The rules describe a site tree that existed when someone marked it; routes added since are unmarked, inherit whatever their nearest marked ancestor said, and nobody is told. Treat the marked context as a reviewed artefact with an owner and a review date — not as configuration that looks after itself. ## Why this belongs in a tool comparison at all When you are choosing between tools, the interesting question is rarely "can it do X" — it is "what does X cost me every week". Here the add-on is unusually honest: it does not pretend to infer intent, it asks for it, and it stores what it was told. That is a feature in a comparison, because it makes the recurring cost visible up front instead of surfacing later as findings nobody trusts. There is a second reason it belongs in the comparison, and it is the one that survives a change of tool. Any product that tests authorisation has to be told what the answer should be, because no amount of traffic reveals intent — a request that succeeds looks the same whether it was meant to or not. What differs between products is only *how* they ask: through a marked-up tree, a per-role matrix, a set of recorded sessions replayed as different users. So when you compare, do not ask which tool can test access control; ask what each one wants from a human, how often it will want it again, and whether that artefact can live in version control where someone will review it. On the last of those this add-on scores well, because its rules travel in an exported context file. The corresponding red flag in a candidate is the opposite belief — that pointing any automated scan at an authenticated application will surface cross-user access problems by itself. Whatever tool you pick, someone has to supply the intent. The tools differ in whether they make you say so.
- If the marks are reusable, what goes stale about them?The tree they describe. Routes added after someone marked it are unmarked, so they inherit whatever their nearest marked ancestor said and nobody is told. Treat an exported context as a reviewed artefact with an owner and a review date, not as configuration that maintains itself.
- Why is `INHERIT` a separate value rather than just the absence of a rule?Because absence and "defer to my ancestor" have to be distinguishable when a rule has been written down. The inference step returns an explicit rule unless it is `INHERIT`, in which case it keeps walking upward — so you can record the intent to defer instead of leaving a gap.
saying these in an interview costs you the question
- The add-on infers who should see what from the traffic
- Every node in the tree has to be marked by hand
- Unmarked nodes are all treated as denied
- The rules can be set through the add-on's API like any option
- Access rules are global rather than per user