OAuth 2 is an open standard for authorization that enables third-party applications to obtain limited access to DigitalOcean user accounts, by delegating user authentication to DigitalOcean.
Developers must register their application to use OAuth. A registered application is assigned a client ID and client secret. The client secret should be kept confidential, and only used between the application and the DigitalOcean authorization server https://cloud.digitalocean.com/v1/oauth
.
The DigitalOcean OAuth API supports the Authorization Code flow, which is suitable for web applications running on a server. This is a description of the flow for third party applications.
Give the user an authorization link, which redirects the user to DigitalOcean and is composed of the authorize
endpoint with the appropriate parameters. Your application page in the DigitalOcean Control Panel contains a sample link without the scope
and state
parameters.
Auth Code Request Endpoint: https://cloud.digitalocean.com/v1/oauth/authorize
Parameters: Auth Code Request:
Name | Type | Description |
---|---|---|
client_id |
string | Required. The client ID that you received from DigitalOcean when you registered. |
redirect_uri |
string | Required. Must match the callback URL that you supplied during application registration. The callback URL where users will be sent after authorization. |
response_type |
string | Required. Must be set to “code” to request an authorization code. |
scope |
string | Optional. If not provided, scope defaults to “read”. The valid scopes are listed below. |
state |
string | Recommended. An unguessable random string, used to protect against request forgery attacks. |
prompt |
string | Optional. A space-separated list of strings that dictate how the user is requested to authorize their account. The valid prompt values are listed below. |
Here is an example of a request user authorization URL:
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=code
&client_id=4c413ac36ac22268
&redirect_uri=https://example.com/callback
&scope=read write
&state=0807edf7d85e5d
If the user authorizes the application, DigitalOcean redirects back to your redirect_uri
with an authorization code in a code
parameter (and a state
parameter, if you specified one in the authorization request). Make sure that the value of state
matches the one that was provided (if provided) in the previous step–if it does not, the process should be aborted as the request was created by third party.
Use the code
in your access token request, which is a POST request to the token
endpoint with the appropriate parameters.
https://cloud.digitalocean.com/v1/oauth/token
In addition to other information, the response includes two important items: access_token
and refresh_token
.
Name | Type | Description |
---|---|---|
grant_type |
string | Required. Must be set to authorization_code for an access token request. |
code |
string | Required. The code that you received as a response to Step 1. |
client_id |
string | Required. The client ID that you received from DigitalOcean when you registered. |
client_secret |
string | Required. The client secret that you received from DigitalOcean when you registered. |
redirect_uri |
string | Required. Must match the callback URL that you supplied during application registration. |
Here is an example access token request using curl
:
curl -X POST "https://cloud.digitalocean.com/v1/oauth/token?grant_type=authorization_code
&code=f252c4bd6b1b4d249b7
&client_id=4c413ac36ac22268
&client_secret=b05a2ad77b24f3
&redirect_uri=https://example.com/callback"
If the request was successful, the authorization server returns an access token grant that looks something like the following (JSON format):
{
"access_token": "doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "dor_v1_d6ce4b93104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2",
"scope": "read write",
"info": {
"name": "Sammy the Shark",
"email":"sammy@digitalocean.com",
"uuid":"9f06cff6-a636-11ec-9e9d-3381ceabe039"
}
}
When the user has authorized the application under a team context, the info
object will include team information as well:
{
"access_token": "doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "dor_v1_d6ce4b93104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2",
"scope": "read write",
"info": {
"name": "Sammy the Shark",
"email":"sammy@digitalocean.com",
"uuid":"9f06cff6-a636-11ec-9e9d-3381ceabe039",
"team_uuid": "a5e87c48-a636-11ec-a6ac-1323bf96ef4d",
"team_name": "My Team"
}
}
Now you may use the access token to make requests, on behalf of the user, from the resource server via the API (endpoint: https://api.digitalocean.com/v2/). For more information about making API requests, the full DigitalOcean API v2 documentation is available at our developer’s portal.
The access token may be used until it expires (30 days after being issued) or is otherwise invalidated (for example, user revoked or refresh token used).
Here is an example of using the access token ($TOKEN
) with DO API V2 to list Droplets using curl
:
curl -X GET "https://api.digitalocean.com/v2/droplets" \
-H "Authorization: Bearer $TOKEN"
The DigitalOcean OAuth API also supports the implicit authorization flow. This is useful for client-side applications such as mobile or desktop clients where the client secret should not be stored on the user’s device.
Give the user an authorization link, which redirects them to DigitalOcean and is composed of the authorize endpoint with the appropriate parameters specifying the response_type
as token
.
Token Request Endpoint: https://cloud.digitalocean.com/v1/oauth/authorize
Parameters: Token Request
Name | Type | Description |
---|---|---|
client_id |
string | Required. The client ID that you received from DigitalOcean when you registered. |
redirect_uri |
string | Required. Must match the callback URL that you supplied during application registration. The callback URL where users will be sent after authorization. |
response_type |
string | Required. Must be set to “token” to request an OAuth token. |
scope |
string | Optional. If not provided, scope defaults to “read”. The valid scopes are listed below. |
state |
string | Recommended. An unguessable random string, used to protect against request forgery attacks. |
Here is an example authorization link:
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=token
&client_id=4c413ac36ac22268
&redirect_uri=https://example.com/callback
&scope=read%20write
&state=0807edf7d85e5d
If the user authorizes the application, DigitalOcean redirects back to your redirect_uri
with an OAuth token in the token
parameter (and a state
parameter, if you specified one in the authorization request). Make sure that the value of state matches the one that was provided (if provided) in the previous step–if it does not, the process should be aborted as the request was created by third party. Additionally, the expires_in
parameter indicates the time remaining before token expires in seconds.
Here is an example callback (access token grant):
https://example.com/callback#access_token=doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381
&token_type=bearer
&expires_in=2592000
&state=0807edf7d85e5d
Now you may use the access token to make requests, on behalf of the user, from the resource server via the API (endpoint: https://api.digitalocean.com/v2/). For more information about making API requests, the full DigitalOcean API v2 documentation is available at our developer’s portal.
The access token may be used until it expires (30 days after being issued) or is otherwise invalidated (for example, user revoked or refresh token used).
Here is an example of using the access token ($TOKEN
) with DO API V2 to list Droplets using curl
:
curl -X GET "https://api.digitalocean.com/v2/droplets" \
-H "Authorization: Bearer $TOKEN"
If you would like to request a new access token (and new refresh token), you may do so by sending the authorization server a token refresh request. A typical reason for refreshing a token is that the original access token has expired. A refresh token may only be used once, and using it invalidates the access token that it was issued with.
Use the refresh_token
in your token refresh request, which is a POST request to the token
endpoint with the appropriate parameters.
The endpoint is https://cloud.digitalocean.com/v1/oauth/token
, which has the following parameters:
Name | Type | Description |
---|---|---|
grant_type |
string | Required. Must be set to refresh_token for a token refresh request. |
refresh_token |
string | Required. The refresh_token that was received with the original access token. |
The refresh token response looks like the normal access token grant. It includes new access and refresh tokens.
Example Token Refresh Request
Here is an example token refresh request:
curl -X POST "https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&refresh_token=00a3aae641658d"
If the request was successful, the authorization server will return a JSON body including a new access token grant:
{
"access_token": "doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "dor_v1_d6ce4b93104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2",
"scope": "read write",
"info": {
"name": "Sammy the Shark",
"email":"sammy@digitalocean.com",
"uuid":"9f06cff6-a636-11ec-9e9d-3381ceabe039"
}
}
When the user has authorized the application under a team context, the info
object will include team information as well:
{
"access_token": "doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381",
"token_type": "bearer",
"expires_in": 2592000,
"refresh_token": "dor_v1_d6ce4b93104521c47be0b580e9296453ef4y319b02b5513469f0ec72d99af2e2",
"scope": "read write",
"info": {
"name": "Sammy the Shark",
"email":"sammy@digitalocean.com",
"uuid":"9f06cff6-a636-11ec-9e9d-3381ceabe039",
"team_uuid": "a5e87c48-a636-11ec-a6ac-1323bf96ef4d",
"team_name": "My Team"
}
}
If you would like to revoke an access token, you may do so by sending the authorization server a token revocation request. Once a token is revoked, it is invalidated and may not be used again.
Use the access_token
in your token revocation request, which is a POST request to the revoke
endpoint with the appropriate parameters.
The endpoint is https://cloud.digitalocean.com/v1/oauth/revoke
, which has the following parameters:
Name | Type | Description |
---|---|---|
token |
string | Required. Must be set to the value of the access token to revoke. |
The response to this request is an empty JSON object.
Here is an example of sending a token revocation request, using the token itself as the bearer token, using curl
:
curl -X POST https://cloud.digitalocean.com/v1/oauth/revoke \
-d token=doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381 \
-H "Authorization: Bearer doo_v1_4ea90994efe8999d0892b6069bc754a78c656f8e843361e1e4d1cd04ac85c381"
Scopes limit the type of access that an access token will allow. The DigitalOcean API supports two scopes, “read” and “read write”.
Name | Description |
---|---|
(no scope) | Defaults to read scope. |
read | Grants read-only access to user account. This allows actions that can be requested using the GET and HEAD methods. |
read write | Grants read/write access to user account, that is, full access. This allows actions that can be requested using the DELETE, PUT, and POST methods, in addition to the actions allowed by the read scope. |
The prompt
query parameter allows the requesting application to define the behavior of the authorization page, as shown to the user when they authorize an OAuth application.
Name | Description |
---|---|
(no prompt) | Defaults to select_account . |
none |
If the user is signed in, and has previously authorized the OAuth application, they will be directed back to the valid redirect_url with a new token. A hint can be used by specifying an i query parameter, being the first 6 characters of an expected account UUID. If the user is signed in, and they have not previously authorized the application, they will be redirected back to the valid redirect_url with error=consent_required query parameter. If the user is not signed in, they will be redirected back to the valid redirect_url with error=login_required . |
select_account |
Default prompt. If a user is not signed in, they will be required to sign in. Signed in users must authorize the OAuth application before proceeding. |
There are several things that can go wrong during the authorization step. Here are a few of the more common ones:
If the user denies authorization, they will be redirected to your callback URL with an error_description
parameter:
https://example.com/callback?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.
Correct this by having your user authorize your application.
If the callback URL in your authorization code link does not match your registered callback URL, the user will be displayed a page with the following error:
An error has occurred The redirect uri included is not valid.
Correct this by replacing the value of the redirect_uri
parameter in your authorization code link with your application’s registered callback URL.
If an invalid scope is specified in your authorization code link, the user will be displayed a page with the following error:
An error has occurred The requested scope is invalid, unknown, or malformed.
Correct this by using a valid scope in your authorization link. The valid scopes are listed in the Scopes section, above.
There are several things that can go wrong during the access token request step. Here are a few of the more common ones:
If your access token request contains a redirect_uri
that does not match your registered callback URL, or if your authorization grant (code
) is invalid (already used, expired, revoked), you will receive the following error:
{
"error":"invalid_grant",
"error_description":"The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}
Correct this by ensuring (a) your redirect_uri
value matches your registered callback URL. If the callback URL was not the problem, a new code
should be requested by starting the authorization process over. Also of note, authorization codes are valid for 10 minutes after being issued.
If your client credentials are incorrect (client ID or client secret), you will receive the following message:
{
"error":"invalid_client",
"error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."
}
Correct this by ensuring your request contains client credentials that match the client ID and client secret listed in your application’s registration page (located in the DigitalOcean Control Panel).
It is possible for the user to change the scope of the authorization request by modifying the value of the scope
parameter in the authorization link that you provided them. Therefore, to prevent application errors due to insufficient scope, it is recommended that you verify that the scope of the access token grant matches the scope that was originally requested.