1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# User Authorization
<!--
Brief description of the problem being solved and the approach being suggested.
Focus on the external behavior of the system (APIs, SLO requirements, etc),
and for larger initiatives, outline the system design sufficiently such that
parallel streams of work can make progress independently.
-->
## Context, scope, and history
<!--
Establish context for the system under review and the changes you’re considering:
* what does the audience need to know to better understand the changes that follow?
-->
## Goals and non-goals
<!--
What is a measurable definition of success? (.e.g. Reduce p95 response time to <100ms).
What are you explicitly not solving with this approach?
-->
## Design overview
Authorization policies are enforced using a:
* Subject: The authenticated user.
* Resource: The object that the user is attempting to interact with.
* Action: The type of interaction. (i.e. create, read, update, delete).
Each Subject is identified using a canonical identifier from the `sub` claim of
the `access_token` issued by Auth0 (e.g. `"sub": "auth0|627b10e1019dd10068e03db4"`).
Each Resource is identified via a canonical URI in the form of `scheme://host/path`.
For example, `https://api.cmdzero.io/atlas/organizations/:org_id/investigations/:id`
uses the scheme of `https`, host of `api.cmdzero.io`, and path of
`atlas/organizations/:org_id/investigations/:id` to describe the target resource
to perform the action on. The `:org_id` is a placeholder for a ULID
to represent a unique organization and the `:id` is a ULID to identify a
specific investigation underway for that organization.
An Action must be one of the following strings `read`, `write`. The `read`
action implies that the Subject wishes to retrieve the data associated with the
Resource. A `write` action implies that the Subject wants to create or update
the data associated with the Resource.
Using this model we can describe policies as a formula that can be evaluated and
matched efficiently at the time of enforcing authorization rules.
```plaintext
request = subject, resource, action
token = request bearer token
policy = f(token), resource, action
effect = policy_satisfied? ? allow : deny
```
The above can be evalated to produce an authorization result.
```plaintext
result = f(token) && request.resource == policy.resource && request.action == policy.action
```
`f(token)` is a function that accepts the `access_token` from the
`Authorization` header for the request. The function `f` will determine how to
decode the token apply any caveats and return a true or false answer.
Example:
Name: Adnan
* Role: IR
* Organization: Mandiant
Name: Mike
* Role: CISO
* Organization: GitHub
Adnan is an incident responder that works for Mandiant and is called in when a
breach has occurred at GitHub. Mike is the CISO at GitHub and has requested help
from Mandiant to help understand the extent of a breach.
Mike invites Adnan to join the GitHub Organization to be able to manage the
incident.
1. Mike invites Adnan:
```
POST /organizations/:github_id/invitations/
Authorization: Bearer <access_token>
Host: api.cmdzero.io
{
"to": ":adnan_uuid"
}
```
When the API gateway hosted at `api.cmdzero.io` receives this request and uses
the formula listed above to decide whether it should allow or deny access.
```plaintext
request = Mike, https://api.cmdzero.io/organizations/:github_id/invitations/, create
subject, resource, action = { request }
token = ["invitations.create"]
policy = send_invitation?(token), resource, action
effect = satisfied?(policy) ? allow : deny
result = policy(token, resource, action)
```
<!--
Details of your prospective solution.
This should be comprehensive, assume your audience is technical but may not be
intimately familiar with the systems under consideration.
Where appropriate, include system diagrams, API definitions, pseudo-code,
etc to concretize your design; provide your audience with a sense of the
technical underpinnings of your solution.
-->
## Dependencies
<!--
Enumerate system and if relevant, organizational dependencies.
It is very likely that at this stage, not all dependencies will be known,
and/or some decision points around dependencies may remain.
-->
## Milestones
<!--
How will you approach the solution?
What are notable, significant achievements that we'd consider a strong
indicator of progress. Are there any go/no-go decision points?
-->
## Privacy and security concerns
<!--
What does your system potentially expose and what are you doing to mitigate the impact?
Will a security review be required before moving forward with implementation?
-->
## Risks
<!--
What are the system and organizational risks you’re assuming as part of this solution?
-->
## Alternatives considered
<!--
What solutions weren’t appropriate and why?
-->
## Supporting material
<!--
Include any additional references or related documentation.
-->
|