Skip to content

Authentication

Anton Kropp edited this page Feb 27, 2016 · 14 revisions

CassieQ has three forms of authentication

  • Global account access via key
  • Signed requests using an account key
  • Granular access via permission query string claims by account

All configuration is done via the CassieQ admin port API

Creating an account

To create an account you can use the api exposed on the admin port.

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '"test"' 'http://localhost:8081/admin/api/v1/accounts'

{
  "accountName": "test",
  "keys": {
    "primary": "Ez_2IXF07tmBA0a93YEXEqglPX-BbY6bXMrq594dixuYh7NyAY5AP0tDH-gn5xweOx88fuJV4XtPMK0DjTINOA",
    "secondary": "zLhMSpyExx8XYTLS1y8LW6gdp6maCbD90mkFacyNWfdamM2pYAq45HEN4yLaVx0jQslbkNZrJQcAjUs-IrS7DQ"
  }
}

Claims

Claims by account is the preferred method, and gives you the most granular authorization control to your account. Claims are passed in the url as query string parameters. To generate signed claims for a user, you can create a named account key for that group (such as "ui-members") and create permission based url params using that key. This may look of the form:

?auth=puag&sig=NygRs9GBh9n_i2s7KTMof0us-RXm5nt3RnlWKb3N15A

Which can be appended to any API url. The auth is of a simple form (concatenation of single character based permissions) which in this scenario indicates

PutMessage (p)
UpdateMessage (u)
AckMessage (a)
GetQueueInformation (g)

For a full list of granular permissions go to the admin panel permissions api.

The advantage to transparent signature based auth is that you can pass the url to multiple teams and share common auth without leaking secrets. To revoke access, delete the key that was used to generate the signature.

Example

First create an account (follow instructions above,) and then you can create granular permissions for just "update" and "ack" (for example):

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ 
  "accountName": "test", 
  "keyName": "primary",
  "levels": ["u", "a" ] 
}' 'http://localhost:8081/admin/api/v1/permissions'

{
  "queryParam": "auth=ua&sig=cXMI49mULx0Abi0CU2kTQtZ1edzuP_gxtNJ6hcBrVXg"
}

Any user who appends this query param to the end of an API will be authenticated to do update and ack actions ONLY on the test account.

Signing Requests

Authenticating to CassieQ using signed HTTP requests is the simplest secure method of authentication. This also provides full access by account but doesn't expose your access key publicly.

Requests are signed using HMAC-SHA256 and the following format (newlines using \n)

<AccountName>\n
<RequestMethod>\n
<RequestPath>\n
<RequestTime>

Request time is formatted as ISO yyyy-MM-dd'T'HH:mm:ssZZ UTC and its raw value should be included as header x-cassieq-request-time

For example

2 > POST http://localhost:20531/api/v1/accounts/testAccount/queues
2 > Accept-Encoding: gzip
2 > Authorization: Signed MUaxxXIIuQ_z04G_mLLAOb0bd73khxUat7G-X6fhxnI
2 > Connection: keep-alive
2 > Content-Length: 278
2 > Content-Type: application/json; charset=UTF-8
2 > Host: localhost:20531
2 > User-Agent: okhttp/2.5.0
2 > x-cassieq-request-time: 2016-02-27T20:54:44Z
{
  "queueName" : "testQueue"
}

Notice the Authorization: Signed block. The signature is computed by signing the following newline delimited block:

testAccount\n
POST\n
/api/v1/accounts/testAccount/queues\n
2016-02-27T20:54:44Z

Authentication is accomplished by taking a signature of this string and putting it in the authorization header as

Authorization: Signed <signature>

If you do not send the x-cassieq-request-time header you must still include a time value in the signature using the known value of UTC 0

1969-12-31T16:00:00-08:00

Key based authentication

(Using this method of authentication should be avoided)

This is by far the easiest method, but also the least secure, since account keys are transmitted with each request. This grants full access by account. This was added for testing purposes only to make the swagger ui would work.

Key based authentication is done via passing an account key in the authorization header such as

Authorization: Key <your account key>

This is not the recommended authentication case but is supported and is currently the only way to experiment with the swagger API. Put your access key into the swagger api key section for access.

Key rotation

CassieQ supports multiple keys per account, so you can safely rotate keys without breaking current consumers. To rotate keys, create a new key and re-generate permissions. Leave the old key intact. Distribute the new permissions query params to all your clients. When you are satisfied that the expected clients have the new credentials, you can delete the old key.

Clone this wiki locally