Conditions on Permission
The shop API lets a shopper edit their own cart while it is open. Once the cart has been ordered, the shopper cannot change its contents. The shopper still has the same role and still owns the cart. The difference is the cart’s state: the cart is no longer open, so the server refuses the edit.
To change a cart item, the server checks three conditions: the caller is a shopper, the caller owns the cart, and the cart is open.
| Caller | Cart owner | Cart state | May change an item? |
|---|---|---|---|
| Shopper 7 | Shopper 7 | Open | Yes |
| Shopper 7 | Shopper 8 | Open | No: another shopper’s cart |
| Shopper 7 | Shopper 7 | Ordered | No: the cart was ordered |
A policy is a rule the system uses to decide whether an action is allowed. For this operation, we can write the policy as: “A shopper may change an item in a cart they own while that cart is open.”
The role comes from the user’s role assignment. Ownership and state come from the stored cart.
The server sends a different response depending on which condition fails. If the caller does not own the cart, the server returns NOT_FOUND. If the caller owns the cart but it has already been ordered, the server returns CART_NOT_OPEN, which tells them why the edit was refused. In a REST API, the status would be 409 Conflict, meaning a request that conflicts with the current state of the resource.
Permissions that depend on state
Let’s look at a more detailed example from HopPress. An author writes a draft and submits it for review, and an editor publishes it or returns it for changes.
The author can edit their own post while it is a draft or has been returned. After submission, the author can still read it but cannot edit it, so the text stays fixed while the editor reviews it. In the initial release, the author also cannot edit a published post.
| State of the author’s own post | May read? | May edit? | May submit? |
|---|---|---|---|
| Draft | Yes | Yes | Yes |
| Returned | Yes | Yes | Yes |
| Submitted | Yes | No | No |
| Published | Yes | No | No |
Every row of this table is about the same author and the same post. What changes from row to row is the action and the post’s state, and those decide the answer.
Separation of duties
A HopPress user can hold both the author and editor roles. They can write their own posts and review other people’s posts. Our design does not let them publish their own submission. Another editor must review it.
Requiring different people to perform parts of a sensitive process is called separation of duties. NIST’s explanation of separation of duties describes this kind of restriction.
One way to enforce this is to prohibit anyone from holding both roles. That would also prevent an author from reviewing other people’s work. Instead, we add a condition to the publish operation. To publish a post, the caller must be an editor, the post must be submitted, and the caller must not be its author.