Skip to content

Commit 683f5e5

Browse files
author
Luke Sneeringer
authored
feat: AIP-211 – Authorization checks (#30)
1 parent fbafa2f commit 683f5e5

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

aip/general/0211/aip.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Authorization checks
2+
3+
The majority of operations, whether reads or writes, require authorization:
4+
permission to do the thing the user is asking to do. Additionally, it is
5+
important to be careful how much information is provided to _unauthorized_
6+
users, since leaking information can be a security concern.
7+
8+
## Guidance
9+
10+
Services **must** check authorization before validating any request, to ensure
11+
both a secure API surface and a consistent user experience. An operation
12+
**may** require multiple permissions or preconditions in order to grant
13+
authorization.
14+
15+
If a request can not pass the authorization check for any reason, the service
16+
**should** error with `403 Forbidden`, and the corresponding error message
17+
**should** look like: "Permission `{p}` denied on resource `{r}` (or it might
18+
not exist)." This avoids leaking resource existence.
19+
20+
If it is not possible to determine authorization for a resource because the
21+
resource does not exist, the service **should** check authorization to read
22+
children on the parent resource, and return `404 Not Found` if the
23+
authorization check passes.
24+
25+
### Multiple operations
26+
27+
A service could encounter a situation where it has two different operations
28+
with two different permissions, either of which would reveal the existence of a
29+
resource if called, but a user only has permission to call one of them.
30+
31+
In this situation, the service **should** still only check for authorization
32+
applicable to the operation being called, and **should not** try to "help out"
33+
by checking for related authorization that would provide permission to reveal
34+
existence, because such algorithms are complicated to implement correctly and
35+
prone to accidental leaks.
36+
37+
For example, posit a scenario where:
38+
39+
- A resource exists within a given collection that a user is unable to read.
40+
- The user _does_ have the ability to create other resources, and the
41+
collection uses user-specified IDs (meaning that a failure because of a
42+
duplicate ID would reveal existance).
43+
44+
In this situation, the get or create methods **should** still only check
45+
_their_ permissions when determining what error to return, and not one
46+
another's.
47+
48+
## Rationale
49+
50+
[RFC 7231 §6.5.3][] states that services are permitted to use `404 Not Found`
51+
in lieu of `403 Forbidden` in situations where the service does not want to
52+
divulge existance, whereas this AIP argues for the use of `403 Forbidden`
53+
instead. We take this position for the following reasons:
54+
55+
- The practice of "getting `404 Not Found` until you have enough permission to
56+
get `403 Forbidden`" is counter-intuitive and increases the difficulty of
57+
troubleshooting.
58+
- A service _could_ ameliorate this by sending information about missing
59+
permissions while still using the `404 Not Found` status code, but this
60+
constitutes a mixed message.
61+
- While `403 Forbidden` is essentially always an error requiring manual action,
62+
`404 Not Found` is often a valid response that the application can handle
63+
(e.g. "get or create"); overloading it for permission errors deprives
64+
applications of this benefit.
65+
- RFC 7231 §6.5.4 states that `404 Not Found` results are cacheable, but
66+
permission errors are not generally cacheable. Sending explicit cache
67+
controls on a conditional basis could ameliorate this, but would defeat the
68+
purpose.
69+
- The guidance here is more consistent with most other real-world authorization
70+
systems.
71+
72+
[rfc 7231 §6.5.3]: https://tools.ietf.org/html/rfc7231#section-6.5.3

aip/general/0211/aip.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
id: 211
3+
state: approved
4+
created: 2021-02-24
5+
placement:
6+
category: design-patterns
7+
order: 115

0 commit comments

Comments
 (0)