diff --git a/src/luamod.lua b/src/luamod.lua
index 473ecb26999d1f4ff362ac35849669891fbc2122..50a2f2af24924464c0a18762e895addc1572e25c 100644
--- a/src/luamod.lua
+++ b/src/luamod.lua
@@ -843,6 +843,7 @@ function pico.grant_privilege(grantee, privilege, object_type, object_name, opts
             op_kind = 'grant_privilege',
             priv_def = {
                 grantee_id = grantee_def.id,
+                grantor_id = box.session.uid(),
                 object_type = object_type,
                 object_name = object_name,
                 privilege = privilege,
@@ -932,7 +933,8 @@ function pico.revoke_privilege(grantee, privilege, object_type, object_name, opt
         -- Throws error if object doesn't exist
         object_resolve(object_type, object_name)
 
-        if box.space._pico_privilege:get{grantee_def.id, object_type, object_name, privilege} == nil then
+        local priv = box.space._pico_privilege:get{grantee_def.id, object_type, object_name, privilege}
+        if priv == nil then
             -- Privilege is not yet granted, no op needed
             return nil
         end
@@ -942,6 +944,7 @@ function pico.revoke_privilege(grantee, privilege, object_type, object_name, opt
             op_kind = 'revoke_privilege',
             priv_def = {
                 grantee_id = grantee_def.id,
+                grantor_id = priv.grantor_id,
                 object_type = object_type,
                 object_name = object_name,
                 privilege = privilege,
diff --git a/src/schema.rs b/src/schema.rs
index 5f30c5a0ef21707bb9dbc0c483a0fe78758ef39b..8c5326c488b2a92fc3fbb82b4456a2dd24e8c12b 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -237,6 +237,7 @@ pub struct PrivilegeDef {
     /// In tarantool users and roles are stored in the same space, which means a
     /// role and a user cannot have the same id or name.
     pub grantee_id: UserId,
+    pub grantor_id: UserId,
     pub object_type: String,
     pub object_name: String,
     pub privilege: String,
diff --git a/src/storage.rs b/src/storage.rs
index 19d82b24394e86a009c2fbe0d0bc8189bd4cb835..a2395efa89d1183b5e65787be7418ccd770e0c51 100644
--- a/src/storage.rs
+++ b/src/storage.rs
@@ -2162,6 +2162,7 @@ impl Privileges {
             .is_local(true)
             .is_temporary(false)
             .field(("grantee_id", FieldType::Unsigned))
+            .field(("grantor_id", FieldType::Unsigned))
             .field(("object_type", FieldType::String))
             .field(("object_name", FieldType::String))
             .field(("privilege", FieldType::String))
diff --git a/src/traft/op.rs b/src/traft/op.rs
index 5193515be85a7c5fe0a53a67fd708f70bf62ec1e..df89e24b9f2954e21aee10034dc666f74741b250 100644
--- a/src/traft/op.rs
+++ b/src/traft/op.rs
@@ -152,24 +152,26 @@ impl std::fmt::Display for Op {
             Self::Acl(Acl::GrantPrivilege { priv_def }) => {
                 let PrivilegeDef {
                     grantee_id,
+                    grantor_id,
                     object_type,
                     object_name,
                     privilege,
                     schema_version,
                     ..
                 } = priv_def;
-                write!(f, "GrantPrivilege({schema_version}, {grantee_id}, {object_type}, {object_name}, {privilege})")
+                write!(f, "GrantPrivilege({schema_version}, {grantee_id}, {grantor_id}, {object_type}, {object_name}, {privilege})")
             }
             Self::Acl(Acl::RevokePrivilege { priv_def }) => {
                 let PrivilegeDef {
                     grantee_id,
+                    grantor_id,
                     object_type,
                     object_name,
                     privilege,
                     schema_version,
                     ..
                 } = priv_def;
-                write!(f, "RevokePrivilege({schema_version}, {grantee_id}, {object_type}, {object_name}, {privilege})")
+                write!(f, "RevokePrivilege({schema_version}, {grantee_id}, {grantor_id}, {object_type}, {object_name}, {privilege})")
             }
         };
 
diff --git a/test/int/test_acl.py b/test/int/test_acl.py
index 44358c68b8965da81efaa3c7209b1afb659e2d59..df1565c378de5c9a515e445661f81125cdb66bfe 100644
--- a/test/int/test_acl.py
+++ b/test/int/test_acl.py
@@ -190,6 +190,14 @@ def test_acl_lua_api(cluster: Cluster):
         "_pico_property",
     )
 
+    dave_id = i1.call("box.space._pico_user.index.name:get", "Dave")[0]
+
+    priv = i1.call(
+        "box.space._pico_privilege:get", (dave_id, "space", "_pico_property", "read")
+    )
+
+    assert priv[1] == 0  # The above grant was executed from guest. 0 is guest user id.
+
     # Already granted -> ok.
     i1.call(
         "pico.grant_privilege",