Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add alternative ways to write a policy #1513

Merged
merged 10 commits into from
Oct 14, 2024
17 changes: 16 additions & 1 deletion documentation/topics/security/policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Then you can start defining policies for your resource.

Each policy defined in a resource has two parts -

- a condition, such as `action_type(:read)` or `actor_attribute_equals(:admin, true)` or `always()`. If this condition is true for a given action request, then the policy will be applied to the request.
- a condition or a list of conditions, such as `action_type(:read)`, `[action_type(:read), actor_attribute_equals(:admin, true)]` or `always()`. If the condition, or all conditions if given a list are true for a given action request, then the policy will be applied to the request.
- a set of policy checks, each of which will be evaluated individually if a policy applies to a request.

If more than one policy applies to any given request (eg. an admin actor calls a read action) then **all applicable policies must pass** for the action to be performed.
Expand Down Expand Up @@ -54,6 +54,21 @@ There are four check types, all of which do what they sound like they do:

If a single check does not explicitly authorize or forbid the whole policy, then the flow moves to the next check. For example, if an `authorize_if` check does NOT return true, this _does not mean the whole policy is forbidden_ - it means that further checking is required.

### Policy with `condition` inside `do` block

A condition or a list of conditions can also be moved inside the `policy` block.

This can make a really long list of conditions easier to read.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some explanation here. Like why they might want to specify the condition this way.

Putting the condition inside the policy block can make really long condition lists easier to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added some explanation.

```elixir
policies do
policy do
condition always()
zachdaniel marked this conversation as resolved.
Show resolved Hide resolved
authorize_if always()
end
end
```

### How a Decision is Reached

**Not every check in a policy must pass!** This is described above, but is very important so another example is provided here. Checks go from top to bottom, are evaluated independently of each other, and _the first one that reaches a decision_ determines the overall _policy result_. For example:
Expand Down
Loading