summaryrefslogtreecommitdiffstats
path: root/docs/auth/oauth.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/auth/oauth.md')
-rw-r--r--docs/auth/oauth.md110
1 files changed, 110 insertions, 0 deletions
diff --git a/docs/auth/oauth.md b/docs/auth/oauth.md
index dc9e9860e4..8f46dcc8af 100644
--- a/docs/auth/oauth.md
+++ b/docs/auth/oauth.md
@@ -86,3 +86,113 @@ token scope; or POSTing to `/api/applications/<pk>/tokens/` by providing only `s
the parent application will be automatically linked.
# More Docs Coming Soon
+Note a default new application will be created for each new user. So each new user is supposed to see
+at least one application available to them.
+
+Tokens, on the other hand, are resources used to actually authenticate incoming requests and mask the
+permissions of underlying user. Tokens can be created by POSTing to `/api/v2/tokens/`
+endpoint by providing `application` and `scope` fields to point to related application and specify
+token scope; or POSTing to `/api/applications/<pk>/tokens/` by providing only `scope`, while
+the parent application will be automatically linked.
+
+Individual tokens will be accessible via their primary keys:
+`/api/<version>/me/oauth/tokens/<primary key of a token>/`. Here is a typical token:
+```
+{
+ "id": 17,
+ "type": "access_token",
+ "url": "/api/v2/me/oauth/tokens/17/",
+ "related": {
+ "user": "/api/v2/users/1/",
+ "application": "/api/v2/me/oauth/applications/4/",
+ "activity_stream": "/api/v2/me/oauth/tokens/17/activity_stream/"
+ },
+ "summary_fields": {
+ "application": {
+ "id": 4,
+ "name": "admin's token",
+ "client_id": "D6SwhKbfp2LuUjkmiUpMMYFyNqhpv5PTVci7eXTT"
+ },
+ "user": {
+ "id": 1,
+ "username": "admin",
+ "first_name": "",
+ "last_name": ""
+ }
+ },
+ "created": "2017-12-12T16:48:10.489550Z",
+ "modified": "2017-12-12T16:48:10.522189Z",
+ "user": 1,
+ "token": "kqHqxfpHGRRBXLNCOXxT5Zt3tpJogn",
+ "refresh_token": "miZq3hqSugvYxhzdQYJIBDgIHxJPnT",
+ "application": 4,
+ "expires": "2017-12-13T02:48:10.488180Z",
+ "scope": "read"
+}
+```
+For an OAuth token, the only fully mutable field is `scope`. The `application` field is *immutable
+on update*, and all other fields are totally immutable, and will be auto-populated during creation:
+`user` field will be the `user` field of related application; `expires` will be generated according
+to Tower configuration setting `OAUTH2_PROVIDER`; `token` and `refresh_token` will be auto-generated
+to be non-crashing random strings.
+
+On RBAC side:
+- A user will be able to create a token if they are able to see the related application;
+- System admin is able to see and manipulate every token in the system;
+- Organization admins will be able to see and manipulate all tokens belonging to Organization
+ members;
+- Other normal users will only be able to see and manipulate their own tokens.
+> Note: Users can only see the token or refresh-token _value_ at the time of creation ONLY.
+
+#### Using OAuth 2 token system as a Personal Access Token (PAT)
+The most common usage of OAuth 2 is authenticating users. The `token` field of a token is used
+as part of the HTTP authentication header, in the format `Authorization: Bearer <token field value>`. This _Bearer_
+token can be obtained by doing a curl to the `/api/o/token/` endpoint as shown in `api_o_auth_authorization_root_view.md`.
+
+Here is an example of using that PAT to access an API endpoint using `curl`:
+```
+curl -H "Authorization: Bearer kqHqxfpHGRRBXLNCOXxT5Zt3tpJogn" http://localhost:8013/api/v2/credentials/
+```
+
+According to OAuth 2 specification, users should be able to acquire, revoke and refresh an access
+token. In AWX the equivalent, and the easiest, way of doing that is creating a token, deleting
+a token, and deleting a token quickly followed by creating a new one.
+
+On the other hand, the specification also provides standard ways of doing those. RFC 6749 elaborates
+on those topics, but in summary, an OAuth token is officially acquired via authorization using
+authorization information provided by applications (special application fields mentioned above).
+There are dedicated endpoints for authorization and acquiring tokens. The token acquire endpoint
+is also responsible for token refresh, and token revoke is done by a dedicated token revoke endpoint.
+
+In AWX, our OAuth system is built on top of
+[Django Oauth Toolkit](https://django-oauth-toolkit.readthedocs.io/en/latest/), which provides full
+support on standard authorization, token revoke and refresh. AWX implements them and puts related
+endpoints under `/api/o/` endpoint. Detailed examples on the most typical usage of those endpoints
+are available as description text of `/api/o/`.
+
+#### Token scope mask over RBAC system
+The scope of an OAuth token is a space-separated string composed of keywords like 'read' and 'write'.
+These keywords are configurable and used to specify permission level of the authenticated API client.
+For the initial OAuth implementation, we use the most simple scope configuration, where the only
+valid scope keywords are 'read' and 'write'.
+
+Read and write scopes provide a mask layer over the RBAC permission system of AWX. In specific, a
+'write' scope gives the authenticated user full permissions the RBAC system provides, while 'read'
+scope gives the authenticated user only read permissions the RBAC system provides.
+
+For example, if a user has admin permission to a job template, she can both see and modify, launch
+and delete the job template if authenticated via session or basic auth. On the other hand, if she
+is authenticated using OAuth token, and the related token scope is 'read', she can only see but
+not manipulate or launch the job template, despite she has admin role over it; if the token scope is
+'write' or 'read write', she can take full advantage of the job template as its admin.
+
+## Acceptance Criteria
+* All CRUD operations for OAuth applications and tokens should function as described.
+* RBAC rules applied to OAuth applications and tokens should behave as described.
+* A default application should be auto-created for each new user.
+* Incoming requests using unexpired OAuth token correctly in authentication header should be able
+ to successfully authenticate themselves.
+* Token scope mask over RBAC should work as described.
+* Tower configuration setting `OAUTH2_PROVIDER` should be configurable and function as described.
+* `/api/o/` endpoint should work as expected. In specific, all examples given in the description
+ help text should be working (user following the steps should get expected result).