Untrusted client¶
Follow sections sequentially to complete demonstration of an access from an untrusted client.
Create application¶
Login to Jazer’s dashboard. Create a new application by clicking on the create new app button. A dialog will be shown asking for an application name. Give it a name like Untrusted client test and click on the create button. An application will then be created and shown in the application list. Click on the newly created application in the application list to open application page.
Create API key¶
Open API keys using left sidebar menu item . Create a new API key using toolbar item . A dialog will be shown asking for an API key name. Give it a name like Untrusted API key and click on the create button. API key will be created with no permissions. To add a permission use permissions toolbar item . Use /resources/todo for the path and enable methods GET and POST. Turn ACL on. Add two more permissions for users one with path /users/core\.user and other with path /users/core\.user\.token. On both enable POST method and leave ACL turned off. Add another two permissions for inspecting ACL. One with the path /resources/todo\.acl/[0-9a-fA-F]{24} and the other with the path /resources/todo\.acl\.acl/[0-9a-fA-F]{24}. On both enable GET method and turn ACL on. Save API key changes using toolbar item .
To protect data ACL should be turned on for untrusted client API key permissions. There are cases when it is safe to turn it off like for fetching public data. When permission undergoes ACL each document ACL record is checked against users credentials. The client, therefore, needs to authenticate a user.
Find application ID¶
Open the metadata page using left sidebar menu item . Application ID is presented alongside other application metadata. The client must supply application ID in the application-id header in each API request.
Create user¶
To create a user make API request:
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "core.user",
"attributes": {
"username": "john.smith",
"password": "aDayInTheLife"
}
}
}' \
-X POST https://api.jazer.com/users/core.user
The response will contain created user:
{
"data": {
"type": "core.user",
"id": "59bee9ffac610577a9bae5b1",
"attributes": {
"username": "john.smith",
"password": "$2a$11$vD7Ky82IX5cD6tYWeIpQ8e9jH1NHbYbAzdUrhJcJFVAlCdOxHVBD6"
},
"links": {
"self": "https://api.jazer.io/users/core.user/59bee9ffac610577a9bae5b1"
}
}
}
Note
System types usually have prefix core
.
Create token¶
To create an authentication token for a user make API request with Authorization header where value starts with Basic followed by base64 encoded <USERNAME>:<PASSWORD>. Created user would encode john.smith:aDayInTheLife where the result would be am9obi5zbWl0aDphRGF5SW5UaGVMaWZl. Online service can be used to base64 encode while testing.
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Basic am9obi5zbWl0aDphRGF5SW5UaGVMaWZl' \
-X POST https://api.jazer.io/users/core.user.token
The response will contain created token:
{
"data": {
"type": "core.user.token",
"id": "59bef133ac610577a9bae5b7",
"attributes": {
"token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6eyJ0eXBlIjoiY29yZS51c2VyLnRva2VuIiwiaWQiOiI1OWJlZjEzM2FjNjEwNTc3YTliYWU1YjcifSwidXNlciI6eyJ0eXBlIjoiY29yZS51c2VyIiwiaWQiOiI1OWJlZTlmZmFjNjEwNTc3YTliYWU1YjEifSwiaXNzIjoiamF6ZXIiLCJpYXQiOjE1MDU2ODU4MTEsImV4cCI6MTUwODI3NzgxMX0.MEUCIQC3xyKTm8BONMA2D7-TEQHQRvwkHtB7LCcb_RSt-snZ_wIgEuoeGQrFFHlKGTK9rLyVq2lH25CjJ7IcMyUtLVWqedI",
"created": "2017-09-17T22:03:31.060Z"
},
"relationships": {
"user": {
"data": {
"type": "core.user",
"id": "59bee9ffac610577a9bae5b1"
}
}
},
"links": {
"self": "https://api.jazer.io/users/core.user.token/59bef133ac610577a9bae5b7"
}
}
}
Create resource¶
Create a todo resource. A user token must be supplied in Authorization
header since API key permission for todo resource is protected with ACL.
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <JOHN_SMITH_USER_TOKEN>' \
-d '
{
"data": {
"type": "todo",
"attributes": {
"title": "Buy flowers"
}
}
}' \
-X POST https://api.jazer.io/resources/todo
The response will contain createded todo resource:
{
"data": {
"type": "todo",
"id": "59bef4cdac610577a9bae5bb",
"attributes": {
"title": "Buy flowers"
},
"links": {
"self": "https://api.jazer.io/resources/todo/59bef4cdac610577a9bae5bb"
}
}
}
Fetch resources¶
Make an API request to fetch all todo resources:
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <JOHN_SMITH_USER_TOKEN>' \
-X GET https://api.jazer.io/resources/todo
The response will contain previously created todo resource:
{
"meta": {
"count": 1
},
"data": [
{
"type": "todo",
"id": "59bef4cdac610577a9bae5bb",
"attributes": {
"title": "Buy flowers"
},
"links": {
"self": "https://api.jazer.io/resources/todo/59bef4cdac610577a9bae5bb"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/todo?page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/todo?page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Create another user and a token for that user. Fetch all todo resources using the new token. The response will contain zero todo resources. When the user John Smith created Buy flowers todo resource, all ACL rights were automatically assigned to him. Any other user who uses API key which undergoes ACL for todo resources will not see Buy flowers todo resource. Since API key has permission to read ACL record, ACL of a created todo can be inspected using API request:
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <JOHN_SMITHS_USER_TOKEN>' \
-X GET https://api.jazer.io/resources/todo.acl/<TODO_ID>
The response will contain ACL record for a given todo resource:
{
"data": {
"type": "todo.acl",
"id": "59bef4cdac610577a9bae5bb",
"attributes": {
"read": [
{
"id": "59bee9ffac610577a9bae5b1",
"type": "core.user"
}
],
"update": [
{
"id": "59bee9ffac610577a9bae5b1",
"type": "core.user"
}
],
"delete": [
{
"id": "59bee9ffac610577a9bae5b1",
"type": "core.user"
}
]
},
"links": {
"self": "https://api.jazer.io/resources/todo.acl/59bef4cdac610577a9bae5bb"
}
}
}
ACL record of a resource shows who is allowed to perform a specific operation on a resource. The user John Smith could update ACL record appending other users to read array. When other user makes API request to fetch todo resources then the result would contain one John Smith created. The user John Smith can update ACL record appending other users to update array allowing them to update todo resource. This does not imply that other users have right to change ACL record of that resource. They have only right to change the resource. To be able to change ACL record they need to have an update right in a super ACL record. Super ACL record is basically ACL record for ACL record of a resource. API request to inspect super ACL:
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <JOHN_SMITHS_USER_TOKEN>' \
-X GET https://api.jazer.io/resources/todo.acl.acl/<TODO_ID>
The response will contain super ACL record of a given todo resource:
{
"data": {
"type": "todo.acl.acl",
"id": "59bef4cdac610577a9bae5bb",
"attributes": {
"read": [
{
"id": "59bee9ffac610577a9bae5b1",
"type": "core.user"
}
],
"update": [
{
"id": "59bee9ffac610577a9bae5b1",
"type": "core.user"
}
]
},
"links": {
"self": "https://api.jazer.io/resources/todo.acl.acl/59bef4cdac610577a9bae5bb"
}
}
}
Super ACL record shows who can read and update ACL record of a resource. There is no delete operation since ACL records are system types which are automatically created with the resource and cannot be deleted.