mirror of
https://github.com/ansible/awx.git
synced 2026-02-14 17:50:02 -03:30
clears authtoken & add PAT
This commit is contained in:
@@ -1,70 +1,67 @@
|
||||
## Introduction
|
||||
Starting from Tower 3.3, OAuth 2 will be used as the new means of token-based authentication. Users
|
||||
will be able to manage OAuth tokens as well as applications, a server-side representation of API
|
||||
clients used to generate tokens. By including an OAuth token as part of the HTTP authentication
|
||||
header, a user will be able to authenticate herself and gain more restrictive permissions on top of
|
||||
the base RBAC permissions of the user. The degree of restriction is controllable by the scope of an
|
||||
OAuth token. Refer to [RFC 6749](https://tools.ietf.org/html/rfc6749) for more details of OAuth 2
|
||||
specification.
|
||||
will be able to manage OAuth 2 tokens as well as applications, a server-side representation of API
|
||||
clients used to generate tokens. With OAuth 2, a user can authenticate by passing a token as part of
|
||||
the HTTP authentication header. The token can be scoped to have more restrictive permissions on top of
|
||||
the base RBAC permissions of the user. Refer to [RFC 6749](https://tools.ietf.org/html/rfc6749) for
|
||||
more details of OAuth 2 specification.
|
||||
|
||||
## Usage
|
||||
|
||||
#### Managing OAuth applications and tokens
|
||||
The root of OAuth management endpoints is `/api/<version>/me/oauth/`, which gives a list of endpoint
|
||||
roots for managing individual type of OAuth resources: OAuth application under
|
||||
`/api/<version>/me/oauth/applications/` and OAuth token under `/api/<version>/me/oauth/tokens/`. The
|
||||
reason for OAuth management endpoints to be under `/api/<version>/me/` is because, as an authentication
|
||||
approach, OAuth resources will only take effect to the underlying user.
|
||||
#### Managing OAuth 2 applications and tokens
|
||||
Applications and tokens can be managed as a top-level resource at `/api/<version>/applications` and
|
||||
`/api/<version>/tokens`. These resources can also be accessed respective to the user at
|
||||
`/api/<version>/users/N/<resource>`. Applications can be created by making a POST to either `api/<version>/applications`
|
||||
or `/api/<version>/users/N/applications`.
|
||||
|
||||
Each OAuth application belongs to a specific user, and is used to represent a specific API client
|
||||
on the server side. For example, if AWX user Alice wants to make her `curl` command to talk to
|
||||
AWX, the first thing is creating a new application and probably name it `Alice' curl client`.
|
||||
Each OAuth 2 application represents a specific API client on the server side. For an API client to use the API,
|
||||
it must first have an application, and issue an access token.
|
||||
|
||||
Individual applications will be accessible via their primary keys:
|
||||
`/api/<version>/me/oauth/applications/<primary key of an application>/`. Here is a typical application:
|
||||
`/api/<version>/applications/<primary key of an application>/`. Here is a typical application:
|
||||
```
|
||||
{
|
||||
"id": 1,
|
||||
"type": "application",
|
||||
"url": "/api/v2/me/oauth/applications/1/",
|
||||
"type": "o_auth2_application",
|
||||
"url": "/api/v2/applications/1/",
|
||||
"related": {
|
||||
"user": "/api/v2/users/1/",
|
||||
"tokens": "/api/v2/me/oauth/applications/1/tokens/",
|
||||
"activity_stream": "/api/v2/me/oauth/applications/1/activity_stream/"
|
||||
"tokens": "/api/v2/applications/1/tokens/",
|
||||
"activity_stream": "/api/v2/applications/1/activity_stream/"
|
||||
},
|
||||
"summary_fields": {
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "admin",
|
||||
"username": "root",
|
||||
"first_name": "",
|
||||
"last_name": ""
|
||||
},
|
||||
"tokens": {
|
||||
"count": 13,
|
||||
"count": 1,
|
||||
"results": [
|
||||
{
|
||||
"token": "UdglJ1IkG3YrkzPWkEIwBqWP2xL8X7",
|
||||
"id": 16
|
||||
},
|
||||
...
|
||||
"scope": "read",
|
||||
"token": "**************",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"created": "2017-12-07T16:08:21.341687Z",
|
||||
"modified": "2017-12-07T16:08:21.342015Z",
|
||||
"name": "admin's app",
|
||||
"created": "2018-02-20T23:06:43.215315Z",
|
||||
"modified": "2018-02-20T23:06:43.215375Z",
|
||||
"name": "Default application for root",
|
||||
"user": 1,
|
||||
"client_id": "l7VbJdYxqKzoewQR7iZAYkiUI7AdqQhJuiAF4TqJ",
|
||||
"client_secret": "gsplwGti48nJhs5dJ9IMJ0BqN3LvwvFPFgbrQzhXz4bT2oOJBmoCj2egpAUF6Ivme1LFLYAeLwYkmj8AVHEkpYfYxMvK6LTNJG8nO2AIGt7l6MCgj9oD5cgwLvsfGxl2",
|
||||
"client_id": "BIyE720WAjr14nNxGXrBbsRsG0FkjgeL8cxNmIWP",
|
||||
"client_secret": "OdO6TMNAYxUVv4HLitLOnRdAvtClEV8l99zlb8EJEZjlzVNaVVlWiKXicznLDeANwu5qRgeQRvD3AnuisQGCPXXRCx79W1ARQ5cSmc9mrU1JbqW7nX3IZYhLIFgsDH8u",
|
||||
"client_type": "confidential",
|
||||
"redirect_uris": "",
|
||||
"authorization_grant_type": "password",
|
||||
"skip_authorization": false
|
||||
}
|
||||
},
|
||||
```
|
||||
In the above example, `user` is the underlying user this application associates to; `name` can be
|
||||
used as a human-readable identifier of the application. The rest fields, like `client_id` and
|
||||
`redirect_uris`, are mainly used for OAuth authorization, which will be covered later in 'Using
|
||||
In the above example, `user` is the primary key of the user this application associates to and `name` is
|
||||
a human-readable identifier for the application. The other fields, like `client_id` and
|
||||
`redirect_uris`, are mainly used for OAuth 2 authorization, which will be covered later in the 'Using
|
||||
OAuth token system' section.
|
||||
|
||||
Fields `client_id` and `client_secret` are immutable identifiers of applications, and will be
|
||||
@@ -77,112 +74,15 @@ On RBAC side:
|
||||
- Organization admins will be able to see and manipulate all applications belonging to Organization
|
||||
members;
|
||||
- Other normal users will only be able to see, update and delete their own applications, but
|
||||
cannot create any new application.
|
||||
cannot create any new applications.
|
||||
|
||||
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. There are two ways of creating a token: POSTing to `/me/oauth/tokens/`
|
||||
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 `/me/oauth/applications/<pk>/tokens/` by providing only `scope`, while
|
||||
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`. `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 she is 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.
|
||||
|
||||
#### Using OAuth token system
|
||||
The most significant usage of OAuth is authenticating users. `token` field of a token is used
|
||||
as part of HTTP authentication header, in the format `Authorization: Bearer <token field value>`.
|
||||
Here is a `curl` command example:
|
||||
```
|
||||
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 token acquire; The token acquire endpoint
|
||||
is also responsible for token refresh; and token revoke is done by 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 reuses them and puts related
|
||||
endpoints under `/api/o/` endpoint. Detailed examples on some 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).
|
||||
# More Docs Coming Soon
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
## Introduction
|
||||
>> Updated to these docs coming soon.
|
||||
|
||||
Before Tower 3.3, auth token is used as the main authentication method. Starting from Tower 3.3,
|
||||
session-based authentication will take the place as the main authentication, while auth token
|
||||
will be replaced by OAuth tokens also introduced in 3.3.
|
||||
|
||||
Reference in New Issue
Block a user