Authentication and Authorization

Any Swift authentication/authorization middleware must follow the protocols of Keystone, the official OpenStack identity service. If you decide to use the Keystone Swift auth middleware, all versions of the auth protocol will be supported. (Currently, Keystone has three versions of their protocol.) If you choose another auth system, it may only support a subset of those protocol versions.

The SwiftStack Auth middleware supports two versions of the auth protocol, known as "V1 Auth" and "V2 Auth".

V1 Auth

For a user to authenticate to a cluster, they must know three pieces of information:
  1. Username
  2. Password
  3. AUTH_URL (displayed on the Cluster Monitor page)

The user will provide the information using one of two commands, swift or curl, and they will get information about their Swift account in return. Two key pieces of information returned are the AUTH_TOKEN and STORAGE_URL.

In the examples shown, the user provides "superman" for both the username and password.

Authentication via swift command

swift -A <AUTH_URL> -U <USERNAME> -K <PASSWORD> stat -v

It returns several pieces of information, including the AUTH_TOKEN and STORAGE_URL.

$ swift -A http://swift.example.com/auth/v1.0 -U superman -K superman \
    stat -v
StorageURL: http://swift.example.com/v1/AUTH_superman
Auth Token: AUTH_tkb5bab9e25a274b4a853fe2587b5dc8f9
   Account: AUTH_superman
Containers: 0
   Objects: 0
     Bytes: 0
Content-Type: text/plain; charset=utf-8
X-Timestamp: 1375225766.50237
X-Trans-Id: tx88ac2ec242fd4af6a1e3d-0051f847a6
X-Put-Timestamp: 1375225766.50237

Authentication via curl command

curl -i -H "X-Auth-User: <USERNAME>" -H "X-Auth-Key: <PASSWORD>" <AUTH_URL>

It returns several pieces of information, including the AUTH_TOKEN and STORAGE_URL.

Tip

Under SwiftStack Auth, the storage URL always ends in a Swift Storage Account name that starts with AUTH_ followed by the username.

$ curl -i -H "X-Auth-User: superman" -H "X-Auth-Key: superman" \
    https://swift.example.com/auth/v1.0/
HTTP/1.1 200 OK
X-Storage-Url: https://swift.example.com/v1/AUTH_superman
X-Auth-Token: AUTH_tke43b35e50eab4eecaf72221dc8f2f3a7
Content-Type: text/html; charset=UTF-8
X-Storage-Token: AUTH_tke43b35e50eab4eecaf72221dc8f2f3a7
X-Trans-Id: txe66f5a0dde8c41be9c487-0051f2f216
Content-Length: 0
Date: Fri, 26 Jul 2013 22:03:02 GMT

V2 Auth

Just like V1 Auth, three pieces of information are required for a user to authenticate to a cluster:

  1. Username
  2. Password
  3. AUTH_URL (same as the V1 Auth URL from the Cluster Monitor page except the v1.0 at the end is replaced with v2.0, for example, http://swift.example.com/auth/v2.0)

However, unlike V1 Auth, there is an additional item which can be provided: the tenant, which is a general Keystone concept which means account in the specific case of Swift. The tenant affects which storage URL you will get back in the response to your auth request. If you don't specify a tenant, you will get the default storage URL for your username, as in V1 Auth. For example, if your username is alice and your auth middleware uses the default prefix of AUTH_, then your default account name is AUTH_alice, and you will get back a storage URL of the form https://swift.example.com/v1/AUTH_alice.

However, what if Alice wants to view data in Bob's account, assuming that Bob has given her access via a container ACL or account ACL? (See Container ACLs and Account ACLs.) Or what if the Swift cluster has been set up so that users don't each get their own accounts, but rather share project-based accounts such as AUTH_project1?

Using V1 Auth, Alice (or a tool she uses) must manually examine the returned storage URL, remove her account's name, and append the name of the account she wants to access. (This tends to work in practice, but it is not guaranteed -- the other account might be accessed via a different server, for instance!) However, V2 Auth allows her to get the correct storage URL directly, by providing as input the tenant (account) that she is interested in accessing. Typical tenants might include AUTH_alice (to access her own account) or AUTH_shared (to access a shared account) or LDAP_bob (to access Bob's account, which is authenticated via LDAP).

Authentication via "swift" command

The swift command uses different command-line flags to specify V2 Auth params. To specify that you want to use the V2 Auth protocol, use a command line such as the following:

swift --os-auth-url <AUTH_URL> \
    --os-username <USERNAME> \
    --os-password <PASSWORD> \
    --os-tenant-name <TENANT> \
    stat -v

Alternatively, if you will be invoking the swift command several times and want to save some typing, you can store the input parameters in environment varables:

export OS_USERNAME=<username>
export OS_PASSWORD=<password>
export OS_TENANT_NAME=<tenant>
export OS_AUTH_URL=<auth_url>
swift stat -v

The output will be exactly the same as for V1 Auth.

Authentication via curl command

Where V1 Auth uses HTTP headers in a GET command, V2 Auth uses a POST command with JSON containing the credentials as the request body. Since it's easy to make a typo such as missing or misplacing a closing brace, we recommend that if you use raw curl commands for V2 Auth requests, you put your input in a file.

The format of the JSON object containing the credentials is as follows:

{
   "auth" : {
       "passwordCredentials" : {
           "username" : "<username>",
           "password" : "<password>"
       },
       "tenantName" : "<tenant>"
   }
}

If the above text is stored in a file named /tmp/creds, then you can authenticate with the V2 Auth protocol using the following curl command:

curl -i <AUTH_URL> -d @/tmp/creds

This will return a blob of valid JSON, but it is difficult to read because of its lack of formatting. To see a nicely-formatted version of the auth response, use a formatter such as json_pp:

curl -s <AUTH_URL> -d @/tmp/creds | json_pp

Since json_pp requires valid JSON as input, you must use the -s flag with curl to suppress the HTTP headers. However, this means that you won't see the HTTP return code, and it will not be obvious whether the auth request succeeded. Specifically, the response body for an invalid auth request is the string "Invalid credentials", which is not valid JSON, so a program such as json_pp will throw an error when trying to format it.

With this in mind, the output of a successful V2 auth request looks like this:

{
   "access" : {
      "token" : {
         "id" : "AUTH_tk4602560647c640de86924e2f28716b46"
         "expires" : "2015-01-22T00:04:06Z",
         "tenant" : {
            "id" : "AUTH_sharedacct",
            "name" : "AUTH_sharedacct"
         },
      },
      "user" : {
         "name" : "alice",
         "id" : "alice"
         "roles" : [
            {
               "id" : "alice",
               "name" : "alice"
            },
            {
               "name" : "AUTH_alice",
               "id" : "AUTH_alice"
            },
            {
               "name" : ".reseller_admin",
               "id" : ".reseller_admin"
            }
         ],
      },
      "serviceCatalog" : [
         {
            "endpoints" : [
               {
                  "region" : "default",
                  "publicURL" : "http://192.168.22.200/v1/AUTH_sharedacct",
                  "versionId" : 1,
                  "tenantId" : "AUTH_sharedacct"
               },
               {
                  "publicURL" : "http://192.168.22.200/v1/AUTH_alice",
                  "region" : "default",
                  "tenantId" : "AUTH_alice",
                  "versionId" : 1
               }
            ],
            "name" : "Swift Object Storage (http://192.168.22.200)",
            "type" : "object-store"
         }
      ]
   }
}