Swift ACL usage examples

This blog post is a reminder for swift ACL usage. ACLs in swift are set up by the acl.py middleware. The ACL let the account (or tenant) owner set R/W access rights for authenticated users or even unauthenticated access. The later is really cool to configure data access for anyone. Below we’ll mostly use python-swiftclient CLI to set the ALCs so it’s better to mention that the headers involved in ACL configuration are X-Container-Read and X-Container-Write.

The examples are performed against a devstack configuration with keystone. Here we prepare our test environment:

Create a new user called ‘demouser2′:

$ source openrc admin admin
$ keystone  user-role-list --user demouser2 --tenant demo

For a non privileged user (we don't provide any role to demouser2) in an account the operations on swift account is forbidden :

$ swift --os-tenant-name=demo --os-username=demouser2 --os-password=demouser2 --os-auth-url=http://localhost:5000/v2.0 stat
Account HEAD failed: http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477 403 Forbidden
$ swift --os-tenant-name=demo --os-username=demouser2 --os-password=demouser2 --os-auth-url=http://localhost:5000/v2.0 list
Account GET failed: http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477?format=json 403 Forbidden  [first 60 chars of response] Forbidden Access was denied to this resourc

Create a container in demo account and push an object :

swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 post container
swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 upload container stackrc

To allow access to that container for user demouser2 we must set the ACL with tenant:user. Here 'demo:demouser2' (if just the tenant is specifed then all users under that tenant will be allowed):

swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 post container -r demo:demouser2
swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 stat container 
  Account: AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477
Container: container
  Objects: 1
    Bytes: 9673
 Read ACL: demo:demouser2
Write ACL: 
  Sync To: 
 Sync Key: 
Accept-Ranges: bytes
X-Timestamp: 1374660280.52319
X-Trans-Id: tx410a244a56e5488da1ba12234e31eb3a
Content-Type: text/plain; charset=utf-8

demouser2 is now able to stat and list the container:

$ swift --os-tenant-name=demo --os-username=demouser2 --os-password=demouser2 --os-auth-url=http://localhost:5000/v2.0 list container
stackrc
$ swift --os-tenant-name=demo --os-username=demouser2 --os-password=demouser2 --os-auth-url=http://localhost:5000/v2.0 stat container
  Account: AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477
Container: container
  Objects: 1
    Bytes: 9673
 Read ACL: 
Write ACL: 
  Sync To: 
 Sync Key: 
Accept-Ranges: bytes
X-Timestamp: 1374660280.52319
X-Trans-Id: tx3bc153f84cb84b4f864c704641077490
Content-Type: text/plain; charset=utf-8

Beside of giving rights to an authenticated user, the account owner can set the container for public access:

$ swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 post container -r '.r:*'
$ swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 stat container
  Account: AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477
Container: container
  Objects: 1
    Bytes: 9673
 Read ACL: .r:*
Write ACL: 
  Sync To: 
 Sync Key: 
Accept-Ranges: bytes
X-Timestamp: 1374660280.52319
X-Trans-Id: txb319121498b742fea15f493ddf67f43d
Content-Type: text/plain; charset=utf-8

Object access are successful with any HTTP client (we don't provide any token):

$ curl http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container/stackrc
$ curl -I http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container/stackrc

If we want to allow container listing, ie being able to list objects in a container or even retrieving container stats we must add the .rlistings ACL.

$ swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 post container -r '.r:*,.rlistings'
$ curl -H'Accept: application/json' http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container
[{"hash": "a6e2a0d0cfe5732321366269cb8aec11", "last_modified": "2013-07-24T12:41:20.780320", "bytes": 9673, "name": "stackrc", "content_type": "application/octet-stream"}]
$ curl -I  http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container
HTTP/1.1 204 No Content
Content-Length: 0
X-Container-Object-Count: 1
Accept-Ranges: bytes
X-Timestamp: 1374660280.52319
X-Container-Bytes-Used: 9673
Content-Type: text/plain; charset=utf-8
X-Trans-Id: tx66f89632880c4410851e4d0f9db0cfe0
Date: Wed, 24 Jul 2013 13:10:19 GMT

The '.r' ACL stands for Referer. Swift look at the "Referer" header to allow or not the request.

$ swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 post container -r '.r:.openstack.org,.rlistings'

Be trying one of our previous commands, the request is now forbidden.

$ curl http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container
Unauthorized This server could not verify that you are authorized to access the document you requested.

The request will be allowed when the Referer header is set:

$ curl -I -H 'Referer: http://docs.openstack.org' http://192.168.56.102:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container
HTTP/1.1 204 No Content
Content-Length: 0
X-Container-Object-Count: 1
Accept-Ranges: bytes
X-Timestamp: 1374660280.52319
X-Container-Bytes-Used: 9673
Content-Type: text/plain; charset=utf-8
X-Trans-Id: tx6e028ebb44a341e28025b797572ffcea
Date: Wed, 24 Jul 2013 13:18:31 GMT

For write ACLs we can configure access for authenticated user. Note that Referer rule in the write ACL is not allowed. For those examples we'll use curl instead of swift client.

$ swift --os-tenant-name=demo --os-username=demo --os-password=wxcvbn --os-auth-url=http://localhost:5000/v2.0 stat container
  Account: AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477
Container: container
  Objects: 3
    Bytes: 10724
 Read ACL: 
Write ACL: demo:demouser2
  Sync To: 
 Sync Key: 
Accept-Ranges: bytes
X-Timestamp: 1374660280.52319
X-Trans-Id: tx09032c7d33824ec0a7d4133b7e9d6fc9
Content-Type: text/plain; charset=utf-8

Retrieve the demouser2 token against keystone:

$ T=$(keystone --os-tenant-name=demo --os-username=demouser2 --os-password=demouser2 --os-auth-url=http://localhost:5000/v2.0 token-get | awk '/ id / {print $4}')

The object download is forbidden as there is no rule in read ACL:

$ curl -i -XGET -H "X-Auth-Token: $T" http://localhost:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container/openrc
HTTP/1.1 403 Forbidden
Content-Length: 73
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txcf044ca23149415787950de5a5d5c3d4
Date: Wed, 24 Jul 2013 15:07:02 GMT

Finally the object PUT work as expected:

$ curl -i -XPUT -H "X-Auth-Token: $T" --data-binary "bouh" http://localhost:8080/v1/AUTH_cbd3ac87d06b4f73b096ae2d4bcbb477/container/openrc
HTTP/1.1 201 Created
Last-Modified: Wed, 24 Jul 2013 15:07:07 GMT
Content-Length: 0
Etag: c9c5384adec41a13eea91ed4d20d809e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx9ad48e4b965a4e119d6d85a436a3896d
Date: Wed, 24 Jul 2013 15:07:07 GMT

One thought on “Swift ACL usage examples

  1. Pingback: OpenStack Community Weekly Newsletter (July 19 – 26) » The OpenStack Blog

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>