Authz post-filtering of search results
Created by: beyang
Fixes https://github.com/sourcegraph/customer/issues/21.
This PR introduces a significant change to the Sourcegraph permissions model, and specifically to the way permissions are computed for search. Prior to this change, permissions were enforced solely by authzFilter
and the permissions model was based on the following constraints:
- Any request for data from a repository X first requests metadata about X from the
db
package (repo metadata is stored in PostgreSQL). - All exported repository accessors in the
db
package callauthzFilter
to check permissions and do not return metadata for unauthorized repositories.
The advantages of this model are that it is easy to understand and simple to enforce. One significant disadvantage is that it requires verifying permissions on all repositories on the instance for global searches. That is because the search architecture requires sending an explicit list of repositories to the indexed-search service, and for global searches, this list is the list of all repositories on the instance. Due to the constraints of the permissions model, permissions were verified when this list of all repositories is compiled.
This PR modifies the permissions model to introduce a bypass mechanism that allows a context item to be set that eliminates permissions checks. It is the caller's responsibility to verify permissions for data that is returned from method invocations made using the cache bypass context item. Obviously, this bypass context item should be used very sparingly. It is currently used in one place in the top-level search handler in package graphqlbackend
. This enables us to check permissions for only the repositories in the search results set (far fewer than the total number of repositories on the instance).
This permission model change is opt-in, toggled by a boolean site config field experimentalFeatures.authz.postSearchFilter
. The config field also disables search suggestions (which still use the old permissions model and would therefore defeat the whole purpose if enabled).