Skip to content

Commit c556f9d

Browse files
committed
docs: document explicit permissions via the Sourcegraph API
1 parent 00c1232 commit c556f9d

1 file changed

Lines changed: 237 additions & 70 deletions

File tree

docs/admin/permissions/api.mdx

Lines changed: 237 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
# Explicit permissions API
22

3-
Sourcegraph's GraphQL API allows users to explicitly set repository permissions. This is an alternative to other mechanisms, which involve directly talking to the code host.
3+
Sourcegraph supports explicitly setting repository permissions via the [Sourcegraph API](/api). This is an alternative to other mechanisms, which involve directly talking to the code host.
4+
5+
The Sourcegraph API is an external API introduced in Sourcegraph 7.0 for custom integrations. The authoritative schema for the operations described on this page — including request and response types — can be browsed at `/api-reference` on your instance (for example, `https://sourcegraph.example.com/api-reference`), where you can also download the OpenAPI schema.
6+
7+
> NOTE: The explicit permissions API requires the **Explicit Permissions API** license feature. Calls made on an instance without this license feature fail with a `FailedPrecondition` error.
48
59
## Permissions mechanisms in parallel
610

7-
If you want to use explicit permissions managmeent alongside permissions synchronised from code hosts, read section [permission mechanisms in parallel here](/admin/permissions/#permissions-mechanisms-in-parallel).
11+
If you want to use explicit permissions management alongside permissions synchronised from code hosts, read section [permission mechanisms in parallel here](/admin/permissions/#permissions-mechanisms-in-parallel).
812

913
## Recommendations
1014

11-
We only recommend to use explicit permissions API in cases, where the other methods are not possible or effective.
15+
We only recommend to use the explicit permissions API in cases, where the other methods are not possible or effective.
1216
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.
1317

14-
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.
18+
It's also a good idea to use the explicit permissions API if the source of truth for the codehost permissions is already defined in some external system, e.g. LDAP group membership.
1519
In that case, it might be less resource intensive to sync the permissions from external source of truth directly via a periodically running routine.
1620

1721
## SLA
@@ -22,7 +26,7 @@ Sourcegraph does not provide SLA for how fresh the permissions are, since the da
2226

2327
## Disadvantages
2428

25-
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.
29+
It is important to note, that when using the 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.
2630

2731
Keeping the permissions in sync and fresh is the responsibility of the site admins.
2832

@@ -39,116 +43,279 @@ To enable the permissions API, add the following to the [site configuration](/ad
3943

4044
The `bindID` value specifies how to uniquely identify users when setting permissions:
4145

42-
- `username`: You can [set permissions](#setting-repository-permissions-for-users) for users by specifying their Sourcegraph usernames. Using usernames is **preferred**, as usernames are required to be unique for each user.
43-
- `email`: You can [set permissions](#setting-repository-permissions-for-users) 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.
46+
- `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.
47+
- `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.
4448

45-
After you enable the permissions API, you must [set permissions](#setting-repository-permissions-for-users) to allow users to view repositories (site admins bypass all permissions checks and can always view all repositories).
49+
After you enable the permissions API, you must set permissions to allow users to view repositories (site admins bypass all permissions checks and can always view all repositories).
4650

4751
> NOTE: If you were previously using [permissions syncing](/admin/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.
4852
4953
> 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.
5054
51-
## Setting a repository as unrestricted
55+
## API surface
5256

53-
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.
57+
Explicit repository permissions are managed through the following operations on the Sourcegraph API. Each operation is served at `/api/<fully-qualified-method>` on your instance, accepts a JSON request body via HTTP `POST`, and returns a JSON response. The authoritative schema is available at `/api-reference`.
5458

55-
For example:
59+
| Operation | Description |
60+
| --- | --- |
61+
| `explicitrepopermissions.v1.Service/GetExplicitRepoPermission` | Look up a single explicit permission. |
62+
| `explicitrepopermissions.v1.Service/ListExplicitRepoPermissions` | List explicit permissions by repository or by user. |
63+
| `explicitrepopermissions.v1.Service/CreateExplicitRepoPermission` | Grant a user explicit access to a repository. |
64+
| `explicitrepopermissions.v1.Service/DeleteExplicitRepoPermission` | Revoke a user's explicit access to a repository. |
5665

57-
```graphql
58-
mutation {
59-
setRepositoryPermissionsUnrestricted(
60-
repositories: ["<repo ID>", "<repo ID>", "<repo ID>"]
61-
unrestricted: true
62-
)
66+
### Resource names
67+
68+
Resources are addressed using [Google AIP-122](https://google.aip.dev/122) style resource names:
69+
70+
- **Repository**: `repositories/{numeric_id}` — for example, `repositories/123`.
71+
- **User**: `users/{numeric_id}`, `users/@{username}`, or `users/{email}` — for example, `users/456`, `users/@alice`, or `users/alice@example.com`.
72+
- **Permission**: `repositories/{repo_id}/explicitRepoPermissions/{user_id_or_identifier}` — for example, `repositories/123/explicitRepoPermissions/@alice` or `repositories/123/explicitRepoPermissions/456`.
73+
74+
### Authentication
75+
76+
Requests to the Sourcegraph API must authenticate with a token; browser session cookies are not accepted. Pass a Sourcegraph access token as a Bearer token in the `Authorization` header:
77+
78+
```http
79+
Authorization: Bearer <token>
80+
```
81+
82+
OAuth tokens and the standard Sourcegraph HTTP header authentication formats are also accepted.
83+
84+
### Token scopes
85+
86+
Tokens used with these operations must carry the appropriate scopes:
87+
88+
- Read operations (`GetExplicitRepoPermission`, `ListExplicitRepoPermissions`) require the `externalapi:read` scope.
89+
- Write operations (`CreateExplicitRepoPermission`, `DeleteExplicitRepoPermission`) require the `externalapi:write` scope.
90+
91+
Broadly-scoped `user:all` tokens continue to be accepted, but their use against the Sourcegraph API is audit-logged. We recommend issuing scoped tokens to integrations whenever possible.
92+
93+
### RBAC permissions
94+
95+
In addition to a valid token scope, the calling user must also hold the corresponding RBAC permission:
96+
97+
- `REPO_PERMISSIONS#READ` for read operations.
98+
- `REPO_PERMISSIONS#WRITE` for write operations.
99+
100+
Site admins bypass all permissions checks by default. See the [Site administrators](/admin/permissions/#site-administrators) section.
101+
102+
## Operations
103+
104+
### GetExplicitRepoPermission
105+
106+
Look up a single explicit repository permission by name.
107+
108+
**Request**
109+
110+
```json
111+
{
112+
"name": "repositories/123/explicitRepoPermissions/@alice"
63113
}
64114
```
65115

66-
## Setting repository permissions for users
116+
**Response**
67117

68-
Setting the permissions for a user can be accomplished with 2 [GraphQL API](/api/graphql) calls.
118+
```json
119+
{
120+
"name": "repositories/123/explicitRepoPermissions/456",
121+
"user": "users/456",
122+
"repository": "repositories/123"
123+
}
124+
```
69125

70-
First, obtain the ID of the repository from its name:
126+
### ListExplicitRepoPermissions
71127

72-
```graphql
73-
query {
74-
repository(name: "github.com/owner/repo") {
75-
id
76-
}
128+
List the explicit permissions associated with a repository or with a user. The `parent` field selects the listing dimension and may be either a repository or a user resource name.
129+
130+
**Request — by repository**
131+
132+
```json
133+
{
134+
"parent": "repositories/123",
135+
"page_size": 50,
136+
"page_token": ""
77137
}
78138
```
79139

80-
Next, set the list of users allowed to view the repository:
140+
**Request — by user**
81141

82-
```graphql
83-
mutation {
84-
setRepositoryPermissionsForUsers(
85-
repository: "<repo ID>"
86-
userPermissions: [{bindID: "alice"}, {bindID: "bob"}]
87-
) {
88-
alwaysNil
89-
}
142+
```json
143+
{
144+
"parent": "users/@alice",
145+
"page_size": 50
90146
}
91147
```
92148

93-
Now, only the users specified in the `userPermissions` parameter will be allowed to view the repository. Sourcegraph automatically enforces these permissions for all operations. (Site admins bypass all permissions checks by default. See the [Site administrators](/admin/permissions/#site-administrators) section)
149+
**Response**
94150

95-
You can call `setRepositoryPermissionsForUsers` repeatedly to set permissions for each repository, and whenever you want to change the list of authorized users.
151+
```json
152+
{
153+
"explicit_repo_permissions": [
154+
{
155+
"name": "repositories/123/explicitRepoPermissions/456",
156+
"user": "users/456",
157+
"repository": "repositories/123"
158+
}
159+
],
160+
"next_page_token": "..."
161+
}
162+
```
96163

97-
## Setting sub-repository permissions for users
164+
Pass the returned `next_page_token` back in a subsequent request to fetch the next page. An empty `next_page_token` indicates that there are no more results.
98165

99-
> 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.
166+
### CreateExplicitRepoPermission
100167

101-
Sourcegraph supports permissions on a per-file/directory basis.
168+
Grant a user explicit access to a repository. The `parent` may be either the repository or the user; the other side of the relationship is supplied in `explicit_repo_permission`.
102169

103-
To enable the sub-repo permissions API, add the following to the [site configuration](/admin/config/site-config):
170+
**Request — parent is a repository**
104171

105172
```json
106-
"experimentalFeatures": {
107-
"subRepoPermissions": {"enabled": true}
173+
{
174+
"parent": "repositories/123",
175+
"explicit_repo_permission": {
176+
"user": "users/@alice"
177+
}
108178
}
109179
```
110180

111-
Sub-repo permissions can be set for a repository via the following GraphQL API:
181+
**Request — parent is a user**
112182

113-
```graphql
114-
mutation {
115-
setSubRepositoryPermissionsForUsers(
116-
repository: "<repo ID>"
117-
userPermissions: [{bindID: "alice", paths: ["-/**", "/README.md"]}]
118-
) {
119-
alwaysNil
120-
}
183+
```json
184+
{
185+
"parent": "users/@alice",
186+
"explicit_repo_permission": {
187+
"repository": "repositories/123"
188+
}
121189
}
122190
```
123191

124-
This query denies the user `alice` access to all files in the repository, except for the file `README.md`.
125-
The paths are specified in the [glob syntax](<https://en.wikipedia.org/wiki/Glob_(programming)>), and a `-` prefix indicates that the path should be denied.
126-
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:
192+
**Response**
193+
194+
The created `ExplicitRepoPermission`:
195+
196+
```json
197+
{
198+
"name": "repositories/123/explicitRepoPermissions/456",
199+
"user": "users/456",
200+
"repository": "repositories/123"
201+
}
202+
```
203+
204+
### DeleteExplicitRepoPermission
205+
206+
Revoke a user's explicit access to a repository.
207+
208+
**Request**
209+
210+
```json
211+
{
212+
"name": "repositories/123/explicitRepoPermissions/@alice"
213+
}
214+
```
215+
216+
**Response**
217+
218+
```json
219+
{}
220+
```
221+
222+
## Examples
223+
224+
The examples below use `https://sourcegraph.example.com` as a placeholder for your instance, and assume your access token is exported as `SRC_ACCESS_TOKEN`.
225+
226+
### Grant alice access to repository 123
227+
228+
```bash
229+
curl -X POST \
230+
-H "Authorization: Bearer $SRC_ACCESS_TOKEN" \
231+
-H "Content-Type: application/json" \
232+
-d '{
233+
"parent": "repositories/123",
234+
"explicit_repo_permission": { "user": "users/@alice" }
235+
}' \
236+
https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/CreateExplicitRepoPermission
237+
```
238+
239+
### List all users with explicit access to repository 123
240+
241+
```bash
242+
curl -X POST \
243+
-H "Authorization: Bearer $SRC_ACCESS_TOKEN" \
244+
-H "Content-Type: application/json" \
245+
-d '{
246+
"parent": "repositories/123",
247+
"page_size": 50
248+
}' \
249+
https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/ListExplicitRepoPermissions
250+
```
251+
252+
### List all repositories alice has explicit access to
253+
254+
```bash
255+
curl -X POST \
256+
-H "Authorization: Bearer $SRC_ACCESS_TOKEN" \
257+
-H "Content-Type: application/json" \
258+
-d '{
259+
"parent": "users/@alice",
260+
"page_size": 50
261+
}' \
262+
https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/ListExplicitRepoPermissions
263+
```
264+
265+
### Revoke alice's access to repository 123
266+
267+
```bash
268+
curl -X POST \
269+
-H "Authorization: Bearer $SRC_ACCESS_TOKEN" \
270+
-H "Content-Type: application/json" \
271+
-d '{
272+
"name": "repositories/123/explicitRepoPermissions/@alice"
273+
}' \
274+
https://sourcegraph.example.com/api/explicitrepopermissions.v1.Service/DeleteExplicitRepoPermission
275+
```
276+
277+
## Capabilities not yet covered by the Sourcegraph API
278+
279+
The capabilities below are not yet available on the Sourcegraph API and are currently only accessible through the [Sourcegraph GraphQL debug API](/api/graphql). They will be ported to the Sourcegraph API in a future release.
280+
281+
### Marking a repository as unrestricted
282+
283+
Sometimes it can be useful to mark a repository as `unrestricted`, meaning that it is available to all Sourcegraph users regardless of explicit or synced permissions. Setting `unrestricted` back to `false` restores the previous behaviour.
284+
285+
This capability is currently only available via the [Sourcegraph GraphQL debug API](/api/graphql):
127286

128287
```graphql
129288
mutation {
130-
setSubRepositoryPermissionsForUsers(
131-
repository: "<repo ID>"
132-
userPermissions: [{bindID: "alice", paths: ["/**", "-/README.md"]}]
133-
) {
134-
alwaysNil
135-
}
289+
setRepositoryPermissionsUnrestricted(
290+
repositories: ["<repo ID>", "<repo ID>"]
291+
unrestricted: true
292+
)
136293
}
137294
```
138295

139-
The default permission if a path is not specified is to deny access.
296+
### Sub-repository permissions
297+
298+
Sourcegraph supports experimental per-file/directory permissions within a repository. To enable this feature, add the following to the [site configuration](/admin/config/site-config):
299+
300+
```json
301+
"experimentalFeatures": {
302+
"subRepoPermissions": { "enabled": true }
303+
}
304+
```
140305

141-
### Listing a user's authorized repositories
306+
Paths are specified in [glob syntax](<https://en.wikipedia.org/wiki/Glob_(programming)>). A `-` prefix denies a path, rules are applied in the order in which they are listed, and any path that does not match a rule defaults to deny. A user who has general access to a repository but has no sub-repo rules set retains access to the entire repository.
142307

143-
You may query the set of repositories visible to a particular user with the `authorizedUserRepositories` [GraphQL API](/api/graphql) query, which accepts a `username` or `email` parameter to specify the user:
308+
This capability is currently only available via the [Sourcegraph GraphQL debug API](/api/graphql). For example, the following grants `alice` access to every file in the repository except `README.md`:
144309

145310
```graphql
146-
query {
147-
authorizedUserRepositories(username: "alice", first: 100) {
148-
nodes {
149-
name
150-
}
151-
totalCount
152-
}
311+
mutation {
312+
setSubRepositoryPermissionsForUsers(
313+
repository: "<repo ID>"
314+
userPermissions: [{ bindID: "alice", paths: ["/**", "-/README.md"] }]
315+
) {
316+
alwaysNil
317+
}
153318
}
154319
```
320+
321+
> NOTE: The [Sourcegraph GraphQL debug API](/api/graphql) is intended for diagnostics and simple tooling and does not provide backwards-compatibility guarantees. Prefer the Sourcegraph API for production integrations.

0 commit comments

Comments
 (0)