RESTHeart Cloud
Menu

Reference

Users and permissions through the API

The requests behind the Users and Permissions pages: create a user, grant a role a permission, limit a user to their own documents, hide a field.

Everything the Users and Permissions pages do is a request to your service. This page lists those requests, for a script, a CI job or an app of yours. Authenticate as root or with a role that has a permission on /users and /acl; on Dedicated the paths are /restheart/users and /restheart/acl.

Users

A user is _id, password and roles. Any other field is yours to add.

export ROOT_PASSWORD='the password you set on Connect'

curl -u root:$ROOT_PASSWORD -X POST https://f3a9c1.eu-central-1-free-1.restheart.com/users \
  -H 'Content-Type: application/json' \
  -d '{ "_id": "alice", "password": "her-password", "roles": ["user"] }'
Operation Request

List and search

GET /users?filter={"roles": "user"}&sort={"_id": 1}&page=1&pagesize=20

Create

POST /users with the document. Or PUT /users/alice?wm=upsert to create or replace by name.

Change roles or password

PATCH /users/alice with { "roles": […​] } or { "password": "new" }

Delete

DELETE /users/alice

The password is hashed by the service and never returned. Responses to GET omit it.

Permissions

A permission is roles, a predicate, a priority and optionally mongo. Lower priority numbers are evaluated first.

curl -u root:$ROOT_PASSWORD -X POST https://f3a9c1.eu-central-1-free-1.restheart.com/acl \
  -H 'Content-Type: application/json' \
  -d '{ "_id": "usersReadOrders", "roles": ["user"], "predicate": "path-prefix('"'"'/orders'"'"') and method(GET)", "priority": 100 }'
Operation Request

List

GET /acl?page=1&pagesize=50

Create

POST /acl with the document, or PUT /acl/<id>?wm=upsert

Change

PATCH /acl/<id> with the fields to change

Delete

DELETE /acl/<id>

Changes apply within about twenty seconds. The predicate language is on the Permissions page.

The four permissions most apps need

Readers may read, writers may also write
{ "_id": "readersRead", "roles": ["reader"], "predicate": "path-prefix('/content') and method(GET)", "priority": 100 }
{ "_id": "writersWrite", "roles": ["writer"], "predicate": "path-prefix('/content') and (method(GET) or method(POST) or method(PATCH) or method(DELETE))", "priority": 100 }
A user sees only their own documents
{
  "_id": "usersReadOwn",
  "roles": ["user"],
  "predicate": "path-prefix('/notes') and method(GET)",
  "priority": 100,
  "mongo": { "readFilter": { "owner": "@user._id" } }
}
What a user creates is stamped as theirs
{
  "_id": "usersCreateOwn",
  "roles": ["user"],
  "predicate": "path('/notes') and method(POST)",
  "priority": 100,
  "mongo": { "mergeRequest": { "owner": "@user._id" } }
}
A field is never returned
{
  "_id": "hideInternalNotes",
  "roles": ["user"],
  "predicate": "path-prefix('/orders') and method(GET)",
  "priority": 100,
  "mongo": { "projectResponse": { "internalNotes": 0 } }
}

@user._id is replaced with the name of the user making the request, @user.roles with their roles, and @now with the current time. readFilter, writeFilter, mergeRequest and projectResponse are explained on the Permissions page.

When something is refused

  • 401: the credentials are wrong or missing.

  • 403: no permission matched the role, path and method. Check the user’s roles and the predicate.

  • A GET that returns less than expected: a readFilter is at work.

  • A document with a field you did not send: a mergeRequest added it.

  • rhc: users and permissions as part of a setup file in git, instead of curl.

  • API keys: how a user issues a long-lived credential for a script or an agent.

  • Permission management and user management on restheart.org: the full reference.