Step by step permissions API tutorial

Let’s use one of the application examples: using Kinto as a storage API for a blog application.

Note

Some general details are provided in the Concepts and Permissions sections. Make sure you are familiar with main concepts before starting this.

Important

In this tutorial, we use the internal accounts plugin.

We create the following accounts:

$ echo '{"data": {"password": "s3cr3t"}}' | http PUT http://localhost:8888/v1/accounts/julia
$ echo '{"data": {"password": "wh1sp3r"}}' | http PUT http://localhost:8888/v1/accounts/natim

Basic permission setup

The servicedenuages-blog bucket will contain two collections: articles and comments.

Let’s start by giving all authenticated users read access to the bucket.

$ echo '{"permissions": {"read": ["system.Authenticated"]}}' | \
    http PUT https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog \
    --auth julia:s3cr3t
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 203
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:20:37 GMT
ETag: "1437056437581"
Last-Modified: Thu, 16 Jul 2015 14:20:37 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "id": "servicedenuages-blog",
        "last_modified": 1437056437581
    },
    "permissions": {
        "read": [
            "system.Authenticated"
        ],
        "write": [
            "account:julia"
        ]
    }
}

Now, with that same user, let’s create two collections in this buckets: articles and comments.

$ http PUT https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/articles \
    --auth julia:s3cr3t
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 159
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:40:39 GMT
ETag: "1437057639758"
Last-Modified: Thu, 16 Jul 2015 14:40:39 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "id": "articles",
        "last_modified": 1437057639758
    },
    "permissions": {
        "write": [
            "account:julia"
        ]
    }
}
$ http PUT https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/comments \
    --auth julia:s3cr3t
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 159
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:41:39 GMT
ETag: "1437057699755"
Last-Modified: Thu, 16 Jul 2015 14:41:39 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "id": "comments",
        "last_modified": 1437057699755
    },
    "permissions": {
        "write": [
            "account:julia"
        ]
    }
}

Thanks to the read permission that we set previously, all authenticated users will be able to read both collections.

Let’s verify that. Create an article:

$ echo '{"data":{"title": "My article", "content": "my content", "published_at": "Thu Jul 16 16:44:15 CEST 2015"}}' | \
    http POST https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/articles/records \
    --auth julia:s3cr3t
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Backoff: 10
Connection: keep-alive
Content-Length: 278
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:43:45 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "content": "my content",
        "id": "b8c4cc34-f184-4b4d-8cad-e135a3f0308c",
        "last_modified": 1437057825171,
        "published_at": "Thu Jul 16 16:44:15 CEST 2015",
        "title": "My article"
    },
    "permissions": {
        "write": [
            "account:julia"
        ]
    }
}

Indeed, using another user like natim, we can read the article:

$ http GET https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/articles/records/b8c4cc34-f184-4b4d-8cad-e135a3f0308c \
    --auth natim:wh1sp3r
HTTP/1.1 200 OK
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, Last-Modified, ETag
Connection: keep-alive
Content-Length: 278
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:46:49 GMT
ETag: "1437057825171"
Last-Modified: Thu, 16 Jul 2015 14:43:45 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "content": "my content",
        "id": "b8c4cc34-f184-4b4d-8cad-e135a3f0308c",
        "last_modified": 1437057825171,
        "published_at": "Thu Jul 16 16:44:15 CEST 2015",
        "title": "My article"
    },
    "permissions": {
        "write": [
            "account:julia"
        ]
    }
}

If we want authenticated users to be able to create a comment, we can PATCH the permissions of the comments collections:

$ echo '{"permissions": {"record:create": ["system.Authenticated"]}}' | \
    http PATCH https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/comments \
    --auth julia:s3cr3t
HTTP/1.1 200 OK
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 200
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:49:38 GMT
ETag: "1437057699755"
Last-Modified: Thu, 16 Jul 2015 14:41:39 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "id": "comments",
        "last_modified": 1437057699755
    },
    "permissions": {
        "record:create": [
            "system.Authenticated"
        ],
        "write": [
            "account:julia"
        ]
    }
}

Now every authenticated user, like natim here, can add a comment.

$ echo '{"data":{"article_id": "b8c4cc34-f184-4b4d-8cad-e135a3f0308c", "comment": "my comment", "author": "*natim*"}}' | \
    http POST https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/comments/records \
    --auth natim:wh1sp3r
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 248
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:50:44 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "article_id": "b8c4cc34-f184-4b4d-8cad-e135a3f0308c",
        "author": "*natim*",
        "comment": "my comment",
        "id": "5e2292d5-8818-4cd4-be7d-d5a834d36de6",
        "last_modified": 1437058244384
    },
    "permissions": {
        "write": [
            "account:natim"
        ]
    }
}

Permissions and groups

So far only the creator of the initial bucket (i.e. julia, the blog admin) can write articles. Let’s invite some writers to create articles!

We will create a new group called writers with natim as one of the members.

$ echo '{"data": {"members": ["account:natim"]}}' | \
    http PUT https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/groups/writers \
    --auth julia:s3cr3t
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 247
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:54:58 GMT
ETag: "1437058498218"
Last-Modified: Thu, 16 Jul 2015 14:54:58 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "id": "writers",
        "last_modified": 1437058498218,
        "members": [
            "account:natim"
        ]
    },
    "permissions": {
        "write": [
            "account:julia"
        ]
    }
}

Now we grant the write permission on the blog bucket to the writers group.

$ echo '{"permissions": {"write": ["/buckets/servicedenuages-blog/groups/writers"]}}' | \
    http PATCH https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog \
    --auth julia:s3cr3t
HTTP/1.1 200 OK
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 254
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:56:55 GMT
ETag: "1437056437581"
Last-Modified: Thu, 16 Jul 2015 14:20:37 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "id": "servicedenuages-blog",
        "last_modified": 1437056437581
    },
    "permissions": {
        "read": [
            "system.Authenticated"
        ],
        "write": [
            "account:julia",
            "/buckets/servicedenuages-blog/groups/writers"
        ]
    }
}

Now natim can write new articles!

$ echo '{"data":{"title": "natim article", "content": "natims content", "published_at": "Thu Jul 16 16:59:16 CEST 2015"}}' | \
    http POST https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/articles/records \
    --auth natim:wh1sp3r
HTTP/1.1 201 Created
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Connection: keep-alive
Content-Length: 285
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 14:58:47 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": {
        "content": "natims content",
        "id": "f9a61750-f61f-402b-8785-1647c9325a5d",
        "last_modified": 1437058727907,
        "published_at": "Thu Jul 16 16:59:16 CEST 2015",
        "title": "natim article"
    },
    "permissions": {
        "write": [
            "account:natim"
        ]
    }
}

Listing records

One can fetch the list of articles.

$ http GET https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/articles/records
HTTP/1.1 200 OK
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, Next-Page, Last-Modified, ETag
Connection: keep-alive
Content-Length: 351
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 15:06:20 GMT
ETag: "1437058727907"
Last-Modified: Thu, 16 Jul 2015 14:58:47 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": [
        {
            "content": "natims content",
            "id": "f9a61750-f61f-402b-8785-1647c9325a5d",
            "last_modified": 1437058727907,
            "published_at": "Thu Jul 16 16:59:16 CEST 2015",
            "title": "natim article"
        },
        {
            "content": "my content",
            "id": "b8c4cc34-f184-4b4d-8cad-e135a3f0308c",
            "last_modified": 1437057825171,
            "published_at": "Thu Jul 16 16:44:15 CEST 2015",
            "title": "My article"
        }
    ]
}

Or the list of comments.

$ http GET https://demo.kinto-storage.org/v1/buckets/servicedenuages-blog/collections/comments/records
HTTP/1.1 200 OK
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, Next-Page, Last-Modified, ETag
Connection: keep-alive
Content-Length: 147
Content-Type: application/json; charset=UTF-8
Date: Thu, 16 Jul 2015 15:08:48 GMT
ETag: "1437058244384"
Last-Modified: Thu, 16 Jul 2015 14:50:44 GMT
Server: nginx/1.4.6 (Ubuntu)

{
    "data": [
        {
            "article_id": "b8c4cc34-f184-4b4d-8cad-e135a3f0308c",
            "author": "natim",
            "comment": "my comment",
            "id": "5e2292d5-8818-4cd4-be7d-d5a834d36de6",
            "last_modified": 1437058244384
        }
    ]
}