Back to Arangodb

ArangoDB REST API Endpoint Permissions

Documentation/path_permissions.md

3.12.11133.7 KB
Original Source

ArangoDB REST API Endpoint Permissions

Migration philosophy

In the "classic" system permissions were given on a per-user basis and could only be configured for databases and collections. Essentially, there were three levels:

  • NONE
  • RO (read-only)
  • RW (read-write)

which a particular user could have for each database and - within a database - for each collection. Important here is that RW access always included RO access.

The _system database has played an important role, since many API accesses were authorized by asking if the user has RW access to the _system database.

Often, access to metadata was governed by RO or RW permissions on the container. For example, creating an index on a collection was allowed, if the user had RW access to the database which contained the collection.

Finally, there is the "SUPERUSER" access, which means that a valid JWT token without a preferred_username field was found. SUPERUSER access has no restrictions whatsoever and is allowed to do everything.

SUPERUSER is currently being used for three different reasons:

  • Cluster-internal communication:

    Only Coordinators do detailed authentication or authorization. DBServers and Agents generally only accept API calls from a SUPERUSER.

  • Platform-internal operations:

    Certain internal tools and services use SUPERUSER access to the database.

  • Internally overriding permission checks:

    E.g. certain APIs need to access certain (system) collections, but they should work even without the user having explicit access to those collections. The permission checks are (or have been) ignorant of such decisions, so the caller did its own checks, switched to a SUPERUSER context, and proceeded.

This was all not very convenient and flexible and was for many things very coarse-grained.

RBAC strives to

  • make this more fine-grained
  • create an indirection via "roles"
  • make this a lot more flexible by also adding "resource patterns" to be able to specify access rights to groups of resources with one "policy", rather than specifying everything collection-by-collection.
  • keep the SUPERUSER access

Of course, we need to maintain backwards compatibility for the case that RBAC is not enabled in the core DB.

The basic way to implement this new system is to overhaul all the authorization across all APIs in the following way:

We create an abstraction so that we can specify which access permissions one needs for each operation across all APIs. Then we implement this abstraction by a number of methods on the ExecContext, which contains the user and role data from authentication. For example, there will be methods like ExecContext::canSeeCollection(<dbname>, <collname>) -> Result.

The ExecContext then has a member AuthMode _authMode, which implements these abstractions. AuthMode itself is then just an interface and we can have different implementations for "RBAC disabled" (implementing the old system) and for "RBAC enabled" (implementing the new RBAC system) and possibly others like "no authentication" and "test mode".

This means it becomes an interesting exercise to even define this abstraction. It needs to be fine-grained enough to be able to be mapped to the RBAC system. And it needs to be fine-grained enough for all nuances of the old system (which has grown wild over time to a certain extent).

Then we have to go through all API implementations and change all authorization checks by calls to the new abstraction API.

Then we need to implement the checks in the different AuthMode variants.

This makes the new system relatively well reviewable. We have to check that in each API we call the right method(s) on the ExecContext. This is a distributed exercise and can be parallelized, once we have a completely clear documentation as to what the abstraction does.

Then we "only" have to review the non-RBAC implementation to see if it implements exactly what is specified.

For RBAC enabled, we can then verify the new implementation and thus exactly know to what new permissions the old system maps.

Finally, we must add extensive tests.

Where to check authorization

There are essentially three places in the execution paths of APIs, where authorization checks are done. Keep in mind that we do an authentication check very early on in the still in the CommTask, before we have even created a RestHandler object. This will essentially verify if a proper Authorization header is present. This could be basic auth or a JWT token. If there is no proper authentication, we can forbid the request right away. If we do not know the user or the JWT signature is not valid, we can decline the request right away as FORBIDDEN. Of course, there are a select few URL paths, which are "open" and do not require any authentication, and we need to handle the case of "no authentication", too.

In the meantime we have changed this to perform header parsing but not any further checks in the CommTask. Then, we have some virtual methods on the RestHandler class which are called early during the execution (but already on the Scheduler thread) of the RestHandler. These perform then authentication checks - depending on the particular needs of the URL path (some do checks, some don't).

After authentication, we perform a first authorization check: Namely, the identity detected (user/roles) has to have read access to the database which was specified in the /_db/<dbname> part of the URL path. This check is done globally already in the above mentioned virtual methods of the RestHandler to error out early, since we want to enforce it for all routes (with very few exceptions).

The bulk of the authorization checks is then performed in the RestHandlers (or, for 3.12, in the server-side JavaScript functions). The idea is that most general permission checks are done in the RestHandlers, with the exception of collection and view access checks.

Finally, the third place, where we do authorization checks, is this: Since basically all collection accesses need a transaction, we enforce collection access permissions in the transaction code, basically, when collections/views are added to a transaction.

Mapping the old permissions to the new RBAC system

Philosophy: "Keep the authorization in ´arangod` as much as possible as it is without RBAC, with the following modifications, if RBAC is enabled:

  • Database and collection access is controlled by RBAC instead of data in the _users collection.
  • It is also a bit more fine-grained (in particular for collections).
  • For databases, we have three access levels:
    1. NONE
    2. RO
    3. RW These are controlled by two RBAC actions:
    • db.ReadDatabase (with a database as resource db:database:<name>)
    • db.WriteDatabase (with a database as resource db:database:<name>) The first governs if an identity can use the database at all, at the same time it governs, whether or one can see a database in the listing of all accessible databases (GET /_api/database/user). The second governs creating and dropping, as well as changing properties of a database. This is very similar to the classic system, except that creating and dropping of database "d" used to be regulated by RW access to the _system database ("container principle"). Now, we have more fine grained authorization with resource patterns. The _system database is no longer so special. This means, one has at least level "RO", if one has db.ReadDatabase for a database, and one has level "RW", if one has both db.ReadDatabase and db.WriteDatabase for the database.
  • For collections, we split "Collection RW" into two separate access levels (which are independent of each other): "RWDATA" (which includes reading the collection meta data and data!) and "RWMETA" (which includes and modifying the collection meta data, for example creating and dropping indexes), so we have these access levels:
    1. NONE
    2. RO
    3. RWDATA
    4. RWMETA where RWDATA and RWMETA include RO, but RWMETA does not include RWDATA, since it is entirely possible that we want to allow somebody to modify indexes of a collection but not data.
  • Permission to create and drop collections are separate from this hierarchy.
  • There are five RBAC actions for collections: db:ReadCollection, db:WriteCollectionData and db:WriteCollectionMeta. To reach level Read for a collection, one only needs "allow" for db:ReadCollection. To reach level RWDATA one needs "allow" for db:ReadCollection and db:WriteCollectionData. To reach level RWMETA one needs "allow" on db:ReadCollection and db:WriteCollectionData. To create a collection, one needs db:CreateCollection, to drop a collection, one needs db:DropCollection.
  • For views, there are three levels:
    1. NONE
    2. RO
    3. RW There are two RBAC actions for views: db:ReadView and db:WriteView. One needs db:ReadView to achieve at least level RO and one needs noth db:ReadView and db:WriteView to achieve level RW.
  • All places that previously required RW access to the _system database are assigned to exactly one of the actions with the prefix db:Admin, for which one needs "allow" to execute the operation.
  • Enabled RBAC implies --server.harden.
  • We move the initial read access check for the requested database to a virtual method of the RestVocbaseBaseHandler, which is called in runHandler, but already on the scheduler.
  • Every other change is an exception, which we (grudgingly) make because we found some issue with the current system.
  • There is an additional action db:UseApiVersion to configure, which roles are allowed to use which API versions. Every request of an authenticated identity is gated by an api version check. It is asked in RestHandler::checkApiVersionAccess.

This philosophy helps in the following ways:

  • simple to explain and document
  • simple to implement (can keep at lot of code)
  • simple to review (in particular w.r.t. same behaviour as before with RBAC disabled!)
  • relatively simple to test (relatively few different cases)
  • maintains the "spirit" of RBAC that a "deny" should trump any potentially contradicting "allow" (which is why we cannot use OR conditions)

Abstraction in ExecContext to check these permissions

The ExecContext offers the following checking methods, all of which return a Result, so that a decline can return the actual reason (which can be different for RBAC enabled and disabled):

  • canUseAdminAction(rbac::Category::Any const action) -> Result

  • canUseHardenedAction(rbac::Category::Any const action) -> Result

  • canSeeDatabase(std::string_view db) -> Result

  • canCreateDatabase(std::string_view db) -> Result

  • canDropDatabase(std::string_view db) -> Result

  • canUseDatabase(std::string_view db, DatabaseAccessLevel const level) -> Result

  • canSeeCollection(std::string_view db, std::string_view coll) -> Result

  • canCreateCollection(std::string_view db, std::string_view coll) -> Result

  • canDropCollection(std::string_view db, std::string_view coll) -> Result

  • canUseCollection(std::string_view db, std::string_view coll, CollectionAccessLevel const level) -> Result

  • canDumpCollection(std::string_view db, std::string_view coll) -> Result

  • canRestoreCollection(std::string_view db, std::string_view coll) -> Result

  • canRestoreCreateView(std::string_view db, std::string_view viewName, std::vector<std::string> linkedCollNames) -> Result

  • canRestoreDropView(std::string_view db, std::string_view view) -> Result

  • canRestoreWriteData(std::string_view db, std::string_view coll) -> Result

  • canCreateIndex(std::string_view db, std::string_view coll) -> Result

  • canDropIndex(std::stgring_view db, std::string_view coll) -> Result

  • canSeeView(std::string_view db, std::string_view view) -> Result

  • canCreateView(std::string_view db, std::string_view view) -> Result

  • canDropView(std::string_view db, std::string_view view) -> Result

  • canReadView(std::string_view db, std::string_view view) -> Result

  • canRenameView(std::string_view db, std::string_view oldViewName, std::string_view newViewName, std::vector<std::string> collections) -> Result

  • canSeeAnalyzer(std::string_view db, std::string_view analyzer) -> Result

  • canCreateAnalyzer(std::string_view db, std::string_view analyzer) -> Result

  • canDropAnalyzer(std::string_view db, std::string_view analyzer) -> Result

  • canUseAnalyzer(std::string_view db, std::string_view analyzer) -> Result

  • canSeeGraph(std::string_view db, std::string_view graph) -> Result

  • canCreateGraph(std::string_view db, std::string_view graph, std::span<std::string_view> collectionNamesToCreate, std::span<std::string_view> collectionNamesToRead) -> Result

  • canDropGraph(std::string_view db, std::string_view graph, std::span<std::string_view> collectionNames) -> Result

  • canUseGraph(std::string_view db, std::string_view graph, GraphAccessLevel const level) -> Result

  • canReadUser(std::string_view user) -> Result

  • canReadUsers(std::span<std::string_view const> -> std::vector<bool>

  • canCreateUser(std::string_view user) -> Result

  • canDropUser(std::string_view user) -> Result

  • canModifyUserProfile(std::string_view user) -> Result

  • canGrantUserPermissions(std::string_view user) -> Result

  • canUseApiVersion(uint32_t version) -> Result

  • isSuperuser() -> bool

Note that for now, canSee* is equivalent to canUse*(RO). For collections canUseCollection(RWDATA) is needed to write data. Testing existence of a collection only needs canSeeCollection, whereas reading the metadata of a collection needs canUseCollection(RO) and similarly for databases, views, analyzers and graphs.

However, we keep the semantic checks separate in case we want to split things further later.

There is one subtlety, though. If we ever want to separate being able to see canSee* from canUse*(RO) later, then we want that if a user cannot see a collection (say) and cannot read it, then the error when trying to access it should be "NOTFOUND", to not give away the information that the collection exists! This must be considered in the central implementation of these methods.

Implementation details for the abstract methods for RBAC disabled

  • canUseAdminAction(rbac::Category::Any const action) -> Result

    check RW access for _system database

  • canUseHardenedAction(rbac::Category::Any const action) -> Result

    if hardened, check RW access for _system database, if not hardened, no further check

  • canSeeDatabase(std::string_view db) -> Result

    check that database authentication level is at least RO

  • canCreateDatabase(std::string_view db) -> Result

    check RW access for _system database

  • canDropDatabase(std::string_view db) -> Result

    check RW access for _system database

  • canUseDatabase(std::string_view db, DatabaseAccessLevel const level) -> Result

    check database auth level and use this:

    • DatabaseAccessLevel::Read: needs auth::Level::RO or more
    • DatabaseAccessLevel::Write: needs auth::Level::RW

    If the user is not allowed to see the database, this must return NOT_FOUND!

  • canSeeCollection(std::string_view db, std::string_view coll) -> Result

    check RO access for database (that is, always return Ok, since this has been checked already)

  • canCreateCollection(std::string_view db, std::string_view coll) -> Result

    check RW access for database

  • canDropCollection(std::string_view db, std::string_view coll) -> Result

    check RW access for database

  • canUseCollection(std::string_view db, std::string_view coll, CollectionAccessLevel const level) -> Result

    check collection auth level and use this:

    • CollectionAccessLevel::Read: needs auth::Level::RO or more
    • CollectionAccessLevel::WriteData: needs auth::Level::RW
    • CollectionAccessLevel::WriteMeta: needs auth::Level::RW and auth::Level::RW on database!

    If the user is not allowed to see the collection, this must return NOT_FOUND!

  • canDumpCollection(std::string_view db, std::string_view coll) -> Result

    Behaves exactly like canUseCollection(db, coll, CollectionAccessLevel::Read), except that access is additionally granted if the identity has RW access to the _system database (i.e. is an "admin"; equivalent to canUseAdminAction(rbac::Category::AdminDump{})). This mirrors the classic behaviour of arangodump, which could always be run by an admin, regardless of specific per-collection permissions.

  • canRestoreCollection(std::string_view db, std::string_view coll) -> Result

    Behaves exactly like canUseCollection(db, coll, CollectionAccessLevel::WriteData), except that access is additionally granted if the identity has RW access to the _system database (i.e. is an "admin"; equivalent to canUseAdminAction(rbac::Category::AdminRestore{})). This mirrors the classic behaviour of arangorestore, which could always be run by an admin, regardless of specific per-collection permissions.

  • canRestoreCreateView(std::string_view db, std::string_view viewName, std::vector<std::string> linkedCollNames) -> Result

    Behaves exactly like canCreateView(db, viewName, linkedCollNames), except that access is additionally granted if the identity has RW access to the _system database (i.e. is an "admin"; equivalent to canUseAdminAction(rbac::Category::AdminRestore{})). This mirrors the classic behaviour of arangorestore, which could always be run by an admin, regardless of specific per-view permissions.

  • canRestoreDropView(std::string_view db, std::string_view view) -> Result

    Behaves exactly like canDropView(db, view), except that access is additionally granted if the identity has RW access to the _system database (i.e. is an "admin"; equivalent to canUseAdminAction(rbac::Category::AdminRestore{})). This mirrors the classic behaviour of arangorestore, which could always be run by an admin, regardless of specific per-view permissions.

  • canRestoreWriteData(std::string_view db, std::string_view coll) -> Result

    Behaves exactly like canUseCollection(db, coll, CollectionAccessLevel::WriteData), except that access is additionally granted if the identity has RW access to the _system database (i.e. is an "admin"; equivalent to canUseAdminAction(rbac::Category::AdminRestore{})). This mirrors the classic behaviour of arangorestore, which could always be run by an admin, regardless of specific per-collection permissions.

  • canCreateIndex(std::string_view db, std::string_view coll) -> Result

    The user needs to have CollectionAccessLevel::WriteMeta for the collection and DatabaseAccessLevel::Write for the database.

  • canDropIndex(std::stgring_view db, std::string_view coll) -> Result

    The user needs to have CollectionAccessLevel::WriteMeta for the collection and DatabaseAccessLevel::Write for the database.

  • canSeeView(std::string_view db, std::string_view view) -> Result

    check RO access for database (no-op)

  • canCreateView(std::string_view db, std::string_view view) -> Result

    check RW access for database

  • canDropView(std::string_view db, std::string_view view) -> Result

    check RW access for database

  • canReadView(std::string_view db, std::string_view view) -> Result

    check R access for database

  • canRenameView(std::string_view db, std::string_view oldViewName, std::string_view newViewName, std::vector<std::string> collections) -> Result

    This should check that the new name is actually different from the old name and return an error if not. Furthermore, it should do the same check as canUseView with ÀccessLevel::WriteMeta.

  • canSeeAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check RO access for database (no-op)

  • canCreateAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check RW access for database

  • canDropAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check RW access for database

  • canUseAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    assume RO access for database is already checked. Check nothing else without RBAC.

    If the user is not allowed to see the analyzer, this must return NOT_FOUND!

  • canSeeGraph(std::string_view db, std::string_view graph) -> Result

    This is just checking if we have read access to the database, since this automatically implies read access to the _graphs collection.

  • canCreateGraph(std::string_view db, std::string_view graph, std::span<std::string_view> collectionNamesToCreate, std::span<std::string_view> collectionNamesToRead) -> Result

    This is checking if we have write access to the database (since we need write access to the _graphs collection). Furthermore, it checks if we are able to create the collections in the list collectionNamesToCreate and to read the collections in the list collectionNamesToRead.

  • canDropGraph(std::string_view db, std::string_view graph, std::span<std::string_view> collectionNames) -> Result

    This is checking if we have write access to the database (since we need write access to the _graphs collection). Furthermore, it checks if we are able to drop the collections in the list collectionNames.

  • canUseGraph(std::string_view db, std::string_view graph, GraphAccessLevel const level) -> Result

    Currently, this is just checking if we have read access to the database, since this automatically implies read access to the _graphs collection. For CollectionAccessLevel::WriteMeta (needed to change the graph), we need write access to the database.

  • canReadUser(std::string_view user) -> Result

check RO access in system database

  • canReadUsers(std::span<std::string_view const> -> std::vector<bool>

check RO access in system database

  • canCreateUser(std::string_view user) -> Result

check RW access in system database

  • canDropUser(std::string_view user) -> Result

check RW access in system database

  • canModifyUserProfile(std::string_view user) -> Result

check RW access in system database (note: everybody may modify their own profile)

  • canGrantUserPermissions(std::string_view user) -> Result

check RW access in system database

  • isSuperuser() -> bool

    must return true if and only if the authenticated user is the superuser (JWT token with empty preferred_username.

Implementation details for the abstract methods for RBAC enabled

  • canUseAdminAction(rbac::Category::Any const action) -> Result

    check the given RBAC action via the authorization service

  • canUseHardenedAction(rbac::Category::Any const action) -> Result

    default to hardened, check the given RBAC action

  • canSeeDatabase(std::string_view db) -> Result

    check RBAC action db:ReadDatabase, i.e. access level for database is at least "Read".

  • canCreateDatabase(std::string_view db) -> Result

    check RBAC actions db:ReadDatabase and db:WriteDatabase, i.e. access level i for database is at least RW

  • canDropDatabase(std::string_view db) -> Result

    check RBAC actions db:ReadDatabase and db:WriteDatabase, i.e. access level i for database is at least RW

  • canUseDatabase(std::string_view db, DatabaseAccessLevel const level) -> Result

    check database access level, i.e. check RBAC actions db:ReadDatabase and db:WriteDatabase

    If the user is not allowed to see the database, this must return NOT_FOUND!

  • canSeeCollection(std::string_view db, std::string_view coll) -> Result

    check collection access level to be at least RO, i.e., check RBAC action db:ReadCollection

  • canCreateCollection(std::string_view db, std::string_view coll) -> Result

    check db:CreateCollection

  • canDropCollection(std::string_view db, std::string_view coll) -> Result

    check db:DropCollection

  • canUseCollection(std::string_view db, std::string_view coll, CollectionAccessLevel const level) -> Result

    check collection access level, i.e., check RBAC actions db:ReadCollection and db:WriteCollectionData and db:WriteCollectionMeta to find NONE, or RO, or RWDATA, or RW, as described above.

    If the user is not allowed to see the collection, this must return NOT_FOUND!

  • canDumpCollection(std::string_view db, std::string_view coll) -> Result

    check collection access level to be at least RO, i.e., check RBAC action db:ReadCollection, OR check RBAC action db:AdminDump.

  • canRestoreCollection(std::string_view db, std::string_view coll) -> Result

    check collection access level to be at least RWDATA, i.e., check RBAC actions db:ReadCollection and db:WriteCollectionData, OR check RBAC action db:AdminRestore.

  • canRestoreCreateView(std::string_view db, std::string_view viewName, std::vector<std::string> linkedCollNames) -> Result

    check view access level to be RW, i.e., check RBAC actions db:ReadView and db:WriteView, OR check RBAC action db:AdminRestore.

  • canRestoreDropView(std::string_view db, std::string_view view) -> Result

    check view access level to be RW, i.e., check RBAC actions db:ReadView and db:WriteView, OR check RBAC action db:AdminRestore.

  • canRestoreWriteData(std::string_view db, std::string_view coll) -> Result

    check collection access level to be at least RWDATA, i.e., check RBAC actions db:ReadCollection and db:WriteCollectionData, OR check RBAC action db:AdminRestore.

  • canCreateIndex(std::string_view db, std::string_view coll) -> Result

    check db:WriteCollectionMeta for the collection.

  • canDropIndex(std::stgring_view db, std::string_view coll) -> Result

    check db:WriteCollectionMeta for the collection.

  • canSeeView(std::string_view db, std::string_view view) -> Result

    check view access level to be at least RO, i.e., check RBAC action db:ReadView

  • canCreateView(std::string_view db, std::string_view view) -> Result

    check view access level to be RW, i.e., check RBAC actions db:ReadView and db:WriteView

  • canDropView(std::string_view db, std::string_view view) -> Result

    check view access level to be RW, i.e., check RBAC actions db:ReadView and db:WriteView

  • canUseView(std::string_view db, std::string_view view) -> Result

    check view access level, i.e., check RBAC actions db:ReadView and db:WriteView to find NONE, or RO, or RW

    Note that we leave the code as it is to additionally check if the user has canUseCollection(RO) for all linked collections.

    If the user is not allowed to see the view, this must return NOT_FOUND!

  • canRenameView(std::string_view db, std::string_view oldViewName, std::string_view newViewName, std::vector<std::string> collections) -> Result

    This should check that the new name is actually different from the old name and RW access for database.

  • canSeeAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check analyzer access level to be at least RO, i.e., check RBAC action db:ReadAnalyzer

  • canCreateAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check analyzer access level to be RW, i.e., check RBAC actions db:ReadAnalyzer and db:WriteAnalyzer

  • canDropAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check analyzer access level to be RW, i.e., check RBAC actions db:ReadAnalyzer and db:WriteAnalyzer

  • canUseAnalyzer(std::string_view db, std::string_view analyzer) -> Result

    check analyzer access level, i.e., check RBAC actions db:ReadAnalyzer and db:WriteAnalyzer to find NONE, or RO, or RW

    Note that this is a different behaviour from before, but it is more sensible. To call the API, one has to have at least RO access to the database anyway. But writing an analyzer is now done via RBAC and reading, too.

    If the user is not allowed to see the analyzer, this must return NOT_FOUND!

  • canSeeGraph(std::string_view db, std::string_view graph) -> Result

    This checks if we have db:ReadGraph for the resource db:graph:<dbname>:<graphname>. The access to the _graphs collection is then implicit.

  • canCreateGraph(std::string_view db, std::string_view graph, std::span<std::string_view> collectionNamesToCreate, std::span<std::string_view> collectionNamesToRead) -> Result

    This is checking if we have create access to the graph, that is, we have db:CreateGraph With the resource db:graph:<dbname>:<graphname>. Furthermore, it checks if we are able to create the collections in the list collectionNamesToCreate and read the collections in the list collectionNamesToRead..

  • canDropGraph(std::string_view db, std::string_view graph, std::span<std::string_view> collectionNames) -> Result

    This is checking if we have drop access to the graph, that is, we have db:DropGraph with the resource db:graph:<dbname>:<graphname>. Furthermore, it checks if we are able to drop the collections in the list collectionNames.

  • canUseGraph(std::string_view db, std::string_view graph, GraphAccessLevel const level) -> Result

    This is checking if we have db:ReadGraph and db:WriteGraph respectively on the resource db:graph:<dbname>:<graphname>. For CollectionAccessLevel::Read we only need db:ReadGraph, for CollectionAccessLevel:WriteMeta we need both.

  • canReadUser(std::string_view user) -> Result

check RBAC action db:ReadUser

  • canReadUsers(std::span<std::string_view const> -> std::vector<bool>

check RBAC action db:ReadUser

  • canCreateUser(std::string_view user) -> Result

check RBAC action db:CreateUser

  • canDropUser(std::string_view user) -> Result

check RBAC action db:DropUser

  • canModifyUserProfile(std::string_view user) -> Result

check RBAC action db:ModifyUserProfile

  • canGrantUserPermissions(std::string_view user) -> Result

check RBAC action db:GrantUserPermissions

  • isSuperuser() -> bool

    must return true if and only if the authenticated user is the superuser (JWT token with empty preferred_username.

Implementation details when authentication is switched off

All these functions should return Ok. The isSuperuser method should return true.

Complete Endpoint–Action Reference Table

(still being edited)

Ideas:

  • NONE stays no authentication required
  • ANY stays any authenticated user (no further checks in handler)
  • DB access stays as it is
  • COLL access distinguishes meta data and document data
  • views and analyzers get their own actions like collection meta data
  • ADMIN is split into many actions with prefix db:Admin
  • HARDENED is considered to be always on for RBAC, so becomes the same as ADMIN
  • SUPERUSER stays superuser only

Note that some APIs are marked "ANY", but this is not dangerous because

  • the API is only available in MAINTAINER_MODE
  • the API is only available on DBServers or agents, which do not have users, so they only accept SUPERUSER anyway
  • the API is only compiled in when FAILURE_TESTS are activated

Others are marked ADMIN but run only on DBServers or agents, so that they actually only accept SUPERUSER anyway.

Furthermore, there are some command line switches, which change authentication behaviour, in a lot of cases these have 3 possible values: SUPERUSER, ADMIN, ANY, sometimes it is possible to switch off the API entirely. These switches remain and take precedence. RBAC will only be considered if the switch is on ADMIN.

Table of paths and authentification

Meanings of abbreviations:

OPEN - always open
AUTHEN - some existing user (or SUPERUSER) has to be authenticated, no further authorization check must have read access to the used database from /_db/<dbname
canUseAdmin(X) - stands for canUseAdminAction(AdminX)
canUseHard(X) - stands for canUseHardenedAction(AdminX)
isSuperuser - check for superuser
canUseColl(l) - canUseCollection(AccessLevel::l)
canUseDb(l) - canUseDatabase(DatabaseAccessLevel::l)
Admin* - with RBAC, one needs that action, without RBAC, one needs RW on _system
HARD - without RBAC, one needs RW on _system (with RBAC, --server.hardened is always on) (if Admin* and HARD are written, then AUTHEN holds when --server.hardened is off without RBAC)
DB RW - Read/write auth level for the database
DB RO - At least read-only auth level for the database
COLL RO - At least Read auth level for the collection
_system RW - Read/write auth level for _system database
?/S/A - API is switchable between off, superuser and admin access, additionally, an Admin* is specified
S/A - API is switchable between superuser and admin access, additionally, an Admin* is specified
S/A/AU - API is switchable between superuser only and admin only and AUTHEN
SA/SW/LEG - API is switchable between SA (superuser needed for everything), SW (superuser needed for write operations), LEG (legacy mode, superuser not needed, further authorization applies
?/S/A/O - API is switchable between off, superuser only, admin only and public (which is AUTHEN) \

DONEREVITESTMethodPathRestHandlerAbstract auth callAuthorizationCommentsChanges to before RBAC
XXPOST/_open/authRestAuthHandler-OPENneeds special exception in AUTHEN check!
XXPOST/_open/auth/renewRestAuthHandler-OPENneeds special exception in AUTHEN check!
XXGET/_admin/actionsMaintenanceRestHandler-AUTHENOnly really relevant on DBServers
XXPOST/_admin/actionsMaintenanceRestHandler-AUTHENOnly really relevant on DBServers
XXPUT/_admin/actionsMaintenanceRestHandler-AUTHENOnly really relevant on DBServers
XXDELETE/_admin/actions/{id}MaintenanceRestHandler-AUTHENOnly really relevant on DBServers
XXGET/_admin/activitiesactivities::RestHandlerisSuperuser / canUseAdmin(MonInternal)S/A AdminMonitoringInternal
XXGET/_admin/async-registryasync_registry::RestHandlercanUseAdmin(MonInternal)AdminMonitoringInternal
XXPOST/_admin/auth/reloadRestAdminAuthReloadHandlercanuseadmin(AuthReload)AdminAuthReload
XXPOST/_admin/backup/createRestHotBackupHandlerisSuperuser / canUseAdmin(Backup)S/A AdminBackup
XXPOST/_admin/backup/deleteRestHotBackupHandlerisSuperuser / canUseAdmin(Backup)S/A AdminBackup
X-POST/_admin/backup/downloadRestHotBackupHandlerisSuperuser / canUseAdmin(Backup)S/A AdminBackup
XXPOST/_admin/backup/listRestHotBackupHandlerisSuperuser / canUseAdmin(Backup)S/A AdminBackup
X-POST/_admin/backup/uploadRestHotBackupHandlerisSuperuser / canUseAdmin(Backup)S/A AdminBackup
X-POST/_admin/backup/restoreRestHotBackupHandlerisSuperuser / canUseAdmin(Backup)S/A AdminBackup
XXGET/_admin/cluster/collectionShardDistributionRestAdminClusterHandlercanUseAdmin(ClusterInfo)AdminClusterInfoSA/SW/LEG, only coordinator
XXPOST/_admin/cluster/cancelAgencyJobRestAdminClusterHandlercanUseAdmin(MoveShards)AdminMoveShardsSA/SW/LEG, only coordinator
XXPOST/_admin/cluster/cleanOutServerRestAdminClusterHandlercanUseAdmin(MoveShards)AdminMoveShardsSA/SW/LEG, only coordinator
XXGET/_admin/cluster/healthRestAdminClusterHandler-AUTHENSA/SW/LEG, only coordinator
XXGET/_admin/cluster/maintenanceRestAdminClusterHandlercanUseAdmin(Maintenance)AdminMaintenanceSA/SW/LEG, only coordinator+single
XXPUT/_admin/cluster/maintenanceRestAdminClusterHandlercanUseAdmin(Maintenance)AdminMaintenanceSA/SW/LEG, only coordinator+single
XXGET/_admin/cluster/maintenance/{serverId}RestAdminClusterHandlercanUseAdmin(Maintenance)AdminMaintenanceSA/SW/LEG, only coordinator+single
XXPUT/_admin/cluster/maintenance/{serverId}RestAdminClusterHandlercanUseAdmin(Maintenance)AdminMaintenanceSA/SW/LEG, only coordinator+single
XXPOST/_admin/cluster/moveShardRestAdminClusterHandlercanUseAdmin(MoveShard)canUseColl(RW)AdminMoveShards or COLL RWSA/SW/LEG, only coordinator
XXGET/_admin/cluster/nodeEngineRestAdminClusterHandler-AUTHENSA/SW/LEG, only coordinator
XXGET/_admin/cluster/nodeStatisticsRestAdminClusterHandler-AUTHENSA/SW/LEG, only coordinator
XXGET/_admin/cluster/nodeVersionRestAdminClusterHandler-AUTHENSA/SW/LEG, only coordinator
XXGET/_admin/cluster/numberOfServersRestAdminClusterHandler-AUTHENSA/SW/LEG, only coordinator
XXPUT/_admin/cluster/numberOfServersRestAdminClusterHandlercanUseHard(Maintenance)AdminMaintenance, HARDSA/SW/LEG, only coordinator
XXGET/_admin/cluster/queryAgencyJobRestAdminClusterHandlercanUseAdmin(MoveShards)AdminMoveShardsSA/SW/LEG, only coordinator
XXGET/_admin/cluster/rebalanceRestAdminClusterHandlercanUseAdmin(Rebalance)AdminRebalanceSA/SW/LEG, only coordinator
XXPUT/_admin/cluster/rebalanceRestAdminClusterHandlercanUseAdmin(Rebalance)AdminRebalanceSA/SW/LEG, only coordinator
XXPUT/_admin/cluster/rebalanceShardsRestAdminClusterHandlercanUseAdmin(Rebalance)AdminRebalanceSA/SW/LEG, only coordinatorWas: AUTHEN + DB RW
XXPOST/_admin/cluster/removeServerRestAdminClusterHandlercanUseAdmin(RemoveServer)AdminRemoveServerSA/SW/LEG
XXPOST/_admin/cluster/resignLeadershipRestAdminClusterHandlercanUseAdmin(MoveShards)AdminMoveShardsSA/SW/LEG, only coordinator
XXGET/_admin/cluster/shardDistributionRestAdminClusterHandlercanUseAdmin(ClusterInfo)AdminClusterInfoSA/SW/LEG, only coordinator
XXGET/_admin/cluster/shardStatisticsRestAdminClusterHandlercanUseadmin(ClusterInfo)AdminClusterInfoSA/SW/LEG, only coordinator
XXGET/_admin/cluster/statisticsRestAdminClusterHandler-AUTHENSA/SW/LEG, only coordinator
XXPUT/_admin/cluster/uniqIdRestAdminClusterHandlercanUseAdmin(Maintenance)AdminMaintenanceSA/SW/LEG, only coordinator
XXPUT/_admin/cluster/vpackSortMigration/{serverId}RestAdminClusterHandlerisSuperuserSUPERSA/SW/LEG
XXPUT/_admin/compactRestCompactHandlerisSuperuserSUPER
XXGET/_admin/crashesRestCrashHandlercanUseAdmin(CrashHandler)AdminCrashHandler
XXGET/_admin/crashes/{id}RestCrashHandlercanUseAdmin(CrashHandler)AdminCrashHandler
XXDELETE/_admin/crashes/{id}RestCrashHandlercanUseAdmin(CrashHandler)AdminCrashHandler
XXGET/_admin/database/target-versionRestAdminDatabaseHandler-AUTHEN
XXGET/_admin/debug/failatRestDebugHandler-AUTHEN(maintainer mode only)
XXGET/_admin/debug/failat/allRestDebugHandler-AUTHEN(maintainer mode only)
XXPUT/_admin/debug/failat/{name}RestDebugHandler-AUTHEN(maintainer mode only)
XXDELETE/_admin/debug/failatRestDebugHandler-AUTHEN(maintainer mode only)
XXDELETE/_admin/debug/failat/{name}RestDebugHandler-AUTHEN(maintainer mode only)
XXDELETE/_admin/debug/raceControlRestDebugHandler-AUTHEN(maintainer mode only)
XXPUT/_admin/debug/crashRestDebugHandler-AUTHEN(maintainer mode only)
XXGET/_admin/deployment/idRestAdminDeploymentHandler-AUTHENonly coordinators and single
XXPOST/_admin/executeRestAdminExecuteHandler-AUTHENonly --javascript.allow-admin-execute
XXGET/_admin/job/{id}RestJobHandler-AUTHENWe check in the JobManager same use
XXGET/_admin/job/{type}RestJobHandler-AUTHENWe check in the JobManager same use
XXPUT/_admin/job/{id}RestJobHandler-AUTHENWe check in the JobManager same use
XXPUT/_admin/job/{id}/cancelRestJobHandler-AUTHENWe check in the JobManager same use
XXDELETE/_admin/job/allRestJobHandler-AUTHENWe check in the JobManager same use
XXDELETE/_admin/job/expiredRestJobHandler-AUTHENWe check in the JobManager same use
XXDELETE/_admin/job/{id}RestJobHandler-AUTHENWe check in the JobManager same use
XXGET/_api/job/{id}RestJobHandler-AUTHENWe check in the JobManager same use
XXGET/_api/job/{type}RestJobHandler-AUTHENWe check in the JobManager same use
XXPUT/_api/job/{id}RestJobHandler-AUTHENWe check in the JobManager same use
XXPUT/_api/job/{id}/cancelRestJobHandler-AUTHENWe check in the JobManager same use
XXDELETE/_api/job/allRestJobHandler-AUTHENWe check in the JobManager same use
XXDELETE/_api/job/expiredRestJobHandler-AUTHENWe check in the JobManager same use
XXDELETE/_api/job/{id}RestJobHandler-AUTHENWe check in the JobManager same use
XXGET/_admin/licenseRestLicenseHandler(EE)canUseHard(License)AdminLicense, HARD
XXPUT/_admin/licenseRestLicenseHandler(EE)canUseHard(License)AdminLicense, HARD
XXGET/_admin/logRestAdminLogHandlerisSuperuser / canUseAdmin(ReadLogs)AdminReadLogs?/S/A
XXGET/_admin/log/entriesRestAdminLogHandlerisSuperuser / canUseAdmin(ReadLogs)AdminReadLogs?/S/A
XXGET/_admin/log/levelRestAdminLogHandlerisSuperuser / canUseAdmin(ReadLogs)AdminReadLogs?/S/A
XXGET/_admin/log/structuredRestAdminLogHandlerisSuperuser / canUseAdmin(ReadLogs)AdminReadLogs?/S/A
XXPUT/_admin/log/levelRestAdminLogHandlerisSuperuser / canUseAdmin(SetLogLevel)AdminSetLogLevel?/S/A
XXPUT/_admin/log/structuredRestAdminLogHandlerisSuperuser / canUseAdmin(SetLogLevel)AdminSetLogLevel?/S/A
XXDELETE/_admin/logRestAdminLogHandlerisSuperuser / canUseAdmin(SetLogLevel)AdminSetLogLevel?/S/A
XXDELETE/_admin/log/entriesRestAdminLogHandlerisSuperuser / canUseAdmin(SetLogLevel)AdminSetLogLevel?/S/A
XXDELETE/_admin/log/levelRestAdminLogHandlerisSuperuser / canUseAdmin(SetLogLevel)AdminSetLogLevel?/S/A
XXGET/_admin/metricsRestMetricsHandlercanUseHard(Monitoring)AdminMonitoring, HARD
XXGET/_admin/optionsRestOptionsHandlerisSuperuser / canUseAdmin(Options) / -AdminOptionsS/A/AU
XXGET/_admin/options-descriptionRestOptionsDescriptionHandlerisSuperuser / canUseAdmin(Options) / -AdminOptionsS/A/AU
XXGET/_admin/options-publicRestPublicOptionsHandler-AUTHEN
XXPOST/_admin/routing/reloadRestAdminRoutingHandler-AUTHEN(V8 required)
XXGET/_admin/server/api-callsRestAdminServerHandlerisSuperuser / canUseAdmin(ApiCalls)AdminApiCalls?/S/A
XXGET/_admin/server/aql-queriesRestAdminServerHandlerisSuperuser / canUseAdmin(AqlQueries)AdminAqlQueries?/S/A
XXGET/_admin/server/availabilityRestAdminServerHandler-OPEN
XXGET/_admin/server/databaseDefaultsRestAdminServerHandler-AUTHEN
XXGET/_admin/server/idRestAdminServerHandler-AUTHEN(cluster only)
XXGET/_admin/server/modeRestAdminServerHandler-AUTHEN
XXPUT/_admin/server/modeRestAdminServerHandlercanUseAdmin(Maintenance)AdminMaintenance
XXGET/_admin/server/roleRestAdminServerHandler-AUTHEN
XXGET/_admin/server/tlsRestAdminServerHandler-AUTHEN
XXPOST/_admin/server/tlsRestAdminServerHandlerisSuperuserSUPER
XXGET/_admin/server/jwtRestAdminServerHandler-AUTHEN
XXPOST/_admin/server/jwtRestAdminServerHandlerisSuperuserSUPER
XXGET/_admin/server/encryptionRestAdminServerHandler-AUTHEN(not on coordinators)
XXPOST/_admin/server/encryptionRestAdminServerHandlerisSuperuserSUPER(not on coordinators)
XXGET/_admin/shutdownRestShutdownHandler-AUTHEN(only coordinator for soft shutdown)
XXDELETE/_admin/shutdownRestShutdownHandlercanUseAdmin(Shutdown)AdminShutdown
XXGET/_admin/statisticsRestAdminStatisticsHandlercanUseHard(Monitoring)AdminMonitoring, HARD
XXGET/_admin/statistics-descriptionRestAdminStatisticsHandlercanUseHard(Monitoring)AdminMonitoring, HARD
XXGET/_admin/statusRestAdminStatusHandlercanUseHard(Monitoring)AdminMonitoring HARD
XXGET/_admin/supervisionStateRestSupervisionStateHandlercanUseAdmin(SupervisionState)AdminSupervisionState(coordinator only)
XXGET/_admin/support-infoRestSupportInfoHandlerisSuperuser / canUseAdmin(Monitoring) / -AdminMonitoring?/S/A/AU
XXGET/_admin/system-reportRestSystemReportHandlercanUseHard(MonitoringInternal)AdminMonitoringInternali, HARD
XXGET/_admin/telemetricsRestTelemetricsHandlerisSuperuser / canUseAdmin(MonitoringInternal) / -AdminMonitoringInternal?/S/A/AU
XXDELETE/_admin/telemetricsRestTelemetricsHandlerisSuperuser / canUseAdmin(MonitoringInternal) / -AdminMonitoringInternal?/S/A/AU
XXGET/_admin/timeRestTimeHandler-AUTHEN
XXGET/_admin/usage-metricsRestUsageMetricsHandlercanUseHard(MonitoringInternal)AdminMonitoringInternal HARD
XXGET/_admin/versionRestVersionhandler-/canUseHard(MonitoringInternal)AUTHEN, details (2)
XXGET/_admin/wal/propertiesRestWalAccessHandler-SUPER(RocksDB engine) only DBServer
XXPUT/_admin/wal/propertiesRestWalAccessHandler-SUPER(RocksDB engine) only DBServer
XXGET/_admin/wal/transactionsRestWalAccessHandler-SUPER(RocksDB engine) only DBServer
XXPUT/_admin/wal/flushRestWalAccessHandler-SUPER(RocksDB engine) only DBServer
XXPUT/_admin/wal/wait_for_estimator_syncRestWalAccessHandler-SUPER(RocksDB engine) only DBServer
XXGET/_admin/wal/propertiesClusterRestWalHandler-AUTHEN(Cluster engine) NOT_IMPL
XXPUT/_admin/wal/propertiesClusterRestWalHandler-AUTHEN(Cluster engine) NOT_IMPL
XXGET/_admin/wal/transactionsClusterRestWalHandler-AUTHEN(Cluster engine) NOT_IMPL
XXPUT/_admin/wal/flushClusterRestWalHandler-AUTHEN(Cluster engine) DELEGATED to DBServers
XXPUT/_admin/wal/wait_for_estimator_syncClusterRestWalHandlercanUseAdmin(WalAccess) / isSuperuserAdminWalAccess (PROD)/SUPER (MAINT)(Cluster engine)
XXGET/_api/aql-builtinRestAqlFunctionsHandler-AUTHEN
XXGET/_api/aqlfunctionRestAqlUserFunctionsHandler-, then run AQL with _aqlfunctions collAUTHEN + COLL RO _aqlfunctions(V8 required) Note: system-collection!
XXGET/_api/aqlfunction/{namespace}RestAqlUserFunctionsHandler-, then run AQL with _aqlfunctions collAUTHEN + COLL RO _aqlfunctions(V8 required) Note: system-collection!
XXPOST/_api/aqlfunctionRestAqlUserFunctionsHandler-, then run AQL with _aqlfunctions collAUTHEN + COLL RW _aqlfunctions(V8 required) Note: system-collection!
XXDELETE/_api/aqlfunction/{name}RestAqlUserFunctionsHandler-, then run AQL with _aqlfunctions collAUTHEN + COLL RW _aqlfunctions(V8 required) Note: system-collection!
XXGET/_api/analyzerRestAnalyzerHandler-, then run AQL with _analyzers collAUTHEN + COLL RO _analyzersNote: system-collection!
XXGET/_api/analyzer/{name}RestAnalyzerHandler-, then run AQL with _analyzers collAUTHEN + COLL RO _analyzersNote: system-collection!
XXPOST/_api/analyzerRestAnalyzerHandler-, then run AQL with _analyzers collAUTHEN + COLL RW _analyzersNote: system-collection!
XXDELETE/_api/analyzer/{name}RestAnalyzerHandler-, then run AQL with _analyzers collAUTHEN + COLL RW _analyzersNote: system-collection!
XXGET/_api/cluster/agency-cacheRestClusterHandlercanUseAdmin(ReadAgency)AdminReadAgency(coordinator only)
XXGET/_api/cluster/agency-dumpRestClusterHandlercanUseAdmin(ReadAgency)AdminReadAgency(coordinator only)
XXGET/_api/cluster/cluster-infoRestClusterHandlercanUseAdmin(ClusterInfo)AdminClusterInfo(cluster only)
XXPUT/.../flushRestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../get_collection_info/{db}/{coll}RestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../get_collection_info_current/{db}/{coll}/{shard}RestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXPOST/.../get_responsible_serversRestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXPOST/.../get_responsible_shard/{db}/{coll}RestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../get_analyzers_revision/{db}RestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../wait_for_plan_version/{version}RestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../get_max_number_of_shardsRestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../get_max_replication_factorRestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/.../get_min_replication_factorRestClusterHandlerisSuperuserSUPER (no check in MAINTAINERMODE)(cluster only)
XXGET/_api/cluster/endpointsRestClusterHandler-AUTHEN(coordinator only)
XXPOST/_api/collectionRestCollectionHandlercanCreateCollectionCOLL RW
XXGET/_api/collectionRestCollectionHandlercanSeeCollection, only see readableAUTHEN, details (3)
XXGET/_api/collection/{name}RestCollectionHandlercanUseCollection(Read)COLL RO
XXGET/_api/collection/{name}/checksumRestCollectionHandlercanUseCollection(Read)COLL RO
XXGET/_api/collection/{name}/countRestCollectionHandlercanUseCollection(Read)COLL RO
XXGET/_api/collection/{name}/figuresRestCollectionHandlercanUseCollection(Read)COLL RO
XXGET/_api/collection/{name}/propertiesRestCollectionHandlercanUseCollection(Read)COLL RO
XXGET/_api/collection/{name}/revisionRestCollectionHandlercanUseCollection(Read)COLL RO
XXGET/_api/collection/{name}/shardsRestCollectionHandlercanUseCollection(Read)COLL RO
XXPUT/_api/collection/{name}/compactRestCollectionHandlercanUseCollection(WriteMeta)COLL RW
XXPUT/_api/collection/{name}/loadRestCollectionHandlercanUseCollection(Read)COLL RO
XXPUT/_api/collection/{name}/loadIndexesIntoMemoryRestCollectionHandlercanUseCollection(Read)COLL RO
XXPUT/_api/collection/{name}/propertiesRestCollectionHandlercanUseCollection(WriteMeta)COLL RW
X-PUT/_api/collection/{name}/renameRestCollectionHandlercanUseCollection(WriteMeta)COLL RW
XXPUT/_api/collection/{name}/responsibleShardRestCollectionHandlercanUseCollection(Read)COLL RO
XXPUT/_api/collection/{name}/truncateRestCollectionHandlercanUseCollection(WriteData)COLL RWDATA
XXPUT/_api/collection/{name}/unloadRestCollectionHandlercanUseCollection(Read)COLL RO
XXDELETE/_api/collection/{name}RestCollectionHandlercanDropCollectionCOLL RW
XXPOST/_api/cursorRestCursorHandlerthen run AQL and rely on trxAUTHEN + COLL ACCESS via trx
X-POST/_api/cursor/jsonRestCursorHandlerthen run AQL and rely on trxAUTHEN + COLL ACCESS via trx
XXPOST/_api/cursor/{id}RestCursorHandlerthen run AQL and rely on trxAUTHEN + COLL ACCESS via trx
XXPOST/_api/cursor/{id}/{batch-id}RestCursorHandlerthen run AQL and rely on trxAUTHEN + COLL ACCESS via trx
XXPUT/_api/cursor/{id}RestCursorHandlerthen run AQL and rely on trxAUTHEN + COLL ACCESS via trx
XXDELETE/_api/cursor/{id}RestCursorHandlerthen run AQL and rely on trxAUTHEN + COLL ACCESS via trx
XXGET/_api/databaseRestDatabaseHandlercheck to be in _system databaseAUTHEN, _system, list allFIXME?
XXGET/_api/database/userRestDatabaseHandler_system, canSeeDatabaseAUTHEN, _system, detail (4)
XXGET/_api/database/currentRestDatabaseHandler-AUTHEN
XXGET/_api/database/shardStatisticsRestDatabaseHandler-AUTHEN(coordinator only)
XXPOST/_api/databaseRestDatabaseHandler_system, canCreateDbAUTHEN, _system, canCreateDB
XXDELETE/_api/database/{name}RestDatabaseHandler_system, canDropDbAUTHEN, _system, canDropDBshould be canCreateOrDropDatabaseFIXME
XXGET/_api/document/{collection}/{key}RestDocumentHandlercanUseCollection(Read), (via trx)COLL RO
XXHEAD/_api/document/{collection}/{key}RestDocumentHandlercanUseCollection(Read), (via trx)COLL RO
XXPOST/_api/document/{collection}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXPUT/_api/document/{collection}/{key}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXPUT/_api/document/{collection}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXPATCH/_api/document/{collection}/{key}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXPATCH/_api/document/{collection}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXDELETE/_api/document/{collection}/{key}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXDELETE/_api/document/{collection}RestDocumentHandlercanUseCollection(Write), (via trx)COLL RWDATA
XXGET/_api/document-stateRestDocumentStateHandlercanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XXPOST/_api/document-stateRestDocumentStateHandlercanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XXDELETE/_api/document-stateRestDocumentStateHandlercanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XXPOST/_api/dump/next/{id}RestDumpHandlerSAME USERSAME USER(dbserver and single only)
XXPOST/_api/dump/startRestDumpHandlercanUseCollection(Read)AUTHEN + COLL RO(dbserver and single only)AdminDump + SINGLE => escalate to SUPER FIXME?
XXDELETE/_api/dump/{id}RestDumpHandlerSAME USERSAME USER(dbserver and single only)
XXGET/_api/edges/{collection}RestEdgesHandlercanUseCollection(Read) (via trx)COLL RO
XXPOST/_api/edges/{collection}RestEdgesHandlercanUseCollection(Read) (via trx)COLL RO
XXGET/_api/endpointRestEndpointHandler_systemAUTHEN, _system
XXGET/_api/engineRestEngineHandlercanUseHard(MonitoringInternal)AdminMonitoringInternal, HARD
XXGET/_api/engine/statsRestEngineHandlercanUseHard(MonitoringInternal)AdminMonitoringInternal, HARD
XXPOST/_api/explainRestExplainHandlercanUseCollection(Read) (via trx)AUTHEN, COLL RO via trx
XXGET/_api/gharialRestGraphHandlercanSeeGraph: only list thosecanSeeGraph see (6)
XXPOST/_api/gharialRestGraphHandlercanCreateGraphcanCreateGraph + coll checks
XXGET/_api/gharial/{graph}RestGraphHandlercanUseGraph(RO)canUseGraph(RO)
XXDELETE/_api/gharial/{graph}RestGraphHandlercanDropGraphcanDropGraph + canDropColl(...)
XXGET/_api/gharial/{graph}/edgeRestGraphHandlercanUseGraph(RO)canUseGraph(RO)
XXPOST/_api/gharial/{graph}/edgeRestGraphHandlercanUseGraph(RW)canUseGraph(RW)
XXGET/_api/gharial/{graph}/edge/{definition}/{key}RestGraphHandlercanUseGraph(RO)canUseGraph(RO)
XXPOST/_api/gharial/{graph}/edge/{definition}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXPUT/_api/gharial/{graph}/edge/{definition}RestGraphHandlercanUseGraph(RW)canUseGraph(RW)
XXDELETE/_api/gharial/{graph}/edge/{definition}RestGraphHandlercanUseGraph(RW)canUseGraph(RW)
XXPUT/_api/gharial/{graph}/edge/{definition}/{key}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXPATCH/_api/gharial/{graph}/edge/{definition}/{key}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXDELETE/_api/gharial/{graph}/edge/{definition}/{key}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXGET/_api/gharial/{graph}/vertexRestGraphHandlercanUseGraph(RO)canUseGraph(RO)
XXPOST/_api/gharial/{graph}/vertexRestGraphHandlercanUseGraph(RW)canUseGraph(RW)
XXGET/_api/gharial/{graph}/vertex/{collection}/{key}RestGraphHandlercanUseGraph(RO)canUseGraph(RO)
XXPOST/_api/gharial/{graph}/vertex/{collection}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXDELETE/_api/gharial/{graph}/vertex/{collection}RestGraphHandlercanUseGraph(RW)canUseGraph(RW)
XXPUT/_api/gharial/{graph}/vertex/{collection}/{key}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXPATCH/_api/gharial/{graph}/vertex/{collection}/{key}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXDELETE/_api/gharial/{graph}/vertex/{collection}/{key}RestGraphHandlercanUseGraph(RO) + canUseColl(RWDATA)canUseGraph(RO) + COLL RWDATA
XXGET/_api/indexRestIndexHandlercanUseColl(Read)COLL RO
XXGET/_api/index/selectivityRestIndexHandlercanUseColl(Read) (via trx)COLL RO
XXPOST/_api/indexRestIndexHandlercanCreateIndex(coll)COLL RWMETA
XXPOST/_api/index/sync-cachesRestIndexHandlerAUTHENAUTHEN
XXDELETE/_api/index/{collection}/{id}RestIndexHandlercanDropIndex(coll)COLL RWMETA
XXGET/_api/key-generatorsRestKeyGeneratorsHandler-AUTHEN
XXGET/_api/logRestLogHandlercanUseAdmin(AdminReadReplicatedLogAdminReadReplicatedLog(replication2 + cluster only)
XXPOST/_api/logRestLogHandlercanUseAdmin(AdminWriteReplicatedLogAdminWriteReplicatedLog(replication2 + cluster only)
XXDELETE/_api/logRestLogHandlercanUseAdmin(AdminWriteReplicatedLogAdminWriteReplicatedLog(replication2 + cluster only)
XXGET/_api/log-internalRestLogInternalHandlerisSuperuserSUPER(replication2 + cluster only)
XXGET/_api/query/slowRestQueryHandler_system + isSuperuser (if for all DBs)AUTHEN, for all DBs _system + SUPER
XXGET/_api/query/currentRestQueryHandler_system + isSuperuser (if for all DBs)AUTHEN, for all DBs _system + SUPER
XXGET/_api/query/propertiesRestQueryHandler-AUTHEN
XXGET/_api/query/registryRestQueryHandlerisSuperuserSUPER
XXGET/_api/query/rulesRestQueryHandler-AUTHEN
XXPOST/_api/queryRestQueryHandler-AUTHEN
XXDELETE/_api/query/{id}RestQueryHandler_system + isSuperuser (if for all DBs)AUTHEN, for all DBs _system + SUPER
XXDELETE/_api/query/slowRestQueryHandler_system + isSuperuser (if for all DBs)AUTHEN, for all DBs _system + SUPER
XXGET/_api/query-cache/entriesRestQueryCacheHandler-AUTHEN
XXGET/_api/query-cache/propertiesRestQueryCacheHandler-AUTHEN
XXPUT/_api/query-cache/propertiesRestQueryCacheHandler_system + canUseAdmin(AdminQueryCache)_system + AdminQueryCache
XXDELETE/_api/query-cacheRestQueryCacheHandler_system + canUseAdmin(AdminQueryCache)_system + AdminQueryCache
XXGET/_api/query-plan-cacheRestQueryPlanCacheHandlercanUseColl(...)AUTHEN, details (5)
XXDELETE/_api/query-plan-cacheRestQueryPlanCacheHandlercanUseDb(Write)AUTHEN, DB RWneeds an RBAC solution?FIXME
X-GET/_api/replication/applier-stateRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)Coord restriction new
X-DELETE/_api/replication/applier-stateRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)Coord restriction new
X-GET/_api/replication/applier-state-allRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)Coord restriction new
X-GET/_api/replication/applier-configRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)Coord restriction new
X-PUT/_api/replication/applier-configRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)Coord restriction new
X-PUT/_api/replication/applier-startRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/applier-stopRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
XXPOST/_api/replication/batchRestReplicationHandler-SUPERonly actually DBServer (Coordinator forw)
XXPUT/_api/replication/batchRestReplicationHandler-SUPERonly actually DBServer (Coordinator forw)
XXDELETE/_api/replication/batchRestReplicationHandler-SUPERonly actually DBServer (Coordinator forw)
XXGET/_api/replication/clusterInventoryRestReplicationHandlerAdminClusterInfo or canUseColl(Read)AdminDump or COLL ROonly Coordinator, lists only those
X-GET/_api/replication/dumpRestReplicationHandlercanUseAdmin(Dump) or canUseColl(Read)AdminDump or COLL ROonly actually DBServer (Coordinator forw)
X-POST/_api/replication/holdReadLockCollectionRestReplicationHandler-SUPERonly DBServer (Coordinator forbidden)
X-DELETE/_api/replication/holdReadLockCollectionRestReplicationHandler-SUPERonly DBServer (Coordinator forbidden)
X-GET/_api/replication/inventoryRestReplicationHandler-SUPERonly actually DBServer (Coordinator forw)
X-GET/_api/replication/keys/{id}RestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-POST/_api/replication/keysRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/keys/{id}RestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-DELETE/_api/replication/keysRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-DELETE/_api/replication/keys/{id}RestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-GET/_api/replication/logger-first-tickRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-GET/_api/replication/logger-followRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/logger-followRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-GET/_api/replication/logger-stateRestReplicationHandler-SUPERonly DBServer (ClusterEngine not impl)
X-GET/_api/replication/logger-tick-rangesRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/make-followerRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/addFollowerRestReplicationHandler-SUPERonly DBServer (Coordiantor forbidden)
X-PUT/_api/replication/removeFollowerRestReplicationHandler-SUPERonly DBServer (Coordiantor forbidden)
X-PUT/_api/replication/restore-collectionRestReplicationHandlerAdminRestore or COLL RW (see (1))AdminRestore or COLL RW (1)
X-PUT/_api/replication/restore-dataRestReplicationHandlerEsc. to SUPER if AdminRestore,COLL RWDATAAdminRestore or COLL RWDATA
X-PUT/_api/replication/restore-indexesRestReplicationHandlerAdminRestore or canCreateIndexAdminRestore or INDEX CREATE
X-PUT/_api/replication/restore-viewRestReplicationHandlerAdminRestore or (canDropView&&canCreateV)AdminRestore or VIEW RECREATE
X-GET/_api/replication/revisions/treeRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-POST/_api/replication/revisions/treeRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/revisions/treeRestReplicationHandler-SUPERonly DBServer (Coordinator not i.) MAINT
X-GET/_api/replication/revisions/treependingRestReplicationHandler-SUPERonly DBServer (Coordinator not i.) MAINT
X-PUT/_api/replication/revisions/documentsRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-PUT/_api/replication/revisions/rangesRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
X-GET/_api/replication/server-idRestReplicationHandler-AUTHEN
X-PUT/_api/replication/set-the-leaderRestReplicationHandler-SUPERonly DBServer (Coordinator forbidden)
X-PUT/_api/replication/syncRestReplicationHandler-SUPERonly DBServer (Coordinator not impl)
XXPUT/_api/simple/allRestSimpleQueryHandlercanUseColl(Read) (via AQL/trx)AUTHEN, COLL RO
XXPUT/_api/simple/all-keysRestSimpleQueryHandlercanUseColl(Read) (via AQL/trx)AUTHEN, COLL RO
XXPUT/_api/simple/by-exampleRestSimpleQueryHandlercanUseColl(Read) (via AQL/trx)AUTHEN, COLL RO
XXPUT/_api/simple/lookup-by-keysRestSimpleHandlercanUseColl(Read) (via AQL/trx)AUTHEN, COLL RO
XXPUT/_api/simple/remove-by-keysRestSimpleHandlercanUseColl(WriteData) (via AQL/trx)AUTHEN, COLL RWDATA
XXGET/_api/tasksRestTasksHandlerisSuperuser, check SELFAUTHEN, list only SUPER or SELF(V8 required)
XXGET/_api/tasks/{id}RestTasksHandlerisSuperuser, check SELFAUTHEN, SUPER or SELF(V8 required)
XXPOST/_api/tasksRestTasksHandlercanUseDb(Write)DB RW(V8 required)NO FIX, tasks gone soon
X-PUT/_api/tasks/{id}RestTasksHandlercanUseDb(Write)DB RW(V8 required)NO FIX, tasks gone soon
XXDELETE/_api/tasks/{id}RestTasksHandlercanUseDb(Write)DB RW(V8 required)NO FIX, tasks gone soon
XXGET/_api/token/{user}RestAccessTokenHandlercanReadUsercanReadUser
XXPOST/_api/token/{user}RestAccessTokenHandlercanModifyUserProfilecanModifyUserProfile
XXDELETE/_api/token/{user}/{id}RestAccessTokenHandlercanModifyUserProfilecanModifyUserProfile
XXGET/_api/ttl/propertiesRestTtlHandler_systemAUTHEN, _system
XXGET/_api/ttl/statisticsRestTtlHandler_systemAUTHEN, _system
XXPUT/_api/ttl/propertiesRestTtlHandler_systemAUTHEN, _system
XXPOST/_api/uploadRestUploadHandler-AUTHENGone in 4.0NO FIX
XXGET/_api/userRestUsersHandlercanReadUsers(list)AUTHEN, see only canReadUser(u)
XXPOST/_api/userRestUsersHandlercanCreateUser(u)canCreateUser(u)
XXPOST/_api/user/{user}RestUsersHandler-AUTHEN, just check credentials
XXGET/_api/user/{user}RestUsersHandlercanReadUser(u)canReadUser(u)
XXGET/_api/user/{user}/configRestUsersHandlercanReadUser(u)canReadUser(u)
XXGET/_api/user/{user}/databaseRestUsersHandlercanReadUser(u)canReadUser(u)
XXGET/_api/user/{user}/database/{db}RestUsersHandlercanReadUser(u)canReadUser(u)
XXGET/_api/user/{user}/database/{db}/{coll}RestUsersHandlercanReadUser(u)canReadUser(u)
XXPUT/_api/user/{user}RestUsersHandlercanModifyUserProfile(u)canModifyUserProfile(u)
XXPUT/_api/user/{user}/database/{db}RestUsersHandlercanGrantUserPermissions(u)canGrantUserPermissions(u)
XXPUT/_api/user/{user}/database/{db}/{coll}RestUsersHandlercanGrantUserPermissions(u)canGrantUserPermissions(u)
XXPUT/_api/user/{user}/config/{key}RestUsersHandlercanModifyUserProfile(u)canModifyUserProfile(u)
XXPATCH/_api/user/{user}RestUsersHandlercanModifyUserProfile(u)canModifyUserProfile(u)
XXDELETE/_api/user/{user}RestUsersHandlercanDropUser(u)canDropUser(u)
XXDELETE/_api/user/{user}/config/{key}RestUsersHandlercanModifyUserProfile(u)canModifyUserProfile(u)
XXDELETE/_api/user/{user}/database/{db}RestUsersHandlercanGrantUserPermissions(u)canGrantUserPermissions(u)
XXDELETE/_api/user/{user}/database/{db}/{coll}RestUsersHandlercanGrantUserPermissions(u)canGrantUserPermissions(u)
XXGET/_api/versionRestVersionHandlercanUseHard(MonitoringInt) for detailsAUTHEN, details (2)
XXGET/_api/viewRestViewHandleronly see those with canSeeViewcanSeeView
XXPOST/_api/viewRestViewHandlercanCreateViewcanCreateView
XXDELETE/_api/view/{name}RestViewHandlercanDropViewcanDropView
XXGET/_api/view/{name}RestViewHandlercanReadViewcanReadView
XXGET/_api/view/{name}/propertiesRestViewHandlercanReadViewcanReadView
XXPATCH/_api/view/{name}/propertiesRestViewHandlercanModifyViewcanModifyView
XXPATCH/_api/view/{name}/renameRestViewHandlercanRenameViewcanRenameView
XXPUT/_api/view/{name}/propertiesRestViewHandlercanModifyViewcanModifyView
XXPUT/_api/view/{name}/renameRestViewHandlercanRenameViewcanRenameView
XXGET/_api/wal/lastTickRestWalAccessHandler-SUPERonly DBServer/Single, not on coord
XXGET/_api/wal/open-transactionsRestWalAccessHandler-SUPERonly DBServer/Single, not on coord
XXGET/_api/wal/rangeRestWalAccessHandler-SUPERonly DBServer/Single, not on coord
XXGET/_api/wal/tailRestWalAccessHandler-SUPERonly DBServer/Single, not on coord
XXPUT/_api/wal/tailRestWalAccessHandler-SUPERonly DBServer/Single, not on coord
XXDELETE/_api/wal/tailRestWalAccessHandler-SUPERonly DBServer/Single, not on coord
XXGET/_api/transactionRestTransactionHandler(same user and same db) or isSuperuserAUTHEN, only see same user and dbCoord/Single for users, DBServer internal
XXGET/_api/transaction/{id}RestTransactionHandler-AUTHENCoord/Single for users, DBServer internal
X-GET/_api/transaction/historyRestTransactionHandlerisSuperuserSUPERonly maintainer
XXPOST/_api/transactionRestTransactionHandler-AUTHENCoord/Single for users, DBServer internal
XXPOST/_api/transaction/beginRestTransactionHandler-AUTHENCoord/Single for users, DBServer internal
XXPUT/_api/transaction/{id}RestTransactionHandlersame user or isSuperuserAUTHEN, same user or SUPERCoord/Single for users, DBServer internal
XXDELETE/_api/transaction/{id}RestTransactionHandlersame user or isSuperuserAUTHENCoord/Single for users, DBServer internal
XXDELETE/_api/transaction/writeRestTransactionHandleronly same user or isSuperuserAUTHEN, only same user or SUPERCoord/Single for users, DBServer internal
X-DELETE/_api/transaction/historyRestTransactionHandlerisSuperuserSUPERonly maintainer
X-PUT/_internal/traverser/{option}/{engine-id}InternalRestTraverserHand.-SUPERonle DBServer
X-DELETE/_internal/traverser/{engine-id}InternalRestTraverserHand.-SUPERonle DBServer
XXGET/openapi.jsonRestOpenApiHandler-OPEN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
XJSJS_CreateQueuev8-dispatcher.cppcanUseDatabase(RW) (_system RW for runAs)DB RW (_system RW for runAs)
XJSTRI_RequestCppToV8v8-actions.cppisSuperuser to set isAdminUser flagSUPER
XJSJS_GetReplicatedLogv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_CreateReplicatedLogv8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_Idv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Dropv8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_Insertv8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_Pingv8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_MultiInsertv8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_Statusv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_GlobalStatusv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Headv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Tailv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Slicev8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Pollv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Atv8-replicated-logs.cppcanUseAdmin(ReadReplicatedLog)AdminReadReplicatedLog
XJSJS_Releasev8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_Compactv8-replicated-logs.cppcanUseAdmin(WriteReplicatedLog)AdminWriteReplicatedLog
XJSJS_RemoveUserv8-users.cppcanDropUser()canDropUser
XJSJS_ReloadAuthDatav8-users.cppcanUseAdmin(AuthReload)AdminAuthReload
XJSJS_GrantDatabasev8-users.cppcanGrantUserPermissions()canGrantUserPermissions
XJSJS_RevokeDatabasev8-users.cppcanGrantUserPermissions()canGrantUserPermissions
XJSJS_GrantCollectionv8-users.cppcanGrantUserPermissions()canGrantUserPermissions
XJSJS_RevokeCollectionv8-users.cppcanGrantUserPermissions()canGrantUserPermissions
XJSStoreUserv8-users.cppcanCreateUser()/canModifyUserProfile()canCreateUser/canModifyUserProfile
XJSJS_UpdateUserv8-users.cppcanModifyUserProfile()canModifyUserProfile
XJSJS_GetUserv8-users.cppcanReadUser()canReadUser
XJSJS_UpdateConfigDatav8-users.cppcanModifyUserProfile()canModifyUserProfile
XJSJS_GetConfigDatav8-users.cppcanReaduser()canReadUser
XCPPDatabases::grantCurrentUser (creation of database)Databases.CppcanGrantUserPermissions()canGrantUserPermissions
XJSJS_GetGraphKeysv8-general-graph.cppcanSeeGraphcanSeeGraph, list only visible

(1) For arangorestore, if --overwrite=true or the collection needs to be created, then we need canCreateColl, if --overwrite=false and the collection is already there, we only need COLL RWDATA

(2) For /_api/version, details can only be queried with AdminMonitoringInternal, if --server.harden=true

(3) For /_api/collection, RO for database is needed, then all collections with canSeeCollection are listed

(4) For /_api/database, all databases with canSeeDatabase() are listed

(5) For GET /_api/query-plan-cache only those entries are returned, for which the user has read access to all occurring collections

(6) For graphs, the regulate authorization as follows: - to create, we check canCreateGraph, which gets the list of collections which need to be created and a list of collections which we need to be able to read. Without RBAC, this needs write access to the db (to modify _graphs) and this implies being able to create the collections. With RBAC enabled, this needs db:CreateGraph and db:CreateCollection for those collections needed and db:ReadCollection for those which we need to be able to read. - to drop, we check canDropGraph, which gets the list of collections which need to be dropped. Without RBAC, this needs write access to the db (to modify _graphs) and this implies being able to drop the collections. With RBAC enabled, this needs db:DropGraph and db:DropCollection for those collections needed. - to list the graph, we check canSeeGraph, which checks db:ReadGraph with RBAC and read access to the db without RBAC (to read _graphs). - to see properties and use a graph, we check canUseGraph(RO), which checks db:ReadGraph with RBAC and read access to the db without RBAC (to read _graphs). - modify a graph definition, we check canUseGraph(RWMeta), which checks db:WriteGraph with RBAC and write access to the db without RBAC (to modify _graphs).

Rules:

  • internal use of system collections allowed without check
  • read access to system collections can be regulated by RBAC if switched on
  • write access (with normal APIs) to system collections is superuser only