Token

Ubuntu SSO uses tokens of different kinds for different aspects of the service. Currently it knows about the following types of tokens

OAuth token

An OAuth token represents a token used to sign requests using the OAuth 1.0a spec.

Data structure

  • consumer_key
  • consumer_secret
  • token_key
  • token_secret
  • token_name
  • date_created
  • date_updated

Use cases

Create an oauth token

POST /api/v2/tokens/oauth

Creates a new OAuth token

Form Parameters:
 
  • email – user’s email address
  • password – user’s password
  • token_name – a name for the token
  • otp – one-time password (optional)
Status Codes:

A consumer requesting an authentication token must provide a token name. This name will be used by the user to identify the token when doing token management. The recommended scheme for token names is “application_name-device_name”.

This allows a user to easily identify which tokens belong to which application or to which device. For example they may wish to revoke all tokens for a particular application across their devices, or revoke all tokens on a particular device.

If a token name is requested that already exists (for this user) then the existing token will be returned (status code 200) instead of a new one being created (status code 201).

If an otp (one-time-password) is provided then it will be checked against any two factor devices registered for the account. If the otp does not match any devices then a 403 will be returned.

If an otp is required for the account, but not sent, then a 401 will be returned.

Errors

  • INVALID_CREDENTIALS: Provided email/password is not correct.

    Error status code 401.

    This error has no additional fields in extra.

  • ACCOUNT_SUSPENDED: Account has been suspended.

    Error status code 403.

    This error has no additional fields in extra.

  • ACCOUNT_DEACTIVATED: Account has been deactivated.

    Error status code 403.

    This error has no additional fields in extra.

  • EMAIL_INVALIDATED: This email address has been invalidated.

    Error status code 403.

    This error has no additional fields in extra.

  • TWOFACTOR_REQUIRED: 2-factor authentication required.

    Error status code 401.

    This error has no additional fields in extra.

  • TWOFACTOR_FAILURE: The provided 2-factor key is not recognised.

    Error status code 403.

    This error has no additional fields in extra.

  • PASSWORD_POLICY_ERROR: The user’s password doesn’t comply with the security constraints in force for the account. It must be reset via the web.

    Error status code 403.

    The extra field includes:

    • location: the domain to visit via the web to reset the password
    • reason: the reason why the password doesn’t comply with the policy
  • TOO_MANY_REQUESTS: Too many requests from the same IP address.

    Error status code 429.

    This error has no additional fields in extra.

Examples

Request:

POST /api/v2/tokens/oauth HTTP/1.1
Host: login.ubuntu.com
Accept: application/json
Content-Type: application/json

{
  "email": "foo@example.com",
  "password": "thepassword",
  "token_name": "the-name"
}

If 2-factor authentication is required:

POST /api/v2/tokens/oauth HTTP/1.1
Host: login.ubuntu.com
Accept: application/json
Content-Type: application/json

{
  "email": "foo@example.com",
  "password": "thepassword",
  "token_name": "the-name",
  "otp": "123456"
}

Response:

HTTP/1.1 201 CREATED
Content-Type: application/json
Location: /api/v2/tokens/oauth/the-key

{
  "href": "https://login.ubuntu.com/api/v2/tokens/oauth/the-key",
  "token_key": "token-key",
  "token_secret": "token-secret",
  "token_name": "token-name",
  "consumer_key": "consumer-key",
  "consumer_secret": "consumer-secret"
  "date_created": "2013-01-11 12:43:23",
  "date_updated": "2013-01-11 12:43:23"
}

If credentials don’t match:

HTTP/1.1 401 UNAUTHORIZED
Content-Type: application/json

{
  "code": "INVALID_CREDENTIALS",
  "message": "Your email/password isn't correct.",
  "extra": {}
}

If 2-factor authentication is required:

HTTP/1.1 401 UNAUTHORISED
Content-Type: application/json

{
  "code": "TWOFACTOR_REQUIRED",
  "message": "This account requires 2-factor authentication.",
  "extra": {}
}

Password reset token

A password reset token represents a token used to request a password reset. This token will be generated and an email will be sent to the user’s preferred email address including a value that has to be provided when specifying the new password.

Data structure

  • email

Use cases

Create a password reset token

POST /api/v2/tokens/password

Creates a new password reset token

Form Parameters:
 
  • email – user’s email address
Status Codes:

A consumer requesting a password reset token must provide an email address. This email address will be used to look up the user’s account in order to send the user an email containing a token that must be provided when setting the new password.

To prevent spamming unknowing users by sending multiple password reset emails, only a maximum amount of non-consumed tokens will be allowed to exist at any given time. When such limit is reached, attempting to create a new token will result in an error response.

Errors

  • ACCOUNT_SUSPENDED: Account has been suspended.

    Error status code 403.

    This error has no additional fields in extra.

  • ACCOUNT_DEACTIVATED: Account has been deactivated.

    Error status code 403.

    This error has no additional fields in extra.

  • EMAIL_INVALIDATED: This email address has been invalidated.

    Error status code 403.

    This error has no additional fields in extra.

  • CAN_NOT_RESET_PASSWORD: Can not reset password.

    Error status code 403.

    This error has no additional fields in extra.

  • TOO_MANY_TOKENS: Too many non-consumed tokens exist. Further token creation is not allowed until existing tokens expire or are consumed.

    Error status is 403.

    This error has no additional fields in extra.

Examples

Request:

POST /api/v2/tokens/password HTTP/1.1
Host: login.ubuntu.com
Accept: application/json
Content-Type: application/json

{
  "email": "foo@example.com"
}

Response:

HTTP/1.1 201 CREATED
Content-Type: application/json
Location: /api/v2/tokens/password/the-key

{
  "email": "foo@example.com"
}

If too many tokens exist:

HTTP/1.1 403 FORBIDDEN
Content-Type: application/json

{
  "code": "TOO_MANY_TOKENS",
  "message": "Too many non-consumed tokens exist. Further token creation is not allowed until existing tokens are consumed.",
  "extra": {}
}

Macaroon

A macaroon is a bearer token with fine-grained constraints. See the original paper for details.

Ubuntu SSO issues discharge macaroons, which can be bound to macaroons issued by other cooperating services to prove the user’s identity.

Use cases

Issue a discharge macaroon

POST /api/v2/tokens/discharge

Issues a new discharge macaroon

Form Parameters:
 
  • email – user’s email address
  • password – user’s password
  • caveat_id – the caveat ID addressed to Ubuntu SSO from the macaroon that is to be discharged
  • otp – one-time password (optional)
Status Codes:

The service that issued the macaroon that this discharge is to be bound to should have included a caveat in that macaroon addressed to Ubuntu SSO. To issue an appropriate discharge macaroon, the caller must extract the ID of this caveat. This can be done in Python as follows:

from pymacaroons import Macaroon

def extract_caveat_id(macaroon_raw):
    macaroon = Macaroon.deserialize(macaroon_raw)
    for caveat in macaroon.caveats:
        if caveat.location == 'login.ubuntu.com':
            return caveat.caveat_id
    else:
        raise ValueError('No login.ubuntu.com caveat found')

If an otp (one-time-password) is provided then it will be checked against any two factor devices registered for the account. If the otp does not match any devices then a 403 will be returned.

If an otp is required for the account, but not sent, then a 401 will be returned.

Errors

  • INVALID_CREDENTIALS: Provided email/password is not correct.

    Error status code 401.

    This error has no additional fields in extra.

  • ACCOUNT_SUSPENDED: Account has been suspended.

    Error status code 403.

    This error has no additional fields in extra.

  • ACCOUNT_DEACTIVATED: Account has been deactivated.

    Error status code 403.

    This error has no additional fields in extra.

  • EMAIL_INVALIDATED: This email address has been invalidated.

    Error status code 403.

    This error has no additional fields in extra.

  • TWOFACTOR_REQUIRED: 2-factor authentication required.

    Error status code 401.

    This error has no additional fields in extra.

  • TWOFACTOR_FAILURE: The provided 2-factor key is not recognised.

    Error status code 403.

    This error has no additional fields in extra.

  • PASSWORD_POLICY_ERROR: The user’s password doesn’t comply with the security constraints in force for the account. It must be reset via the web.

    Error status code 403.

    The extra field includes:

    • location: the domain to visit via the web to reset the password
    • reason: the reason why the password doesn’t comply with the policy
  • TOO_MANY_REQUESTS: Too many requests from the same IP address.

    Error status code 429.

    This error has no additional fields in extra.

Examples

Request:

POST /api/v2/tokens/discharge HTTP/1.1
Host: login.ubuntu.com
Accept: application/json
Content-Type: application/json

{
  "email": "foo@example.com",
  "password": "thepassword",
  "caveat_id": "{\"secret\": \"thesecret\", \"version\": 1}"
}

If 2-factor authentication is required:

POST /api/v2/tokens/discharge HTTP/1.1
Host: login.ubuntu.com
Accept: application/json
Content-Type: application/json

{
  "email": "foo@example.com",
  "password": "the-password",
  "caveat_id": "{\"secret\": \"the-secret\", \"version\": 1}",
  "otp": "123456"
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "discharge_macaroon": "the-macaroon"
}

If credentials don’t match:

HTTP/1.1 401 UNAUTHORIZED
Content-Type: application/json

{
  "error_list": [
    {
      "code": "invalid-credentials",
      "message": "Provided email/password is not correct."
    }
  ]
}

If 2-factor authentication is required:

HTTP/1.1 401 UNAUTHORIZED
Content-Type: application/json

{
  "error_list": [
    {
      "code": "twofactor-required",
      "message": "2-factor authentication required."
    }
  ]
}

Refresh a discharge macaroon

POST /api/v2/tokens/refresh

Refreshes a discharge macaroon

Form Parameters:
 
  • discharge_macaroon – the serialized macaroon to be refreshed
Status Codes:

Discharge macaroons are time-limited and must eventually be refreshed. The need for this will be indicated by an error response from the cooperating service. When this happens, the caller should send the old discharge macaroon to this endpoint, which will issue a refreshed version if the original credentials are still valid.

Among other reasons, the discharge macaroon may fail to verify if the user’s password has changed since it was issued. In this case, the caller must request a new discharge macaroon.

Errors

  • INVALID_CREDENTIALS: The provided discharge macaroon is invalid, or the user’s password has changed since the discharge macaroon was issued.

    Error status code 401.

    This error has no additional fields in extra.

  • ACCOUNT_DEACTIVATED: Account has been deactivated.

    Error status code 403.

    This error has no additional fields in extra.

Examples

Request:

POST /api/v2/tokens/refresh HTTP/1.1
Host: login.ubuntu.com
Accept: application/json
Content-Type: application/json

{
  "discharge_macaroon": "the-old-macaroon"
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "discharge_macaroon": "the-new-macaroon"
}

If the user’s password has changed:

HTTP/1.1 401 UNAUTHORIZED
Content-Type: application/json

{
  "error_list": [
    {
      "code": "invalid-credentials",
      "message": "Provided email/password is not correct."
    }
  ]
}