Explicit permissions API
The Sourcegraph API allows you to explicitly grant and revoke individual users' access to repositories. This is an alternative to other mechanisms, which involve directly talking to the code host.
Explicit permissions are available in the Sourcegraph API starting in Sourcegraph 7.4. A few capabilities, such as marking a repository as unrestricted and sub-repository permissions, are still only available through the Sourcegraph GraphQL debug API. See Capabilities only available in the GraphQL API.
Permissions mechanisms in parallel
If you want to use explicit permissions management alongside permissions synchronised from code hosts, read section permission mechanisms in parallel here.
Recommendations
We only recommend to use explicit permissions API in cases, where the other methods are not possible or effective. E.g. if a code host does not support permission syncing/webhooks or if it would take an unreasonable amount of resources/time to sync permissions from the code host.
It's also a good idea to use explicit permissions API if the source of truth for the codehost permissions is already defined in some external system, e.g. LDAP group membership. In that case, it might be less resource intensive to sync the permissions from external source of truth directly via a periodically running routine.
Disadvantages
It is important to note, that when using explicit permissions API, the permissions are written to the database as provided, without further verification that such permissions do exist on the code host side.
Keeping the permissions in sync and fresh is the responsibility of the administrators.
Configuration
To enable the permissions API, add the following to the advanced configuration:
JSON"permissions.userMapping": { "enabled": true, "bindID": "username" }
The bindID value specifies how to uniquely identify users when setting permissions with the GraphQL operations. The Sourcegraph API does not use bindID; it identifies users by resource name instead.
username: You can set permissions for users by specifying their Sourcegraph usernames. Using usernames is preferred, as usernames are required to be unique for each user.email: You can set permissions for users by specifying their email addresses (which must be verified primary emails associated with their Sourcegraph user account). This method can lead to unexpected results if there are multiple Sourcegraph user accounts with the same verified email address. Also, the email address is case-sensitive, so it should be exactly the same as set on the sourcegraph UI.
After you enable the permissions API, you must grant permissions to allow users to view repositories (administrators bypass all permissions checks and can always view all repositories).
NOTE: If you were previously using permissions syncing, e.g. syncing permissions from Github, then those permissions are used as the initial state after enabling explicit permissions. Otherwise, the initial state is for all repositories to have an empty set of authorized users, so users will not be able to view any repositories.
NOTE: In some cases, in order for the repo permissions to be enforced, you must re-save the code host connection configuration with some modification to the JSON after enabling the permissions API.
Authentication and authorization
Requests to the Sourcegraph API must use a token; browser sessions are not accepted. Use one of the following:
- An access token, in the
Authorization: token <access token>header. - An M2M token for a service account or a token issued by an OAuth app, in the
Authorization: Bearer <token>header.
The token needs the following scopes:
| Operations | Required scope |
|---|---|
GetExplicitRepoPermission, ListExplicitRepoPermissions | externalapi:read |
CreateExplicitRepoPermission, DeleteExplicitRepoPermission | externalapi:write |
Tokens with the user:all scope are also accepted, but their use is recorded in the audit log. We recommend creating tokens with the externalapi:* scopes for integrations.
The user the token belongs to must also have the REPO_PERMISSIONS#READ permission for read operations and REPO_PERMISSIONS#WRITE for write operations. The Administrator role has both by default.
The explicit permissions API also requires a license that includes the explicit permissions API feature. Without it, requests fail with a failed_precondition error.
Managing explicit permissions
Each operation is served at https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/<operation> and accepts a JSON request body with POST. The full schema, including request and response types, is available at /api-reference on your instance (for example, https://sourcegraph.example.com/api-reference).
| Operation | Description |
|---|---|
CreateExplicitRepoPermission | Grant a user explicit access to a repository. |
DeleteExplicitRepoPermission | Revoke a user's explicit access to a repository. |
GetExplicitRepoPermission | Check whether a user has explicit access to a repository. |
ListExplicitRepoPermissions | List explicit permissions for a repository or for a user. |
Each permission is a single grant for one user on one repository. Granting or revoking access for one user does not change the access of any other user.
Resource names
Resources are identified by resource names:
- Repository:
repositories/<repository ID>, where the repository ID is numeric, for examplerepositories/123. See Finding a repository's ID. - User:
users/<user ID>,users/@<username>, orusers/<verified email>, for exampleusers/456,users/@alice, orusers/alice@example.com. - Permission:
repositories/<repository ID>/explicitRepoPermissions/<user>, where<user>accepts the same formats as a user resource name without theusers/prefix, for examplerepositories/123/explicitRepoPermissions/@alice.
Responses always identify repositories and users by their numeric IDs.
Finding a repository's ID
The Sourcegraph API does not yet support looking up a repository by name. You can get the numeric repository ID from the GraphQL debug API:
GRAPHQLquery { repository(name: "github.example.com/owner/repo") { databaseID } }
Granting a user access to a repository
The following example grants the user alice access to the repository with ID 123. The other examples on this page use the same SRC_ACCESS_TOKEN.
BASHexport SRC_ACCESS_TOKEN="sgp_example" curl -X POST "https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/CreateExplicitRepoPermission" \ -H "Authorization: token $SRC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "parent": "repositories/123", "explicitRepoPermission": { "user": "users/@alice" } }'
The response contains the created permission:
JSON{ "name": "repositories/123/explicitRepoPermissions/456", "user": "users/456", "repository": "repositories/123" }
You can also use the user as the parent and specify the repository instead, for example {"parent": "users/@alice", "explicitRepoPermission": {"repository": "repositories/123"}}.
If the user already has explicit access to the repository, the request fails with an already_exists error. The user must already exist in Sourcegraph; otherwise the request fails with a not_found error.
Listing explicit permissions
To list every user with explicit access to a repository, use the repository as the parent:
BASHcurl -X POST "https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/ListExplicitRepoPermissions" \ -H "Authorization: token $SRC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "parent": "repositories/123", "pageSize": 100 }'
To list every repository a user has explicit access to, use the user as the parent, for example {"parent": "users/@alice"}.
JSON{ "explicitRepoPermissions": [ { "name": "repositories/123/explicitRepoPermissions/456", "user": "users/456", "repository": "repositories/123" } ], "nextPageToken": "..." }
To get the next page, repeat the request with pageToken set to the returned nextPageToken. When nextPageToken is empty or missing, there are no more results.
The list only contains permissions granted through the explicit permissions API. Permissions synced from code hosts are not included. To see all repositories a user can access, see Listing a user's authorized repositories.
Checking a single permission
BASHcurl -X POST "https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/GetExplicitRepoPermission" \ -H "Authorization: token $SRC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "repositories/123/explicitRepoPermissions/@alice" }'
If the user does not have explicit access to the repository, the request fails with a not_found error.
Revoking a user's access to a repository
BASHcurl -X POST "https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/DeleteExplicitRepoPermission" \ -H "Authorization: token $SRC_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "repositories/123/explicitRepoPermissions/@alice" }'
A successful request returns an empty JSON object. Only permissions granted through the explicit permissions API can be revoked; for a permission synced from a code host, or one that does not exist, the request fails with a not_found error.
Capabilities only available in the GraphQL API
The following capabilities are not yet available in the Sourcegraph API. Use the Sourcegraph GraphQL debug API for them. The GraphQL API does not provide compatibility guarantees, so prefer the Sourcegraph API for everything it supports.
GraphQL operations identify repositories by their GraphQL ID, which you can get with the following query:
GRAPHQLquery { repository(name: "github.example.com/owner/repo") { id } }
Setting repository permissions for users
The setRepositoryPermissionsForUsers mutation replaces the full list of users allowed to view a repository in one call. Users are identified by their bindID, and permissions for a bindID that does not match an existing user are applied when that user is created.
GRAPHQLmutation { setRepositoryPermissionsForUsers( repository: "<repo ID>" userPermissions: [{bindID: "alice"}, {bindID: "bob"}] ) { alwaysNil } }
Now, only the users specified in the userPermissions parameter will be allowed to view the repository. Sourcegraph automatically enforces these permissions for all operations. (Administrators bypass all permissions checks by default. See the Administrators section)
NOTE: The mutation replaces all explicit permissions for the repository, including permissions granted with the Sourcegraph API.
Setting a repository as unrestricted
Sometimes it can be useful to mark a repository as unrestricted, meaning that it is available to all Sourcegraph users. This can be done with the setRepositoryPermissionsUnrestricted mutation. Marking a repository as unrestricted will disregard any previously set explicit or synced permissions. Setting unrestricted back to false will restore the previous behaviour.
For example:
GRAPHQLmutation { setRepositoryPermissionsUnrestricted( repositories: ["<repo ID>", "<repo ID>", "<repo ID>"] unrestricted: true ) }
Setting sub-repository permissions for users
NOTE: If a user has no sub-repo permissions set for a specific repository (assuming that they have general access to the repository), they will have access to the entire repository contents.
Sourcegraph supports permissions on a per-file/directory basis.
To enable the sub-repo permissions API, add the following to the advanced configuration:
JSON"experimentalFeatures": { "subRepoPermissions": {"enabled": true} }
Sub-repo permissions can be set for a repository via the following GraphQL API:
GRAPHQLmutation { setSubRepositoryPermissionsForUsers( repository: "<repo ID>" userPermissions: [{bindID: "alice", paths: ["-/**", "/README.md"]}] ) { alwaysNil } }
This query denies the user alice access to all files in the repository, except for the file README.md.
The paths are specified in the glob syntax, and a - prefix indicates that the path should be denied.
Permissions are applied in the order they are specified. If we were to want to provide alice access to all files except for the README.md file, we could specify the following:
GRAPHQLmutation { setSubRepositoryPermissionsForUsers( repository: "<repo ID>" userPermissions: [{bindID: "alice", paths: ["/**", "-/README.md"]}] ) { alwaysNil } }
The default permission if a path is not specified is to deny access.
Listing a user's authorized repositories
You may query the set of repositories visible to a particular user with the authorizedUserRepositories GraphQL API query, which accepts a username or email parameter to specify the user:
GRAPHQLquery { authorizedUserRepositories(username: "alice", first: 100) { nodes { name } totalCount } }