diff --git a/src/box/sysview_index.cc b/src/box/sysview_index.cc
index b83054961c5dc7b9ec83d1e6657de46073aa2f95..9b1910128026e975c9c11a4cb025793f387f67e5 100644
--- a/src/box/sysview_index.cc
+++ b/src/box/sysview_index.cc
@@ -35,6 +35,7 @@
 struct sysview_iterator {
 	struct iterator base;
 	struct iterator *source;
+	struct space *space;
 };
 
 static inline struct sysview_iterator *
@@ -63,7 +64,7 @@ sysview_iterator_next(struct iterator *iterator)
 	class SysviewIndex *index = (class SysviewIndex *) iterator->index;
 	struct tuple *tuple;
 	while ((tuple = it->source->next(it->source)) != NULL) {
-		if (index->predicate(tuple))
+		if (index->predicate(it->space, tuple))
 			return tuple;
 	}
 	return NULL;
@@ -121,6 +122,7 @@ SysviewIndex::initIterator(struct iterator *iterator,
 	pk->initIterator(it->source, type, key, part_count);
 	iterator->index = (Index *) this;
 	iterator->next = sysview_iterator_next;
+	it->space = source;
 }
 
 struct tuple *
@@ -132,7 +134,7 @@ SysviewIndex::findByKey(const char *key, uint32_t part_count) const
 		tnt_raise(ClientError, ER_MORE_THAN_ONE_TUPLE);
 	primary_key_validate(pk->key_def, key, part_count);
 	struct tuple *tuple = pk->findByKey(key, part_count);
-	if (tuple == NULL || !predicate(tuple))
+	if (tuple == NULL || !predicate(source, tuple))
 		return NULL;
 	return tuple;
 }
@@ -148,11 +150,16 @@ SysviewIndex::replace(struct tuple *old_tuple, struct tuple *new_tuple,
 }
 
 static bool
-vspace_predicate(struct tuple *tuple)
+vspace_predicate(struct space *source, struct tuple *tuple)
 {
+	struct credentials *cr = current_user();
+	if (PRIV_R & cr->universal_access)
+		return true; /* read access to unverse */
+	if (PRIV_R & source->access[cr->auth_token].effective)
+		return true; /* read access to original space */
+
 	uint32_t space_id = tuple_field_u32(tuple, 0);
 	struct space *space = space_cache_find(space_id);
-	struct credentials *cr = current_user();
 	uint8_t effective = space->access[cr->auth_token].effective;
 	return ((PRIV_R | PRIV_W) & (cr->universal_access | effective) ||
 		space->def.uid == cr->uid);
@@ -169,11 +176,14 @@ SysviewVindexIndex::SysviewVindexIndex(struct key_def *key_def)
 }
 
 static bool
-vuser_predicate(struct tuple *tuple)
+vuser_predicate(struct space *source, struct tuple *tuple)
 {
 	struct credentials *cr = current_user();
 	if (PRIV_R & cr->universal_access)
-		return true;
+		return true; /* read access to unverse */
+	if (PRIV_R & source->access[cr->auth_token].effective)
+		return true; /* read access to original space */
+
 	uint32_t uid = tuple_field_u32(tuple, 0);
 	uint32_t owner_id = tuple_field_u32(tuple, 1);
 	return uid == cr->uid || owner_id == cr->uid;
@@ -185,11 +195,14 @@ SysviewVuserIndex::SysviewVuserIndex(struct key_def *key_def)
 }
 
 static bool
-vpriv_predicate(struct tuple *tuple)
+vpriv_predicate(struct space *source, struct tuple *tuple)
 {
 	struct credentials *cr = current_user();
 	if (PRIV_R & cr->universal_access)
-		return true;
+		return true; /* read access to unverse */
+	if (PRIV_R & source->access[cr->auth_token].effective)
+		return true; /* read access to original space */
+
 	uint32_t grantor_id = tuple_field_u32(tuple, 0);
 	uint32_t grantee_id = tuple_field_u32(tuple, 1);
 	return grantor_id == cr->uid || grantee_id == cr->uid;
@@ -201,18 +214,20 @@ SysviewVprivIndex::SysviewVprivIndex(struct key_def *key_def)
 }
 
 static bool
-vfunc_predicate(struct tuple *tuple)
+vfunc_predicate(struct space *source, struct tuple *tuple)
 {
 	struct credentials *cr = current_user();
-	if (PRIV_X & cr->universal_access)
-		return true;
-	uint32_t owner_id = tuple_field_u32(tuple, 1);
-	if (owner_id == cr->uid)
-		return true;
+	if ((PRIV_R | PRIV_X) & cr->universal_access)
+		return true; /* read or execute access to unverse */
+	if (PRIV_R & source->access[cr->auth_token].effective)
+		return true; /* read access to original space */
+
 	const char *name = tuple_field_cstr(tuple, 2);
 	uint32_t name_len = strlen(name);
 	struct func_def *func = func_by_name(name, name_len);
-	if (func != NULL && (PRIV_X & func->access[cr->auth_token].effective))
+	assert(func != NULL);
+	uint8_t effective = func->access[cr->auth_token].effective;
+	if (func->uid == cr->uid || (PRIV_X & effective))
 		return true;
 	return false;
 }
diff --git a/src/box/sysview_index.h b/src/box/sysview_index.h
index de3137a5b391030d65b91baab0f67ae438354ca9..fe1d93e9c7dedca5ba2b00ac5788c902dbd448e3 100644
--- a/src/box/sysview_index.h
+++ b/src/box/sysview_index.h
@@ -33,7 +33,7 @@
 
 struct sysview_iterator;
 
-typedef bool (*sysview_predicate_f)(struct tuple *);
+typedef bool (*sysview_predicate_f)(struct space *source, struct tuple *);
 
 class SysviewIndex: public Index {
 public:
diff --git a/test/box/access_sysview.result b/test/box/access_sysview.result
index 501c2dfe310e951644352849256e59b287c73c28..69c72a935a7d2224eb33b5c75dbe7a96ea7f6add 100644
--- a/test/box/access_sysview.result
+++ b/test/box/access_sysview.result
@@ -238,10 +238,6 @@ box.schema.user.grant('guest', 'write', 'universe')
 box.session.su('guest')
 ---
 ...
-#box.space._vspace:select{}
----
-- 13
-...
 #box.space._vindex:select{}
 ---
 - 32
@@ -270,6 +266,53 @@ box.space.test:drop()
 box.session.su('guest')
 ---
 ...
+-- read access to original space also allow to read a view
+box.session.su('admin')
+---
+...
+space_cnt = #box.space._space:select{}
+---
+...
+index_cnt = #box.space._index:select{}
+---
+...
+box.schema.user.grant('guest', 'read', 'space', '_space')
+---
+...
+box.schema.user.grant('guest', 'read', 'space', '_index')
+---
+...
+box.session.su('guest')
+---
+...
+#box.space._vspace:select{} == space_cnt
+---
+- true
+...
+#box.space._vindex:select{} == index_cnt
+---
+- true
+...
+box.session.su('admin')
+---
+...
+box.schema.user.revoke('guest', 'read', 'space', '_space')
+---
+...
+box.schema.user.revoke('guest', 'read', 'space', '_index')
+---
+...
+box.session.su('guest')
+---
+...
+#box.space._vspace:select{} < space_cnt
+---
+- true
+...
+#box.space._vindex:select{} < index_cnt
+---
+- true
+...
 --
 -- _vuser
 --
@@ -278,9 +321,35 @@ t = box.space._vuser:select(); return #t == 1 and t[1][3] == 'guest'
 ---
 - true
 ...
-#box.space._vuser:select{}
+-- read access to original space also allow to read a view
+box.session.su('admin')
+---
+...
+user_cnt = #box.space._user:select{}
+---
+...
+box.schema.user.grant('guest', 'read', 'space', '_user')
+---
+...
+box.session.su('guest')
+---
+...
+#box.space._vuser:select{} == user_cnt
+---
+- true
+...
+box.session.su('admin')
+---
+...
+box.schema.user.revoke('guest', 'read', 'space', '_user')
 ---
-- 1
+...
+box.session.su('guest')
+---
+...
+#box.space._vuser:select{} < user_cnt
+---
+- true
 ...
 box.session.su('admin')
 ---
@@ -324,9 +393,39 @@ box.space._vpriv.index[2]:select('role')[1][2] == session.uid()
 ---
 - true
 ...
+-- read access to original space also allow to read a view
+box.session.su('admin')
+---
+...
+box.schema.user.grant('guest', 'read', 'space', '_priv')
+---
+...
+priv_cnt = #box.space._priv:select{}
+---
+...
+box.session.su('guest')
+---
+...
+#box.space._vpriv:select{} == priv_cnt
+---
+- true
+...
+box.session.su('admin')
+---
+...
+box.schema.user.revoke('guest', 'read', 'space', '_priv')
+---
+...
+box.session.su('guest')
+---
+...
 cnt = #box.space._vpriv:select{}
 ---
 ...
+cnt < priv_cnt
+---
+- true
+...
 box.session.su('admin')
 ---
 ...
@@ -356,13 +455,43 @@ box.session.su('guest')
 --
 -- _vfunc
 --
-cnt = #box.space._vfunc:select{}
+box.session.su('admin')
+---
+...
+box.schema.func.create('test')
+---
+...
+-- read access to original space also allow to read a view
+func_cnt = #box.space._func:select{}
 ---
 ...
+box.schema.user.grant('guest', 'read', 'space', '_func')
+---
+...
+box.session.su('guest')
+---
+...
+#box.space._vfunc:select{} == func_cnt
+---
+- true
+...
 box.session.su('admin')
 ---
 ...
-box.schema.func.create('test')
+box.schema.user.revoke('guest', 'read', 'space', '_func')
+---
+...
+box.session.su('guest')
+---
+...
+cnt = #box.space._vfunc:select{}
+---
+...
+cnt < func_cnt
+---
+- true
+...
+box.session.su('admin')
 ---
 ...
 box.schema.user.grant('guest', 'execute', 'function', 'test')
diff --git a/test/box/access_sysview.test.lua b/test/box/access_sysview.test.lua
index af8405c1b95feff1f4849de96b5e2fd23a043251..0fee93226d890a059f039763a692ddeff13e6de3 100644
--- a/test/box/access_sysview.test.lua
+++ b/test/box/access_sysview.test.lua
@@ -94,7 +94,6 @@ box.schema.user.revoke('guest', 'read', 'universe')
 box.schema.user.grant('guest', 'write', 'universe')
 box.session.su('guest')
 
-#box.space._vspace:select{}
 #box.space._vindex:select{}
 #box.space._vuser:select{}
 #box.space._vpriv:select{}
@@ -105,6 +104,22 @@ box.schema.user.revoke('guest', 'write', 'universe')
 box.space.test:drop()
 box.session.su('guest')
 
+-- read access to original space also allow to read a view
+box.session.su('admin')
+space_cnt = #box.space._space:select{}
+index_cnt = #box.space._index:select{}
+box.schema.user.grant('guest', 'read', 'space', '_space')
+box.schema.user.grant('guest', 'read', 'space', '_index')
+box.session.su('guest')
+#box.space._vspace:select{} == space_cnt
+#box.space._vindex:select{} == index_cnt
+box.session.su('admin')
+box.schema.user.revoke('guest', 'read', 'space', '_space')
+box.schema.user.revoke('guest', 'read', 'space', '_index')
+box.session.su('guest')
+#box.space._vspace:select{} < space_cnt
+#box.space._vindex:select{} < index_cnt
+
 --
 -- _vuser
 --
@@ -112,7 +127,16 @@ box.session.su('guest')
 -- a guest user can read information about itself
 t = box.space._vuser:select(); return #t == 1 and t[1][3] == 'guest'
 
-#box.space._vuser:select{}
+-- read access to original space also allow to read a view
+box.session.su('admin')
+user_cnt = #box.space._user:select{}
+box.schema.user.grant('guest', 'read', 'space', '_user')
+box.session.su('guest')
+#box.space._vuser:select{} == user_cnt
+box.session.su('admin')
+box.schema.user.revoke('guest', 'read', 'space', '_user')
+box.session.su('guest')
+#box.space._vuser:select{} < user_cnt
 
 box.session.su('admin')
 box.schema.user.grant('guest', 'read,write', 'universe')
@@ -137,8 +161,19 @@ box.session.su('guest')
 -- a guest user can see granted 'public' role
 box.space._vpriv.index[2]:select('role')[1][2] == session.uid()
 
+-- read access to original space also allow to read a view
+box.session.su('admin')
+box.schema.user.grant('guest', 'read', 'space', '_priv')
+priv_cnt = #box.space._priv:select{}
+box.session.su('guest')
+#box.space._vpriv:select{} == priv_cnt
+box.session.su('admin')
+box.schema.user.revoke('guest', 'read', 'space', '_priv')
+box.session.su('guest')
 cnt = #box.space._vpriv:select{}
 
+cnt < priv_cnt
+
 box.session.su('admin')
 box.schema.user.grant('guest', 'read,write', 'space', '_schema')
 box.session.su('guest')
@@ -155,10 +190,22 @@ box.session.su('guest')
 -- _vfunc
 --
 
+box.session.su('admin')
+box.schema.func.create('test')
+
+-- read access to original space also allow to read a view
+func_cnt = #box.space._func:select{}
+box.schema.user.grant('guest', 'read', 'space', '_func')
+box.session.su('guest')
+#box.space._vfunc:select{} == func_cnt
+box.session.su('admin')
+box.schema.user.revoke('guest', 'read', 'space', '_func')
+box.session.su('guest')
 cnt = #box.space._vfunc:select{}
 
+cnt < func_cnt
+
 box.session.su('admin')
-box.schema.func.create('test')
 box.schema.user.grant('guest', 'execute', 'function', 'test')
 box.session.su('guest')