OAuth 2 is used for token-based authentication. You can 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, you can authenticate yourself and adjust the degree of restrictive permissions in addition to the base RBAC permissions. Refer to RFC 6749 for more details of OAuth 2 specification.
For details on using the manage
utility to create tokens, refer to the Token and session management section.
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 2 application represents a specific API client on the server side. For an API client to use the API via an application token, it must first have an application and issue an access token. Individual applications are accessible via their primary keys: /api/<version>/applications/<pk>/
. Here is a typical application:
{
"id": 1,
"type": "o_auth2_application",
"url": "/api/v2/applications/2/",
"related": {
"tokens": "/api/v2/applications/2/tokens/"
},
"summary_fields": {
"organization": {
"id": 1,
"name": "Default",
"description": ""
},
"user_capabilities": {
"edit": true,
"delete": true
},
"tokens": {
"count": 0,
"results": []
}
},
"created": "2018-07-02T21:16:45.824400Z",
"modified": "2018-07-02T21:16:45.824514Z",
"name": "My Application",
"description": "",
"client_id": "Ecmc6RjjhKUOWJzDYEP8TZ35P3dvsKt0AKdIjgHV",
"client_secret": "7Ft7ym8MpE54yWGUNvxxg6KqGwPFsyhYn9QQfYHlgBxai74Qp1GE4zsvJduOfSFkTfWFnPzYpxqcRsy1KacD0HH0vOAQUDJDCidByMiUIH4YQKtGFM1zE1dACYbpN44E",
"client_type": "confidential",
"redirect_uris": "",
"authorization_grant_type": "password",
"skip_authorization": false,
"organization": 1
}
As shown in the example above, name
is the human-readable identifier of the application. The rest of the fields, like client_id
and redirect_uris
, are mainly used for OAuth2 authorization, which is covered later in Using OAuth 2 Token System for Personal Access Tokens (PAT).
The values for the client_id
and client_secret
fields are generated during creation and are non-editable identifiers of applications, while organization
and authorization_grant_type
are required upon creation and become non-editable.
Access rules for applications are as follows:
System administrators can view and manipulate all applications in the system
Organization administrators can view and manipulate all applications belonging to Organization members
Other users can only view, update, and delete their own applications, but cannot create any new applications
Tokens, on the other hand, are resources used to actually authenticate incoming requests and mask the permissions of the underlying user. There are two ways to create a token:
POST to the /api/v2/tokens/
endpoint with application
and scope
fields to point to the related application and specify token scope
POST to the /api/v2/applications/<pk>/tokens/
endpoint with the scope
field (the parent application will be automatically linked)
Individual tokens are accessible via their primary keys: /api/<version>/tokens/<pk>/
. Here is an example of a typical token:
{
"id": 4,
"type": "o_auth2_access_token",
"url": "/api/v2/tokens/4/",
"related": {
"user": "/api/v2/users/1/",
"application": "/api/v2/applications/1/",
"activity_stream": "/api/v2/tokens/4/activity_stream/"
},
"summary_fields": {
"application": {
"id": 1,
"name": "Default application for root",
"client_id": "mcU5J5uGQcEQMgAZyr5JUnM3BqBJpgbgL9fLOVch"
},
"user": {
"id": 1,
"username": "root",
"first_name": "",
"last_name": ""
}
},
"created": "2018-02-23T14:39:32.618932Z",
"modified": "2018-02-23T14:39:32.643626Z",
"description": "App Token Test",
"user": 1,
"token": "*************",
"refresh_token": "*************",
"application": 1,
"expires": "2018-02-24T00:39:32.618279Z",
"scope": "read"
},
For an OAuth 2 token, the only fully editable fields are scope
and description
. The application
field is non-editable on update, and all other fields are entirely non-editable, and are auto-populated during creation, as follows:
user
field corresponds to the user the token is created for, and in this case, is also the user creating the token
expires
is generated according to the Tower configuration setting OAUTH2_PROVIDER
token
and refresh_token
are auto-generated to be non-clashing random strings
Both application tokens and personal access tokens are shown at the /api/v2/tokens/
endpoint. The application
field in the personal access tokens is always null. This is a good way to differentiate the two types of tokens.
Access rules for tokens are as follows:
Users can create a token if they are able to view the related application; and are also able to create a personal token for themselves
System administrators are able to view and manipulate every token in the system
Organization administrators are able to view and manipulate all tokens belonging to Organization members
System Auditors can view all tokens and applications
Other normal users are only able to view and manipulate their own tokens
Note
Users can only view the token or refresh the token value at the time of creation only.
The easiest and most common way to obtain an OAuth 2 token is to create a personal access token at the /api/v2/users/<userid>/personal_tokens/
endpoint, as shown in this example below:
curl -XPOST -k -H "Content-type: application/json" -d '{"description":"Personal Tower CLI token", "application":null, "scope":"write"}' https://<USERNAME>:<PASSWORD>@<TOWER_SERVER>/api/v2/users/<USER_ID>/personal_tokens/ | python -m json.tool
You could also pipe the JSON output through jq
, if installed.
Following is an example of using the personal token to access an API endpoint using curl:
curl -k -H "Authorization: Bearer <token>" -H "Content-Type: application/json" -X POST -d '{}' https://tower/api/v2/job_templates/5/launch/
In Ansible Tower, the OAuth 2 system is built on top of the Django Oauth Toolkit, which provides dedicated endpoints for authorizing, revoking, and refreshing tokens. These endpoints can be found under the /api/v2/users/<USER_ID>/personal_tokens/
endpoint, which also provides detailed examples on some typical usage of those endpoints. These special OAuth 2 endpoints only support using the x-www-form-urlencoded
Content-type, so none of the api/o/*
endpoints accept application/json
.
Note
You can also request tokens using the /api/o/token
endpoint by specifying null
for the application type.
Alternatively, you can add tokens for users through the Tower User Interface, as well as configure the expiration of an access token and its associated refresh token (if applicable).
The scope of an OAuth 2 token is a space-separated string composed of valid scope keywords, ‘read’ and ‘write’. These keywords are configurable and used to specify permission level of the authenticated API client. Read and write scopes provide a mask layer over the Role-Based Access Control (RBAC) permission system of Ansible Tower. Specifically, a ‘write’ scope gives the authenticated user the full permissions the RBAC system provides, while a ‘read’ scope gives the authenticated user only read permissions the RBAC system provides. Note that ‘write’ implies ‘read’ as well.
For example, if you have administrative permissions to a job template, you can view, modify, launch, and delete the job template if authenticated via session or basic authentication. In contrast, if you are authenticated using OAuth 2 token, and the related token scope is ‘read’, you can only view, but not manipulate or launch the job template, despite being an administrator. If the token scope is ‘write’ or ‘read write’, you can take full advantage of the job template as its administrator.
To acquire and use a token, first create an application token:
Make an application with authorization_grant_type
set to password
. HTTP POST the following to the /api/v2/applications/
endpoint (supplying your own organization ID):
{
"name": "Admin Internal Application",
"description": "For use by secure services & clients. ",
"client_type": "confidential",
"redirect_uris": "",
"authorization_grant_type": "password",
"skip_authorization": false,
"organization": <organization-id>
}
Make a token and POST to the /api/v2/tokens/
endpoint:
{
"description": "My Access Token",
"application": <application-id>,
"scope": "write"
}
This returns a <token-value> that you can use to authenticate with for future requests (this will not be shown again).
Use the token to access a resource. The following uses curl as an example:
curl -H "Authorization: Bearer <token-value>" -H "Content-Type: application/json" -X GET https://<tower>/api/v2/users/
The -k
flag may be needed if you have not set up a CA yet and are using SSL.
To revoke a token, you can make a DELETE on the detail page for that token, using that token’s ID. For example:
curl -ku <user>:<password> -X DELETE https://<tower>/api/v2/tokens/<pk>/
Similarly, using a token:
curl -H "Authorization: Bearer <token-value>" -X DELETE https://<tower>/api/v2/tokens/<pk>/ -k
This page lists OAuth 2 utility endpoints used for authorization, token refresh, and revoke. The /api/o/
endpoints are not meant to be used in browsers and do not support HTTP GET. The endpoints prescribed here strictly follow RFC specifications for OAuth 2, so use that for detailed reference. The following is an example of the typical usage of these endpoints in Tower, in particular, when creating an application using various grant types:
Authorization Code
Password
Note
You can perform any of the application functions described here using the Tower User Interface. Refer to the Applications section of the Ansible Tower User Guide for more detail.