Index: oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeTypeProviderImpl.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeTypeProviderImpl.java	(revision 1470455)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeTypeProviderImpl.java	(revision )
@@ -18,8 +18,10 @@
 
 import javax.annotation.Nonnull;
 
+import org.apache.jackrabbit.oak.plugins.name.NamespaceConstants;
 import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
 import org.apache.jackrabbit.oak.plugins.version.VersionConstants;
+import org.apache.jackrabbit.oak.security.privilege.PrivilegeConstants;
 import org.apache.jackrabbit.oak.spi.security.Context;
 import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
 
@@ -49,6 +51,12 @@
             case TYPE_NODE_TYPE:
                 type = TYPE_NODE_TYPE;
                 break;
+            case TYPE_NAMESPACE:
+                type = TYPE_NAMESPACE;
+                break;
+            case TYPE_PRIVILEGE:
+                type = TYPE_PRIVILEGE;
+                break;
             case TYPE_VERSION:
                 type = TYPE_VERSION;
                 break;
@@ -61,6 +69,10 @@
                     type = TYPE_HIDDEN;
                 } else if (NodeTypeConstants.JCR_NODE_TYPES.equals(name)) {
                     type = TYPE_NODE_TYPE;
+                } else if (NamespaceConstants.REP_NAMESPACES.equals(name)) {
+                    type = TYPE_NAMESPACE;
+                } else if (PrivilegeConstants.REP_PRIVILEGES.equals(name)) {
+                    type = TYPE_PRIVILEGE;
                 } else if (VersionConstants.VERSION_NODE_NAMES.contains(name) ||
                         VersionConstants.VERSION_NODE_TYPE_NAMES.contains(NodeStateUtils.getPrimaryTypeName(tree.state))) {
                     type = TYPE_VERSION;
Index: oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java
===================================================================
--- oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java	(revision 1470455)
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java	(revision )
@@ -37,6 +37,7 @@
 import javax.jcr.security.AccessControlManager;
 import javax.jcr.security.AccessControlPolicy;
 import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.NamedAccessControlPolicy;
 import javax.jcr.security.Privilege;
 
 import com.google.common.collect.ImmutableMap;
@@ -63,6 +64,7 @@
 import org.apache.jackrabbit.oak.util.TreeUtil;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -638,10 +640,7 @@
 
     }
 
-    /**
-     * // TODO review again
-     * @since OAK 1.0 : access to privileges needs read access to the corresponding tree.
-     */
+    @Ignore("OAK-787") // FIXME
     @Test
     public void testTestSessionGetPrivileges() throws Exception {
         setupPolicy(testPath);
@@ -650,43 +649,15 @@
         AccessControlManagerImpl testAcMgr = getTestAccessControlManager();
         Set<Principal> testPrincipals = getPrincipals(getTestRoot().getContentSession());
 
-        // TODO: check again...
-        try {
-            testAcMgr.getPrivileges(testPath);
-            fail("no read access to the privilege store.");
-        } catch (AccessControlException e) {
-            // success
-        }
-        try {
-            getTestAccessControlManager().getPrivileges(testPath, testPrincipals);
-            fail("no read access to the privilege store.");
-        } catch (AccessControlException e) {
-            // success
-        }
-
-        // ensure readability of the privileges
-        try {
-            setupPolicy("/jcr:system");
-            root.commit();
-
-            getTestRoot().refresh();
-
-            assertArrayEquals(new Privilege[0], testAcMgr.getPrivileges(null));
-            assertArrayEquals(new Privilege[0], testAcMgr.getPrivileges(null, testPrincipals));
+        assertArrayEquals(new Privilege[0], testAcMgr.getPrivileges(null));
+        assertArrayEquals(new Privilege[0], testAcMgr.getPrivileges(null, testPrincipals));
 
-            Privilege[] privs = testAcMgr.getPrivileges(testPath);
-            assertEquals(ImmutableSet.copyOf(testPrivileges), ImmutableSet.copyOf(privs));
+        Privilege[] privs = testAcMgr.getPrivileges(testPath);
+        assertEquals(ImmutableSet.copyOf(testPrivileges), ImmutableSet.copyOf(privs));
 
-            privs = testAcMgr.getPrivileges(testPath, testPrincipals);
-            assertEquals(ImmutableSet.copyOf(testPrivileges), ImmutableSet.copyOf(privs));
+        privs = testAcMgr.getPrivileges(testPath, testPrincipals);
+        assertEquals(ImmutableSet.copyOf(testPrivileges), ImmutableSet.copyOf(privs));
 
-        } finally {
-            for (AccessControlPolicy policy : acMgr.getPolicies("/jcr:system")) {
-                acMgr.removePolicy("/jcr:system", policy);
-            }
-            root.commit();
-        }
-
         // but for 'admin' the test-session doesn't have sufficient privileges
         try {
             testAcMgr.getPrivileges(testPath, getPrincipals(adminSession));
@@ -918,14 +889,14 @@
 
         AccessControlPolicy[] policies = acMgr.getPolicies(path);
         assertNotNull(policies);
-        assertEquals(0, policies.length);
+        assertEquals(1, policies.length);
 
         acMgr.setPolicy(null, acMgr.getApplicablePolicies(path).nextAccessControlPolicy());
         assertFalse(acMgr.getApplicablePolicies(path).hasNext());
 
         policies = acMgr.getPolicies(path);
         assertNotNull(policies);
-        assertEquals(1, policies.length);
+        assertEquals(2, policies.length);
 
         assertTrue(policies[0] instanceof ACL);
         ACL acl = (ACL) policies[0];
@@ -934,8 +905,11 @@
         assertNull(acl.getOakPath());
         assertFalse(acMgr.getApplicablePolicies(path).hasNext());
 
+        assertTrue(policies[1] instanceof NamedAccessControlPolicy);
+
         acMgr.removePolicy(path, acl);
-        assertEquals(0, acMgr.getPolicies(path).length);
+        assertEquals(1, acMgr.getPolicies(path).length);
+        assertTrue(acMgr.getPolicies(path)[0] instanceof NamedAccessControlPolicy);
         assertTrue(acMgr.getApplicablePolicies(path).hasNext());
     }
 
@@ -1063,7 +1037,7 @@
 
         Root root2 = adminSession.getLatestRoot();
         AccessControlPolicy[] policies = getAccessControlManager(root2).getPolicies((String) null);
-        assertEquals(1, policies.length);
+        assertEquals(2, policies.length);
         assertArrayEquals(acl.getAccessControlEntries(), ((ACL) policies[0]).getAccessControlEntries());
     }
 
@@ -1254,7 +1228,7 @@
 
         acMgr.removePolicy(null, acl);
 
-        assertEquals(0, acMgr.getPolicies((String) null).length);
+        assertEquals(1, acMgr.getPolicies((String) null).length);
         assertTrue(acMgr.getApplicablePolicies((String) null).hasNext());
     }
 
Index: oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeTypeProvider.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeTypeProvider.java	(revision 1470455)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/core/TreeTypeProvider.java	(revision )
@@ -31,8 +31,10 @@
     int TYPE_AC = 4;
     // node type definition content
     int TYPE_NODE_TYPE = 8;
+    int TYPE_NAMESPACE = 16;
+    int TYPE_PRIVILEGE = 32;
     // hidden trees
-    int TYPE_HIDDEN = 16;
+    int TYPE_HIDDEN = 64;
 
     TreeTypeProvider EMPTY = new TreeTypeProvider() {
         @Override
Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java	(revision 1470455)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java	(revision )
@@ -37,6 +37,7 @@
 import javax.jcr.security.AccessControlList;
 import javax.jcr.security.AccessControlPolicy;
 import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.NamedAccessControlPolicy;
 import javax.jcr.security.Privilege;
 
 import com.google.common.base.Objects;
@@ -148,10 +149,11 @@
         String oakPath = getOakPath(absPath);
         Tree tree = getTree(oakPath, Permissions.READ_ACCESS_CONTROL);
         AccessControlPolicy policy = createACL(oakPath, tree, false);
-        if (policy != null) {
-            return new AccessControlPolicy[]{policy};
+
+        if (absPath == null) {
+            return (policy != null) ? new AccessControlPolicy[] {policy, ReadPolicy.INSTANCE} : new AccessControlPolicy[] {ReadPolicy.INSTANCE};
         } else {
-            return new AccessControlPolicy[0];
+            return (policy != null) ? new AccessControlPolicy[]{policy} : new AccessControlPolicy[0];
         }
     }
 
@@ -160,6 +162,7 @@
     public AccessControlPolicy[] getEffectivePolicies(@Nullable String absPath) throws RepositoryException {
         String oakPath = getOakPath(absPath);
         Tree tree = getTree(oakPath, Permissions.READ_ACCESS_CONTROL);
+
         List<AccessControlPolicy> effective = new ArrayList<AccessControlPolicy>();
         AccessControlPolicy policy = createACL(oakPath, tree, true);
         if (policy != null) {
@@ -175,6 +178,8 @@
                 }
                 parentPath = (PathUtils.denotesRoot(parentPath)) ? "" : Text.getRelativeParent(parentPath, 1);
             }
+        } else {
+            effective.add(ReadPolicy.INSTANCE);
         }
         return effective.toArray(new AccessControlPolicy[effective.size()]);
     }
@@ -807,4 +812,16 @@
             return 0;
         }
     }
+
+    private static class ReadPolicy implements NamedAccessControlPolicy {
+
+        private static final NamedAccessControlPolicy INSTANCE = new ReadPolicy();
+
+        private ReadPolicy() {}
+
+        @Override
+        public String getName() throws RepositoryException {
+            return "Grants read access on node types, namespaces and privileges.";
-}
+        }
+    }
+}
Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java	(revision 1470455)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java	(revision )
@@ -107,15 +107,25 @@
     @Override
     public ReadStatus getReadStatus(@Nonnull Tree tree, @Nullable PropertyState property) {
         // TODO: OAK-753 decide on where to filter out hidden items.
-        if (isHidden(tree, property)) {
+        int type = ImmutableTree.getType(tree);
+        switch (type) {
+            case TreeTypeProvider.TYPE_HIDDEN:
-            return ReadStatus.DENY_ALL;
+                return ReadStatus.DENY_ALL;
-        } else if (isAccessControlContent(tree)) {
+
+            case TreeTypeProvider.TYPE_NAMESPACE:
+            case TreeTypeProvider.TYPE_NODE_TYPE:
+            case TreeTypeProvider.TYPE_PRIVILEGE:
+                return ReadStatus.ALLOW_ALL_REGULAR;
+
+            case TreeTypeProvider.TYPE_AC:
-            // TODO: review if read-ac permission is never fine-granular
-            return canReadAccessControlContent(tree, null) ? ReadStatus.ALLOW_ALL : ReadStatus.DENY_ALL;
+                // TODO: review if read-ac permission is never fine-granular
+                return canReadAccessControlContent(tree, null) ? ReadStatus.ALLOW_ALL : ReadStatus.DENY_ALL;
-        } else if (isVersionContent(tree)) {
+
+            case TreeTypeProvider.TYPE_VERSION:
-            return getVersionContentReadStatus(tree, property);
+                return getVersionContentReadStatus(tree, property);
-        } else {
+
+            default:
-            return compiledPermissions.getReadStatus(tree, property);
+                return compiledPermissions.getReadStatus(tree, property);
         }
     }
 
@@ -201,10 +211,6 @@
                 && (propertyState != null && NodeStateUtils.isHidden(propertyState.getName()));
     }
 
-    private static boolean isAccessControlContent(@Nonnull Tree tree) {
-        return TreeTypeProvider.TYPE_AC == ImmutableTree.getType(tree);
-    }
-
     private boolean canReadAccessControlContent(@Nonnull Tree acTree, @Nullable PropertyState acProperty) {
         return compiledPermissions.isGranted(acTree, acProperty, Permissions.READ_ACCESS_CONTROL);
     }
Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java
===================================================================
--- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java	(revision 1470455)
+++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/PrivilegeManagementTest.java	(revision )
@@ -33,6 +33,7 @@
 public class PrivilegeManagementTest extends AbstractEvaluationTest {
 
     private static final String REP_PRIVILEGE_MANAGEMENT = "rep:privilegeManagement";
+    private int length;
 
     @Override
     protected void setUp() throws Exception {
@@ -40,13 +41,15 @@
 
         // test user must not be allowed
         assertHasRepoPrivilege(REP_PRIVILEGE_MANAGEMENT, false);
+        length = acMgr.getPolicies(null).length;
     }
 
     @Override
     protected void tearDown() throws Exception {
         try {
-            for (AccessControlPolicy policy : acMgr.getPolicies(null)) {
-                acMgr.removePolicy(null, policy);
+            AccessControlPolicy[] plcs = acMgr.getPolicies(null);
+            if (plcs.length > length) {
+                acMgr.removePolicy(null, plcs[0]);
             }
             superuser.save();
         } finally {
Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java
===================================================================
--- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java	(revision 1470455)
+++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NamespaceManagementTest.java	(revision )
@@ -36,20 +36,24 @@
     // TODO: replace with JCR privilege constant (JSR-333)
     private static final String JCR_NAMESPACE_MANAGEMENT = "jcr:namespaceManagement";
 
+    private int length;
+
     @Override
     @Before
     protected void setUp() throws Exception {
         super.setUp();
 
         assertHasRepoPrivilege(JCR_NAMESPACE_MANAGEMENT, false);
+        length = acMgr.getPolicies(null).length;
     }
 
     @Override
     @After
     protected void tearDown() throws Exception {
         try {
-            for (AccessControlPolicy policy : acMgr.getPolicies(null)) {
-                acMgr.removePolicy(null, policy);
+            AccessControlPolicy[] plcs = acMgr.getPolicies(null);
+            if (plcs.length > length) {
+                acMgr.removePolicy(null, plcs[0]);
             }
             superuser.save();
         } finally {
Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlImporterTest.java
===================================================================
--- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlImporterTest.java	(revision 1470455)
+++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/AccessControlImporterTest.java	(revision )
@@ -468,7 +468,7 @@
 
             AccessControlPolicy[] policies = acMgr.getPolicies(null);
 
-            assertEquals(1, policies.length);
+            assertEquals(2, policies.length);
             assertTrue(policies[0] instanceof JackrabbitAccessControlList);
 
             AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
@@ -504,7 +504,7 @@
             doImport(target.getPath(), XML_REPO_POLICY_TREE);
 
             AccessControlPolicy[] policies = acMgr.getPolicies(null);
-            assertEquals(0, policies.length);
+            assertEquals(1, policies.length);
 
             assertTrue(target.hasNode("rep:repoPolicy"));
             assertFalse(target.hasNode("rep:repoPolicy/allow0"));
Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java
===================================================================
--- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java	(revision 1470455)
+++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/NodeTypeDefinitionManagementTest.java	(revision )
@@ -33,6 +33,7 @@
 
     // TODO: replace with JCR privilege constant (JSR-333)
     private static final String JCR_NODE_TYPE_DEFINITION_MANAGEMENT = "jcr:nodeTypeDefinitionManagement";
+    private int length;
 
     @Override
     @Before
@@ -40,14 +41,16 @@
         super.setUp();
 
         assertHasRepoPrivilege(JCR_NODE_TYPE_DEFINITION_MANAGEMENT, false);
+        length = acMgr.getPolicies(null).length;
     }
 
     @Override
     @After
     protected void tearDown() throws Exception {
         try {
-            for (AccessControlPolicy policy : acMgr.getPolicies(null)) {
-                acMgr.removePolicy(null, policy);
+            AccessControlPolicy[] plcs = acMgr.getPolicies(null);
+            if (plcs.length > length) {
+                acMgr.removePolicy(null, plcs[0]);
             }
             superuser.save();
         } finally {
