Tarantool CE/EE Documentation portal logo
Support
Updated at July 17, 2026   02:08 PM

Access control

Tarantool enables flexible management of access to various database resources. The main concepts of Tarantool access control system are as follows:

  • A user is a person or program that interacts with a Tarantool instance.
  • An object is an entity to which access can be granted, for example, a space, an index, or a function.
  • A privilege allows a user to perform certain operations on specific objects, for example, creating spaces, reading or updating data.
  • A role is a named collection of privileges that can be granted to a user.

Overview

Users

A user identifies a person or program that interacts with a Tarantool instance. There might be different types of users, for example:

  • A database administrator responsible for the overall management and administration of a database. An administrator can create other users and grant them specified privileges.
  • A user with limited access to certain data and stored functions. Such users can get their privileges from the database administrator.
  • Users used in communications between Tarantool instances. For example, such users can be created to maintain replication and sharding in a Tarantool cluster.

There are two built-in users in Tarantool:

  • admin is a user with all available administrative privileges. If the connection uses an admin-console port, the current user is admin. For example, admin is used when connecting to an instance using tt connect locally using the instance name:

    $ tt connect app:instance001

    To allow remote binary port connections using the admin user, you need to set a password.

  • guest is a user with minimum privileges used by default for remote binary port connections. For example, guest is used when connecting to an instance using tt connect using the IP address and port without specifying the name of a user:

    $ tt connect 192.168.10.10:3301

Passwords

Any user (except guest) may have a password. If a password is not set, a user cannot connect to Tarantool instances.

Tarantool password hashes are stored in the _user system space. By default, Tarantool uses the CHAP protocol to authenticate users and applies SHA-1 hashing to passwords. So, if the password is '123456', the stored hash is a string like 'a7SDfrdDKRBe5FaN2n3GftLKKtk='. In the Enterprise Edition, you can enable PAP authentication with the SHA256 hashing algorithm.

Tarantool Enterprise Edition allows you to improve database security by enforcing the use of strong passwords, setting up a maximum password age, and so on. Learn more from the configuration_authentication topic.

Objects

An object is a securable entity to which access can be granted. Tarantool has a number of objects that enable flexible management of access to data, stored functions, specific actions, and so on.

Below are a few examples of objects:

  • universe represents a database (box.schema) that contains database objects, including spaces, indexes, users, roles, sequences, and functions. Granting privileges to universe gives a user access to any object in a database.
  • space enables granting privileges to user-created or system spaces.
  • function enables granting privileges to functions.

Privileges

The privileges granted to a user determine which operations the user can perform, for example:

  • The read and write permissions granted to the space object allow a user to read or modify data in the specified space.
  • The create permission granted to the space object allows a user to create new spaces.
  • The execute permission granted to the function object allows a user to execute the specified function.
  • The session permission granted to the universe object allows a user to connect to an instance over IPROTO.
  • The usage permission granted to universe object allows a user to use his privileges on database objects (for example, read, write, and alter space).
  • The alter permission granted to a user allows modifying its own settings, for example, a password.
  • The drop permission granted to a user allows dropping users.

Note that some privileges might require read and write access to certain system spaces. For example, the create permission granted to the space object requires read and write permissions to the _space system space. Similarly, granting the ability to create functions requires read and write access to the _func space.

Roles

A role is a container for privileges that can be granted to users. Roles can also be assigned to other roles, creating a role hierarchy.

There are the following built-in roles in Tarantool:

  • super has all available administrative permissions.

  • public has certain read permissions. This role is automatically granted to new users when they are created.

  • replication can be granted to a user used to maintain replication in a cluster.

  • sharding can be granted to a user used to maintain sharding in a cluster.

Below are a few diagrams that demonstrate how privileges can be granted to a user without and with using roles.

  • In this example, a user gets privileges directly without using roles.

    user1 ── privilege1    ├─── privilege2    └─── privilege3
  • In this example, a user gets all privileges provided by role1 and specific privileges assigned directly.

    user1 ── role1 ── privilege1    │        └─── privilege2    ├─── privilege3    └─── privilege4
  • In this example, role2 is granted to role1. This means that a user with role1 subsequently gets all privileges from both roles role1 and role2.

    user1 ── role1 ── privilege1    │        ├─── privilege2    │        └─── role2    │                 ├─── privilege3    │                 └─── privilege4    ├─── privilege5    └─── privilege6

Object owners

An owner of a database object is the user who created it. The owner of the database and the owner of objects that are created initially (the system spaces and the default users) is the admin user.

Owners automatically have privileges for objects they create. They can share these privileges with other users or roles using box.schema.user.grant() and box.schema.role.grant().

Sessions

A session is the state of a connection to Tarantool. The session contains:

  • An integer ID identifying the connection.
  • The current user associated with the connection.
  • The text description of the connected peer.
  • A session's local state, such as Lua variables and functions.

In Tarantool, a single session can execute multiple concurrent transactions. Each transaction is identified by a unique integer ID, which can be queried at the start of the transaction using box.session.sync().

Managing users

Creating a user

To create a new user, call box.schema.user.create(). In the example below, a user is created without a password:

box.schema.user.create('testuser')        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], nil)    end)endg.test_user_with_password_created = function(cg)    cg.server:exec(function()        -- Create a user with a password --        box.schema.user.create('testuser', { password = 'foobar' })        -- End: Create a user with a password --        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_current_user_password_set = function(cg)    cg.server:exec(function()        box.session.su('admin')        -- Set a password for the current user --        box.schema.user.passwd('foobar')        -- End: Set a password for the current user --        t.assert_equals(box.space._user.index.name:select { 'admin' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_specified_user_password_set = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Set a password for the specified user --        box.schema.user.passwd('testuser', 'foobar')        -- End: Set a password for the specified user --        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_grant_revoke_privileges_user = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser', { password = 'foobar' })        box.schema.user.grant('testuser', 'execute', 'universe')        -- Grant privileges to the specified user --        box.schema.user.grant('testuser', 'read', 'space', 'writers')        box.schema.user.grant('testuser', 'read,write', 'space', 'books')        -- End: Grant privileges to the specified user --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke space reading --        box.schema.user.revoke('testuser', 'write', 'space', 'books')        -- End: Revoke space reading --        box.session.su('testuser')        local _, delete_book_error = pcall(function()            box.space.books:delete(10)        end)        t.assert_equals(delete_book_error:unpack().message, "Write access to space 'books' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke session --        box.schema.user.revoke('testuser', 'session', 'universe')        -- End: Revoke session --        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

In this example, the password is specified in the options parameter:

box.schema.user.create('testuser', { password = 'foobar' })        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_current_user_password_set = function(cg)    cg.server:exec(function()        box.session.su('admin')        -- Set a password for the current user --        box.schema.user.passwd('foobar')        -- End: Set a password for the current user --        t.assert_equals(box.space._user.index.name:select { 'admin' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_specified_user_password_set = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Set a password for the specified user --        box.schema.user.passwd('testuser', 'foobar')        -- End: Set a password for the specified user --        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_grant_revoke_privileges_user = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser', { password = 'foobar' })        box.schema.user.grant('testuser', 'execute', 'universe')        -- Grant privileges to the specified user --        box.schema.user.grant('testuser', 'read', 'space', 'writers')        box.schema.user.grant('testuser', 'read,write', 'space', 'books')        -- End: Grant privileges to the specified user --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke space reading --        box.schema.user.revoke('testuser', 'write', 'space', 'books')        -- End: Revoke space reading --        box.session.su('testuser')        local _, delete_book_error = pcall(function()            box.space.books:delete(10)        end)        t.assert_equals(delete_book_error:unpack().message, "Write access to space 'books' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke session --        box.schema.user.revoke('testuser', 'session', 'universe')        -- End: Revoke session --        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

Changing passwords

To set or change a user's password, use box.schema.user.passwd(). In the example below, a user password is set for a currently logged-in user:

box.schema.user.passwd('foobar')        t.assert_equals(box.space._user.index.name:select { 'admin' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_specified_user_password_set = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Set a password for the specified user --        box.schema.user.passwd('testuser', 'foobar')        -- End: Set a password for the specified user --        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_grant_revoke_privileges_user = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser', { password = 'foobar' })        box.schema.user.grant('testuser', 'execute', 'universe')        -- Grant privileges to the specified user --        box.schema.user.grant('testuser', 'read', 'space', 'writers')        box.schema.user.grant('testuser', 'read,write', 'space', 'books')        -- End: Grant privileges to the specified user --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke space reading --        box.schema.user.revoke('testuser', 'write', 'space', 'books')        -- End: Revoke space reading --        box.session.su('testuser')        local _, delete_book_error = pcall(function()            box.space.books:delete(10)        end)        t.assert_equals(delete_book_error:unpack().message, "Write access to space 'books' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke session --        box.schema.user.revoke('testuser', 'session', 'universe')        -- End: Revoke session --        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

To set the password for the specified user, pass a username and password as shown below:

box.schema.user.passwd('testuser', 'foobar')        t.assert_equals(box.space._user.index.name:select { 'testuser' }[1][5]['chap-sha1'], 'm1ADQ7xS4pERcutSrlz0hHYExuU=')    end)endg.test_grant_revoke_privileges_user = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser', { password = 'foobar' })        box.schema.user.grant('testuser', 'execute', 'universe')        -- Grant privileges to the specified user --        box.schema.user.grant('testuser', 'read', 'space', 'writers')        box.schema.user.grant('testuser', 'read,write', 'space', 'books')        -- End: Grant privileges to the specified user --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke space reading --        box.schema.user.revoke('testuser', 'write', 'space', 'books')        -- End: Revoke space reading --        box.session.su('testuser')        local _, delete_book_error = pcall(function()            box.space.books:delete(10)        end)        t.assert_equals(delete_book_error:unpack().message, "Write access to space 'books' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke session --        box.schema.user.revoke('testuser', 'session', 'universe')        -- End: Revoke session --        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

Granting privileges to a user

To grant the specified privileges to a user, use the box.schema.user.grant() function. In the example below, testuser gets read permissions to the writers space and read/write permissions to the books space:

box.schema.user.grant('testuser', 'read', 'space', 'writers')        box.schema.user.grant('testuser', 'read,write', 'space', 'books')        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke space reading --        box.schema.user.revoke('testuser', 'write', 'space', 'books')        -- End: Revoke space reading --        box.session.su('testuser')        local _, delete_book_error = pcall(function()            box.space.books:delete(10)        end)        t.assert_equals(delete_book_error:unpack().message, "Write access to space 'books' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke session --        box.schema.user.revoke('testuser', 'session', 'universe')        -- End: Revoke session --        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

Learn more about granting privileges to different types of objects from access_control_granting_privileges.

Getting a user's information

To check whether the specified user exists, call box.schema.user.exists():

box.schema.user.exists('testuser')--[[- true--]]

To get information about privileges granted to a user, call box.schema.user.info():

box.schema.user.info('testuser')--[[- - - execute    - role    - public  - - read    - space    - writers  - - read,write    - space    - books  - - session,usage    - universe    -  - - alter    - user    - testuser--]]

In the example above, testuser has the following privileges:

  • The execute permission to the public role means that this role is assigned to the user.
  • The read permission to the writers space means that the user can read data from this space.
  • The read,write permissions to the books space mean that the user can read and modify data in this space.
  • The session,usage permissions to universe mean the following:
    • session: the user can authenticate over an IPROTO connection.
    • usage: lets the user use their privileges on database objects (for example, read and modify data in a space).
  • The alter permission lets testuser modify its own settings, for example, a password.

Revoking user's privileges

To revoke the specified privileges, use the box.schema.user.revoke() function. In the example below, write access to the books space is revoked:

box.schema.user.revoke('testuser', 'write', 'space', 'books')        box.session.su('testuser')        local _, delete_book_error = pcall(function()            box.space.books:delete(10)        end)        t.assert_equals(delete_book_error:unpack().message, "Write access to space 'books' is denied for user 'testuser'")        box.session.su('admin')        -- Revoke session --        box.schema.user.revoke('testuser', 'session', 'universe')        -- End: Revoke session --        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

Revoking the session permission to universe can be used to disallow a user to connect to a Tarantool instance:

box.schema.user.revoke('testuser', 'session', 'universe')        local _, change_user_error = pcall(function()            box.session.su('testuser')        end)        t.assert_equals(change_user_error:unpack().message, "Session access to universe '' is denied for user 'testuser'")    end)endg.test_user_dropped = function(cg)    cg.server:exec(function()        box.schema.user.create('testuser')        -- Drop a user --        box.schema.user.drop('testuser')        -- End: Drop a user --        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

Changing the current user

The current user name can be found using box.session.user().

box.session.user()--[[- admin--]]

The current user can be changed:

  • For an admin-console connection: using box.session.su():

    box.session.su('testuser')box.session.user()--[[- testuser--]]
  • For a binary port connection: using the AUTH protocol command, supported by most clients.

  • For a binary-port connection invoking a stored function with the CALL command: if the SETUID property is enabled for the function, Tarantool temporarily replaces the current user with the function's creator, with all the creator's privileges, during function execution.

Dropping users

To drop the specified user, call box.schema.user.drop():

box.schema.user.drop('testuser')        t.assert_equals(box.schema.user.exists('testuser'), false)    end)end

Managing roles

Creating a role

To create a new role, call box.schema.role.create(). In the example below, two roles are created:

box.schema.role.create('books_space_manager')        box.schema.role.create('writers_space_reader')        -- Grant read/write privileges to a role --        box.schema.role.grant('books_space_manager', 'read,write', 'space', 'books')        -- Grant write privileges to a role --        box.schema.role.grant('writers_space_reader', 'read', 'space', 'writers')        -- End: Grant privileges to roles --        -- Grant a role to a role --        box.schema.role.create('all_spaces_manager')        box.schema.role.grant('all_spaces_manager', 'books_space_manager')        box.schema.role.grant('all_spaces_manager', 'writers_space_reader')        -- End: Grant a role to a role --        -- Grant a role to a user --        box.schema.user.grant('testuser', 'books_space_manager')        box.schema.user.grant('testuser', 'writers_space_reader')        -- End: Grant a role to a user --        -- Test removing a tuple from 'writers' --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoking a role from a user  --        box.schema.user.revoke('testuser', 'execute', 'role', 'writers_space_reader')        -- End: Revoking a role from a user --        -- Test selecting data from 'writers' --        box.session.su('testuser')        local _, select_writer_error = pcall(function()            box.space.writers:select(3)        end)        t.assert_equals(select_writer_error:unpack().message, "Read access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Dropping a role  --        box.schema.role.drop('writers_space_reader')        -- End: Dropping a role  --        -- Test roles exist --        t.assert_equals(box.schema.role.exists('books_space_manager'), true)        t.assert_equals(box.schema.role.exists('all_spaces_manager'), true)        t.assert_equals(box.schema.role.exists('writers_space_reader'), false)    end)end

Granting privileges to a role

To grant the specified privileges to a role, use the box.schema.role.grant() function. In the example below, the books_space_manager role gets read and write permissions to the books space:

box.schema.role.grant('books_space_manager', 'read,write', 'space', 'books')

The writers_space_reader role gets read permissions to the writers space:

box.schema.role.grant('writers_space_reader', 'read', 'space', 'writers')

Learn more about granting privileges to different types of objects from access_control_granting_privileges.

Granting a role to a role

Roles can be assigned to other roles. In the example below, the newly created all_spaces_manager role gets all privileges granted to books_space_manager and writers_space_reader:

box.schema.role.create('all_spaces_manager')        box.schema.role.grant('all_spaces_manager', 'books_space_manager')        box.schema.role.grant('all_spaces_manager', 'writers_space_reader')        -- Grant a role to a user --        box.schema.user.grant('testuser', 'books_space_manager')        box.schema.user.grant('testuser', 'writers_space_reader')        -- End: Grant a role to a user --        -- Test removing a tuple from 'writers' --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoking a role from a user  --        box.schema.user.revoke('testuser', 'execute', 'role', 'writers_space_reader')        -- End: Revoking a role from a user --        -- Test selecting data from 'writers' --        box.session.su('testuser')        local _, select_writer_error = pcall(function()            box.space.writers:select(3)        end)        t.assert_equals(select_writer_error:unpack().message, "Read access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Dropping a role  --        box.schema.role.drop('writers_space_reader')        -- End: Dropping a role  --        -- Test roles exist --        t.assert_equals(box.schema.role.exists('books_space_manager'), true)        t.assert_equals(box.schema.role.exists('all_spaces_manager'), true)        t.assert_equals(box.schema.role.exists('writers_space_reader'), false)    end)end

Granting a role to a user

To grant the specified role to a user, use the box.schema.user.grant() function. In the example below, testuser gets privileges granted to the books_space_manager and writers_space_reader roles:

box.schema.user.grant('testuser', 'books_space_manager')        box.schema.user.grant('testuser', 'writers_space_reader')        -- Test removing a tuple from 'writers' --        box.session.su('testuser')        local _, delete_writer_error = pcall(function()            box.space.writers:delete(3)        end)        t.assert_equals(delete_writer_error:unpack().message, "Write access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Revoking a role from a user  --        box.schema.user.revoke('testuser', 'execute', 'role', 'writers_space_reader')        -- End: Revoking a role from a user --        -- Test selecting data from 'writers' --        box.session.su('testuser')        local _, select_writer_error = pcall(function()            box.space.writers:select(3)        end)        t.assert_equals(select_writer_error:unpack().message, "Read access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Dropping a role  --        box.schema.role.drop('writers_space_reader')        -- End: Dropping a role  --        -- Test roles exist --        t.assert_equals(box.schema.role.exists('books_space_manager'), true)        t.assert_equals(box.schema.role.exists('all_spaces_manager'), true)        t.assert_equals(box.schema.role.exists('writers_space_reader'), false)    end)end

Getting a role's information

To check whether the specified role exists, call box.schema.role.exists():

box.schema.role.exists('books_space_manager')--[[- true--]]

To get information about privileges granted to a role, call box.schema.role.info():

box.schema.role.info('books_space_manager')--[[- - - read,write    - space    - books--]]

If a role has the execute permission to other roles, this means that these roles are granted to this parent role:

box.schema.role.info('all_spaces_manager')--[[- - - execute    - role    - books_space_manager  - - execute    - role    - writers_space_reader--]]

Revoking a role from a user

To revoke the specified role from a user, revoke the execute privilege for this role using the box.schema.user.revoke() function. In the example below, the books_space_reader role is revoked from testuser:

box.schema.user.revoke('testuser', 'execute', 'role', 'writers_space_reader')        -- Test selecting data from 'writers' --        box.session.su('testuser')        local _, select_writer_error = pcall(function()            box.space.writers:select(3)        end)        t.assert_equals(select_writer_error:unpack().message, "Read access to space 'writers' is denied for user 'testuser'")        box.session.su('admin')        -- Dropping a role  --        box.schema.role.drop('writers_space_reader')        -- End: Dropping a role  --        -- Test roles exist --        t.assert_equals(box.schema.role.exists('books_space_manager'), true)        t.assert_equals(box.schema.role.exists('all_spaces_manager'), true)        t.assert_equals(box.schema.role.exists('writers_space_reader'), false)    end)end

To revoke role's privileges, use box.schema.role.revoke().

Dropping roles

To drop the specified role, call box.schema.role.drop():

box.schema.role.drop('writers_space_reader')        -- Test roles exist --        t.assert_equals(box.schema.role.exists('books_space_manager'), true)        t.assert_equals(box.schema.role.exists('all_spaces_manager'), true)        t.assert_equals(box.schema.role.exists('writers_space_reader'), false)    end)end

Granting privileges

To grant the specified privileges to a user or role, use the box.schema.user.grant() and box.schema.role.grant() functions, which have similar signatures and accept the same set of arguments. For example, the box.schema.user.grant() signature looks as follows:

box.schema.user.grant(username, permissions, object-type, object-name[, {options}])
  • username: the name of the user that gets the specified privileges.

  • permissions: a string value that represents permissions granted to the user. If there are several permissions, they should be separated by commas without a space.

  • object-type: a type of object to which permissions are granted.

  • object-name: the name of the object to which permissions are granted. An empty string ("") or nil provided instead of object-name grants the specified permissions to all objects of the specified type.

Any object

In the example below, testuser gets privileges allowing them to create any object of any type:

box.schema.user.grant('testuser','read,write,create','universe')

In this example, testuser can grant access to objects that testuser created:

box.schema.user.grant('testuser','write','space','_priv')

Spaces

Creating and altering spaces

In the example below, testuser gets privileges allowing them to create spaces:

box.schema.user.grant('testuser','create','space')box.schema.user.grant('testuser','write', 'space', '_schema')box.schema.user.grant('testuser','write', 'space', '_space')

As you can see, the ability to create spaces also requires write access to certain system spaces.

To allow testuser to drop a space that has associated objects, add the following privileges:

box.schema.user.grant('testuser','create,drop','space')box.schema.user.grant('testuser','write','space','_schema')box.schema.user.grant('testuser','write','space','_space')box.schema.user.grant('testuser','write','space','_space_sequence')box.schema.user.grant('testuser','read','space','_trigger')box.schema.user.grant('testuser','read','space','_fk_constraint')box.schema.user.grant('testuser','read','space','_ck_constraint')box.schema.user.grant('testuser','read','space','_func_index')

Creating and altering indexes

In the example below, testuser gets privileges allowing them to create indexes in the 'writers' space:

box.schema.user.grant('testuser','create,read','space','writers')box.schema.user.grant('testuser','read,write','space','_space_sequence')box.schema.user.grant('testuser','write', 'space', '_index')

To allow testuser to alter indexes in the writers space, grant the privileges below. This example assumes that indexes in the writers space are not created by testuser.

box.schema.user.grant('testuser','alter','space','writers')box.schema.user.grant('testuser','read','space','_space')box.schema.user.grant('testuser','read','space','_index')box.schema.user.grant('testuser','read','space','_space_sequence')box.schema.user.grant('testuser','write','space','_index')

If testuser created indexes in the writers space, granting the following privileges is enough to alter indexes:

box.schema.user.grant('testuser','read','space','_space_sequence')box.schema.user.grant('testuser','read,write','space','_index')

CRUD operations

In this example, testuser gets privileges allowing them to select data from the 'writers' space:

box.schema.user.grant('testuser','read','space','writers')

In this example, testuser is allowed to read and modify data in the 'books' space:

box.schema.user.grant('testuser','read,write','space','books')

Sequences

Creating and dropping sequences

In this example, testuser gets privileges to create sequence generators:

box.schema.user.grant('testuser','create','sequence')box.schema.user.grant('testuser', 'read,write', 'space', '_sequence')

To let testuser drop a sequence, grant them the following privileges:

box.schema.user.grant('testuser','drop','sequence')box.schema.user.grant('testuser','write','space','_sequence_data')box.schema.user.grant('testuser','write','space','_sequence')

Using sequence functions

In this example, testuser is allowed to use the id_seq:next() function with a sequence named 'id_seq':

box.schema.user.grant('testuser','read,write','sequence','id_seq')

In the next example, testuser is allowed to use the id_seq:set() or id_seq:reset() functions with a sequence named 'id_seq':

box.schema.user.grant('testuser','write','sequence','id_seq')

Functions

Creating and dropping functions

In this example, testuser gets privileges to create functions:

box.schema.user.grant('testuser','create','function')box.schema.user.grant('testuser','read,write','space','_func')

To let testuser drop a function, grant them the following privileges:

box.schema.user.grant('testuser','drop','function')box.schema.user.grant('testuser','write','space','_func')

Executing functions

To give the ability to execute a function named 'sum', grant the following privileges:

box.schema.user.grant('testuser','execute','function','sum')

Executing lua functions

Granting the 'execute' privilege on lua_call permits the user to call any global (accessible via the _G Lua table) user-defined Lua function with the IPROTO_CALL request. To grant permission to any non-persistent function, you need to specify its name when granting the lua_call privilege.

function my_func_1() endfunction my_func_2() endbox.cfg({listen = 3301})box.schema.user.create('alice', {password = 'secret'})conn = require('net.box').connect(box.cfg.listen, {user = 'alice', password = 'secret'})box.schema.user.grant('alice', 'execute', 'lua_call', 'my_func_1')conn:call('my_func_1') -- okconn:call('my_func_2') -- access deniedbox.schema.user.grant('alice', 'execute', 'lua_call', 'box.session.su')conn:call('box.session.su', {'admin'}) -- ok

Users

In this example, testuser gets privileges to create other users:

box.schema.user.grant('testuser','create','user')box.schema.user.grant('testuser', 'read,write', 'space', '_user')box.schema.user.grant('testuser', 'write', 'space', '_priv')

Roles

To let testuser create new roles, grant the following privileges:

box.schema.user.grant('testuser','create','role')box.schema.user.grant('testuser', 'read,write', 'space', '_user')box.schema.user.grant('testuser', 'write', 'space', '_priv')

Executing code

To let testuser execute Lua code, grant the execute privilege to the lua_eval object:

box.schema.user.grant('testuser','execute','lua_eval')

Similarly, executing an arbitrary SQL expression requires the execute privilege to the sql object:

box.schema.user.grant('testuser','execute','sql')

Example

In the example below, the created Lua function is executed on behalf of its creator, even if called by another user.

First, the two spaces (space1 and space2) are created, and a no-password user (private_user) is granted full access to them. Then read_and_modify is defined and private_user becomes this function's creator. Finally, another user (public_user) is granted access to execute Lua functions created by private_user.

box.schema.space.create('space1')box.schema.space.create('space2')box.space.space1:create_index('pk')box.space.space2:create_index('pk')box.schema.user.create('private_user')box.schema.user.grant('private_user', 'read,write', 'space', 'space1')box.schema.user.grant('private_user', 'read,write', 'space', 'space2')box.schema.user.grant('private_user', 'create', 'universe')box.schema.user.grant('private_user', 'read,write', 'space', '_func')function read_and_modify(key)  local space1 = box.space.space1  local space2 = box.space.space2  local fiber = require('fiber')  local t = space1:get{key}  if t ~= nil then    space1:put{key, box.session.uid()}    space2:put{key, fiber.time()}  endendbox.session.su('private_user')box.schema.func.create('read_and_modify', {setuid= true})box.session.su('admin')box.schema.user.create('public_user', {password = 'secret'})box.schema.user.grant('public_user', 'execute', 'function', 'read_and_modify')

Whenever public_user calls the function, it is executed on behalf of its creator, private_user.

All object types and permissions

Object types

Object type

Description

universe

A database (box.schema) that contains database objects, including spaces, indexes, users, roles, sequences, and functions. Granting privileges to universe gives a user access to any object in the database.

user

A user.

role

A role.

space

A space.

function

A function.

sequence

A sequence.

lua_eval

Executing arbitrary Lua code.

lua_call

Calling any global user-defined Lua function.

sql

Executing an arbitrary SQL expression.

Permissions

Permission

Object type

Granted to roles

Description

read

All

Yes

Allows reading data of the specified object. For example, this permission can be used to allow a user to select data from the specified space.

write

All

Yes

Allows updating data of the specified object. For example, this permission can be used to allow a user to modify data in the specified space.

create

All

Yes

Allows creating objects of the specified type. For example, this permission can be used to allow a user to create new spaces. Note that this permission requires read and write access to certain system spaces.

alter

All

Yes

Allows altering objects of the specified type. Note that this permission requires read and write access to certain system spaces.

drop

All

Yes

Allows dropping objects of the specified type. Note that this permission requires read and write access to certain system spaces.

execute

role, universe, function, lua_eval, lua_call, sql

Yes

For role, allows using the specified role. For other object types, allows calling a function.

session

universe

No

Allows a user to connect to an instance over IPROTO.

usage

universe

No

Allows a user to use their privileges on database objects (for example, read, write, and alter spaces).

Object types and permissions

Object type

Details

universe

  • read: Allows reading any object types, including all spaces or sequence objects. - write: Allows modifying any object types, including all spaces or sequence objects. - execute: Allows execute functions, Lua code, or SQL expressions, including IPROTO calls. - session: Allows a user to connect to an instance over IPROTO. - usage: Allows a user to use their privileges on database objects (for example, read, write, and alter space). - create: Allows creating users, roles, functions, spaces, and sequences. This permission requires read and write access to certain system spaces. - drop: Allows deleting users, roles, functions, spaces, and sequences. This permission requires read and write access to certain system spaces. - alter: Allows altering user settings or space objects.

user

  • alter: Allows modifying a user description, for example, change the password. - create: Allows creating new users. This permission requires read and write access to the _user system space. - drop: Allows dropping users. This permission requires read and write access to the _user system space.

role

  • execute: Indicates that a role is assigned to the user or another role. - create: Allows creating new roles. This permission requires read and write access to the _user system space. - drop: Allows dropping roles. This permission requires read and write access to the _user system space.

space

  • read: Allows selecting data from a space. - write: Allows modifying data in a space. - create: Allows creating new spaces. This permission requires read and write access to the _space system space. - drop: Allows dropping spaces. This permission requires read and write access to the _space system space. - alter: Allows modifying spaces. This permission requires read and write access to the _space system space. If a space is created by a user, they can read and write it without granting explicit permission.

function

  • execute: Allows calling a function. - create: Allows creating a function. This permission requires read and write access to the _func system space. If a function is created by a user, they can execute it without granting explicit permission. - drop: Allows dropping a function. This permission requires read and write access to the _func system space.

sequence

  • read: Allows using sequences in space_obj:create_index(). - write: Allows all operations for a sequence object. seq_obj:drop() requires a write permission to the _priv system space. - create: Allows creating sequences. This permission requires read and write access to the _sequence system space. If a sequence is created by a user, they can read/write it without explicit permission. - drop: Allows dropping sequences. This permission requires read and write access to the _sequence system space. - alter: Has no effect. seq_obj:alter() and other methods require the write permission.

lua_eval

  • execute: Allows executing arbitrary Lua code using the IPROTO_EVAL request.

lua_call

  • execute: Allows executing any user-defined function using the IPROTO_CALL request. This permission doesn't allow a user to call built-in Lua functions (for example, loadstring() or box.session.su()) and functions defined in the _func system space.

sql

  • execute: Allows executing arbitrary SQL expression using the IPROTO_PREPARE and IPROTO_EXECUTE requests.