diff --git a/src/box/alter.cc b/src/box/alter.cc
index 435febdd24d3b8d362cf857df4e7287d1d24c455..7df8e0ba6ef3af3f28f274e358e0abbeedc6b18f 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -60,7 +60,7 @@
 
 /* {{{ Auxiliary functions and methods. */
 
-void
+static void
 access_check_ddl(uint32_t owner_uid, enum schema_object_type type)
 {
 	struct credentials *cr = current_user();
diff --git a/src/box/call.cc b/src/box/call.cc
index d730369459a27d94dd7c03213ef476e48faec7de..b5f4c4fa8a834489e98d7ecffc1c24781bb3229c 100644
--- a/src/box/call.cc
+++ b/src/box/call.cc
@@ -70,7 +70,7 @@ access_check_func(const char *name, uint32_t name_len, struct func **funcp)
 		return 0;
 	}
 
-	uint8_t access = PRIV_X & ~credentials->universal_access;
+	user_access_t access = PRIV_X & ~credentials->universal_access;
 	if (func == NULL || (func->def->uid != credentials->uid &&
 	     access & ~func->access[credentials->auth_token].effective)) {
 		/* Access violation, report error. */
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 846d97b7c496a1b66dc818750ab3ed4c762bb65d..c1b45a41e58c049a829139b08275c3dee2422a02 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1574,6 +1574,36 @@ local function privilege_resolve(privilege)
         if string.find(privilege, 'execute') then
             numeric = numeric + 4
         end
+        if string.find(privilege, 'session') then
+            numeric = numeric + 8
+        end
+        if string.find(privilege, 'usage') then
+            numeric = numeric + 16
+        end
+        if string.find(privilege, 'create') then
+            numeric = numeric + 32
+        end
+        if string.find(privilege, 'drop') then
+            numeric = numeric + 64
+        end
+        if string.find(privilege, 'alter') then
+            numeric = numeric + 128
+        end
+        if string.find(privilege, 'reference') then
+            numeric = numeric + 256
+        end
+        if string.find(privilege, 'trigger') then
+            numeric = numeric + 512
+        end
+        if string.find(privilege, 'insert') then
+            numeric = numeric + 1024
+        end
+        if string.find(privilege, 'update') then
+            numeric = numeric + 2048
+        end
+        if string.find(privilege, 'delete') then
+            numeric = numeric + 4096
+        end
     else
         numeric = privilege
     end
@@ -1599,6 +1629,36 @@ local function privilege_name(privilege)
     if bit.band(privilege, 4) ~= 0 then
         table.insert(names, "execute")
     end
+    if bit.band(privilege, 8) ~= 0 then
+        table.insert(names, "session")
+    end
+    if bit.band(privilege, 16) ~= 0 then
+        table.insert(names, "usage")
+    end
+    if bit.band(privilege, 32) ~= 0 then
+        table.insert(names, "create")
+    end
+    if bit.band(privilege, 64) ~= 0 then
+        table.insert(names, "drop")
+    end
+    if bit.band(privilege, 128) ~= 0 then
+        table.insert(names, "alter")
+    end
+    if bit.band(privilege, 256) ~= 0 then
+        table.insert(names, "reference")
+    end
+    if bit.band(privilege, 512) ~= 0 then
+        table.insert(names, "trigger")
+    end
+    if bit.band(privilege, 1024) ~= 0 then
+        table.insert(names, "insert")
+    end
+    if bit.band(privilege, 2048) ~= 0 then
+        table.insert(names, "update")
+    end
+    if bit.band(privilege, 4096) ~= 0 then
+        table.insert(names, "delete")
+    end
     return table.concat(names, ",")
 end
 
diff --git a/src/box/user_def.c b/src/box/user_def.c
index a382152bf98e0c1556ee804d3d6645a0bf36601a..def541fd0e6749e93150e2ff6ccaf8803996efc0 100644
--- a/src/box/user_def.c
+++ b/src/box/user_def.c
@@ -30,12 +30,34 @@
  */
 #include "user_def.h"
 const char *
-priv_name(uint8_t access)
+priv_name(user_access_t access)
 {
 	if (access & PRIV_R)
 		return "Read";
 	if (access & PRIV_W)
 		return "Write";
-	return "Execute";
+	if (access & PRIV_X)
+		return "Execute";
+	if (access & PRIV_S)
+		return "Session";
+	if (access & PRIV_U)
+		return "Usage";
+	if (access & PRIV_C)
+		return "Create";
+	if (access & PRIV_D)
+		return "Drop";
+	if (access & PRIV_A)
+		return "Alter";
+	if (access & PRIV_REFERENCE)
+		return "Reference";
+	if (access & PRIV_TRIGGER)
+		return "Trigger";
+	if (access & PRIV_INSERT)
+		return "Insert";
+	if (access & PRIV_UPDATE)
+		return "Update";
+	if (access & PRIV_DELETE)
+		return "Delete";
+	return "Any";
 }
 
diff --git a/src/box/user_def.h b/src/box/user_def.h
index 602ac512faf8c330dbaf9f1ecce198393809ae95..f23fc3bb5abeba19cb0de48374c4bd4114061223 100644
--- a/src/box/user_def.h
+++ b/src/box/user_def.h
@@ -39,6 +39,7 @@
 extern "C" {
 #endif /* defined(__cplusplus) */
 
+typedef uint16_t user_access_t;
 /**
  * Effective session user. A cache of user data
  * and access stored in session and fiber local storage.
@@ -52,7 +53,7 @@ struct credentials {
 	 * Cached global grants, to avoid an extra look up
 	 * when checking global grants.
 	 */
-	uint8_t universal_access;
+	user_access_t universal_access;
 	/** User id of the authenticated user. */
 	uint32_t uid;
 };
@@ -60,12 +61,32 @@ struct credentials {
 enum {
 	/* SELECT */
 	PRIV_R = 1,
-	/* INSERT, UPDATE, DELETE, REPLACE */
+	/* INSERT, UPDATE, UPSERT, DELETE, REPLACE */
 	PRIV_W = 2,
 	/* CALL */
 	PRIV_X = 4,
-	/** Everything. */
-	PRIV_ALL = PRIV_R + PRIV_W + PRIV_X
+	/* SESSION */
+	PRIV_S = 8,
+	/* USAGE */
+	PRIV_U = 16,
+	/* CREATE */
+	PRIV_C = 32,
+	/* DROP */
+	PRIV_D = 64,
+	/* ALTER */
+	PRIV_A = 128,
+	/* REFERENCE - required by ANSI - not implemented */
+	PRIV_REFERENCE = 256,
+	/* TRIGGER - required by ANSI - not implemented */
+	PRIV_TRIGGER = 512,
+	/* INSERT - required by ANSI - not implemented */
+	PRIV_INSERT = 1024,
+	/* UPDATE - required by ANSI - not implemented */
+	PRIV_UPDATE = 2048,
+	/* DELETE - required by ANSI - not implemented */
+	PRIV_DELETE = 4096,
+	/* all bits */
+	PRIV_ALL  = ~((user_access_t) 0),
 };
 
 /**
@@ -84,14 +105,14 @@ struct priv_def {
 	 * What is being granted, has been granted, or is being
 	 * revoked.
 	 */
-	uint8_t access;
+	user_access_t access;
 	/** To maintain a set of effective privileges. */
 	rb_node(struct priv_def) link;
 };
 
 /* Privilege name for error messages */
 const char *
-priv_name(uint8_t access);
+priv_name(user_access_t access);
 
 /**
  * Encapsulates privileges of a user on an object.
@@ -103,14 +124,14 @@ struct access {
 	 * Granted access has been given to a user explicitly
 	 * via some form of a grant.
 	 */
-	uint8_t granted;
+	user_access_t granted;
 	/**
 	 * Effective access is a sum of granted access and
 	 * all privileges inherited by a user on this object
 	 * via some role. Since roles may be granted to other
 	 * roles, this may include indirect grants.
 	 */
-	uint8_t effective;
+	user_access_t effective;
 };
 
 /**