You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add per-connection enforcePermissions toggle and promote PERMISSION_SYNC_ENABLED (#991)
* feat(worker): add per-connection enforcePermissions toggle and promote PERMISSION_SYNC_ENABLED
- Add `enforcePermissions` boolean to all connection config schemas (github, gitlab, bitbucket, gitea, gerrit, azuredevops, genericGitHost). Defaults to the value of `PERMISSION_SYNC_ENABLED` when not set.
- Add `enforcePermissions` column to the `Connection` DB model (migration: 20260310050300).
- Sync `enforcePermissions` from config in `configManager.ts` on create/update.
- Filter repo permission syncer to only queue repos with at least one connection with `enforcePermissions: true`.
- Update `getRepoPermissionFilterForUser` in `prisma.ts` to exempt repos where no connection has `enforcePermissions: true`.
- Deprecate `EXPERIMENT_EE_PERMISSION_SYNC_ENABLED` in favour of `PERMISSION_SYNC_ENABLED` (backwards-compatible via Zod transform fallback).
- Remove `isPermissionSyncEnabled()` helper; replace all call sites with `env.PERMISSION_SYNC_ENABLED === 'true'`.
- Add unit tests for `PERMISSION_SYNC_ENABLED` env var behaviour in `packages/shared/src/env.server.test.ts`.
- Extract `createEnv` options as named export to preserve JSDoc (`@deprecated`) in emitted `.d.ts` (see microsoft/TypeScript#62309).
- Update permission-syncing and environment-variables docs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: update CHANGELOG for #991
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add repoDrivenPermissionSyncIntervalMs and userDrivenPermissionSyncIntervalMs config settings
- Add `repoDrivenPermissionSyncIntervalMs` and `userDrivenPermissionSyncIntervalMs` to the config schema, deprecating the `experiment_` prefixed variants (still respected as fallbacks in getConfigSettings).
- Update repoPermissionSyncer and accountPermissionSyncer to use the new setting names.
- Add tests for getConfigSettings fallback behaviour.
- Update docs and CHANGELOG.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feedback
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
-[EE] Added `enforcePermissions` per-connection flag to control whether repository permissions are enforced for a given connection. Defaults to the value of `PERMISSION_SYNC_ENABLED`. [#991](https://github.com/sourcebot-dev/sourcebot/pull/991)
14
+
-[EE] Added `repoDrivenPermissionSyncIntervalMs` and `userDrivenPermissionSyncIntervalMs` config settings, deprecating the `experiment_` prefixed variants (still respected as fallbacks). [#991](https://github.com/sourcebot-dev/sourcebot/pull/991)
15
+
16
+
### Changed
17
+
-[EE] Promoted `PERMISSION_SYNC_ENABLED` as the canonical env var for enabling permission syncing, deprecating `EXPERIMENT_EE_PERMISSION_SYNC_ENABLED` (still respected as a fallback). [#991](https://github.com/sourcebot-dev/sourcebot/pull/991)
Copy file name to clipboardExpand all lines: docs/docs/configuration/environment-variables.mdx
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,8 +45,9 @@ The following environment variables allow you to configure your Sourcebot deploy
45
45
|`SOURCEBOT_EE_AUDIT_RETENTION_DAYS`|`180`| <p>The number of days to retain audit logs. Audit log records older than this will be automatically pruned daily. Set to `0` to disable pruning and retain logs indefinitely.</p> |
46
46
|`AUTH_EE_GCP_IAP_ENABLED`|`false`| <p>When enabled, allows Sourcebot to automatically register/login from a successful GCP IAP redirect</p> |
47
47
|`AUTH_EE_GCP_IAP_AUDIENCE`| - | <p>The GCP IAP audience to use when verifying JWT tokens. Must be set to enable GCP IAP JIT provisioning</p> |
|`PERMISSION_SYNC_REPO_DRIVEN_ENABLED`|`true`| <p>Enables/disables [repo-driven permission syncing](/docs/features/permission-syncing#how-it-works). Only applies when `EXPERIMENT_EE_PERMISSION_SYNC_ENABLED` is `true`.</p> |
|`PERMISSION_SYNC_REPO_DRIVEN_ENABLED`|`true`| <p>Enables/disables [repo-driven permission syncing](/docs/features/permission-syncing#how-it-works). Only applies when `PERMISSION_SYNC_ENABLED` is `true`.</p> |
50
+
|`EXPERIMENT_EE_PERMISSION_SYNC_ENABLED`**(deprecated)**|`false`| <p>Deprecated. Use `PERMISSION_SYNC_ENABLED` instead.</p> |
50
51
|`AUTH_EE_ALLOW_EMAIL_ACCOUNT_LINKING`|`true`| <p>When enabled, different SSO accounts with the same email address will automatically be linked.</p> |
Copy file name to clipboardExpand all lines: docs/docs/features/permission-syncing.mdx
+56-22Lines changed: 56 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,11 +18,11 @@ that they have access to on the code host. Practically, this means:
18
18
- Ask Sourcebot (and the underlying LLM) will only have access to repositories that the user has access to.
19
19
- File browsing is scoped to the repositories that the user has access to.
20
20
21
-
Permission syncing can be enabled by setting the `EXPERIMENT_EE_PERMISSION_SYNC_ENABLED` environment variable to `true`.
21
+
Permission syncing can be enabled by setting the `PERMISSION_SYNC_ENABLED` environment variable to `true`.
22
22
23
23
```bash
24
24
docker run \
25
-
-e EXPERIMENT_EE_PERMISSION_SYNC_ENABLED=true \
25
+
-e PERMISSION_SYNC_ENABLED=true \
26
26
/* additional args */ \
27
27
ghcr.io/sourcebot-dev/sourcebot:latest
28
28
```
@@ -97,9 +97,9 @@ Permission syncing works with **Bitbucket Cloud**. OAuth tokens must assume the
97
97
- Membership in the [project that contains the repository](https://support.atlassian.com/bitbucket-cloud/docs/configure-project-permissions-for-users-and-groups/)
98
98
- Membership in a group that is part of a project containing the repository
99
99
100
-
These users **will** still gain access via [user-driven syncing](/docs/features/permission-syncing#how-it-works), which fetches all private repositories accessible to each authenticated user. However, there may be a delay between when a repository is added and when affected users gain access in Sourcebot (up to the `experiment_userDrivenPermissionSyncIntervalMs` interval, which defaults to 24 hours).
100
+
These users **will** still gain access via [user-driven syncing](/docs/features/permission-syncing#how-it-works), which fetches all private repositories accessible to each authenticated user. However, there may be a delay between when a repository is added and when affected users gain access in Sourcebot (up to the `userDrivenPermissionSyncIntervalMs` interval, which defaults to 24 hours).
101
101
102
-
If your workspace relies heavily on group or project-level permissions rather than direct user grants, we recommend reducing the `experiment_userDrivenPermissionSyncIntervalMs` interval to limit the window of delay.
102
+
If your workspace relies heavily on group or project-level permissions rather than direct user grants, we recommend reducing the `userDrivenPermissionSyncIntervalMs` interval to limit the window of delay.
103
103
</Warning>
104
104
105
105
**Notes:**
@@ -120,16 +120,64 @@ Permission syncing works with **Bitbucket Data Center**. OAuth tokens must assum
120
120
- Project-level permissions (inherited by all repos in the project)
121
121
- Group membership
122
122
123
-
These users **will** still gain access via [user-driven syncing](/docs/features/permission-syncing#how-it-works), which fetches all repositories accessible to each authenticated user using the `REPO_READ` scope. However, there may be a delay between when access is granted and when affected users see the repository in Sourcebot (up to the `experiment_userDrivenPermissionSyncIntervalMs` interval, which defaults to 24 hours).
123
+
These users **will** still gain access via [user-driven syncing](/docs/features/permission-syncing#how-it-works), which fetches all repositories accessible to each authenticated user using the `REPO_READ` scope. However, there may be a delay between when access is granted and when affected users see the repository in Sourcebot (up to the `userDrivenPermissionSyncIntervalMs` interval, which defaults to 24 hours).
124
124
125
-
If your instance relies heavily on project or group-level permissions, we recommend reducing the `experiment_userDrivenPermissionSyncIntervalMs` interval to limit the window of delay.
125
+
If your instance relies heavily on project or group-level permissions, we recommend reducing the `userDrivenPermissionSyncIntervalMs` interval to limit the window of delay.
126
126
</Warning>
127
127
128
128
**Notes:**
129
129
- A Bitbucket Data Center [external identity provider](/docs/configuration/idp#bitbucket-server) must be configured to (1) correlate a Sourcebot user with a Bitbucket Data Center user, and (2) to list repositories that the user has access to for [User driven syncing](/docs/features/permission-syncing#how-it-works).
130
130
- The connection token must have **Repository Read** permissions so Sourcebot can read repository-level user permissions for [Repo driven syncing](/docs/features/permission-syncing#how-it-works).
131
131
- OAuth tokens require the `REPO_READ` scope to list accessible repositories during [User driven syncing](/docs/features/permission-syncing#how-it-works).
132
132
133
+
# Manually refreshing permissions
134
+
135
+
If a user's permissions have changed and they need access updated immediately (without waiting for the next scheduled sync), they can trigger a manual refresh from the **Linked Accounts** page:
136
+
137
+
1. Navigate to **Settings → Linked Accounts**.
138
+
2. Click the **Connected** button next to the relevant code host account.
139
+
3. Select **Refresh Permissions** from the dropdown.
The button will show a spinner while the sync is in progress and display a confirmation once it completes.
146
+
147
+
148
+
# Overriding enforcement per connection
149
+
150
+
Each [connection](/docs/connections/overview) supports an `enforcePermissions` flag that controls whether permissions are enforced for repositories in that connection. This lets you mix code hosts in a single deployment - for example, enforcing access control on a private GitHub connection while keeping an internal Gerrit instance open to all users.
151
+
152
+
By default, `enforcePermissions` inherits the value of `PERMISSION_SYNC_ENABLED`. You can override it per connection in the [config file](/docs/configuration/config-file):
153
+
154
+
```json
155
+
{
156
+
"connections": {
157
+
"my-github": {
158
+
"type": "github",
159
+
"enforcePermissions": true
160
+
},
161
+
"my-gerrit": {
162
+
"type": "gerrit",
163
+
"url": "https://gerrit.example.com",
164
+
"enforcePermissions": false
165
+
}
166
+
}
167
+
}
168
+
```
169
+
170
+
Setting `enforcePermissions: false` on a connection makes all repositories from that connection accessible to any user, regardless of the global `PERMISSION_SYNC_ENABLED` setting.
171
+
172
+
The table below shows when permissions are enforced based on the combination of `PERMISSION_SYNC_ENABLED` and `enforcePermissions`:
Permission syncing works by periodically syncing ACLs from the code host(s) to Sourcebot to build an internal mapping between Users and Repositories. This mapping is hydrated in two directions:
@@ -146,19 +194,5 @@ The sync intervals can be configured using the following settings in the [config
|`experiment_repoDrivenPermissionSyncIntervalMs`| number | 24 hours | 1 |
150
-
|`experiment_userDrivenPermissionSyncIntervalMs`| number | 24 hours | 1 |
151
-
152
-
## Manually refreshing permissions
153
-
154
-
If a user's permissions have changed and they need access updated immediately (without waiting for the next scheduled sync), they can trigger a manual refresh from the **Linked Accounts** page:
155
-
156
-
1. Navigate to **Settings → Linked Accounts**.
157
-
2. Click the **Connected** button next to the relevant code host account.
158
-
3. Select **Refresh Permissions** from the dropdown.
Copy file name to clipboardExpand all lines: docs/snippets/schemas/v3/azuredevops.schema.mdx
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -189,6 +189,10 @@
189
189
}
190
190
},
191
191
"additionalProperties": false
192
+
},
193
+
"enforcePermissions": {
194
+
"type": "boolean",
195
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
Copy file name to clipboardExpand all lines: docs/snippets/schemas/v3/bitbucket.schema.mdx
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -162,6 +162,10 @@
162
162
}
163
163
},
164
164
"additionalProperties": false
165
+
},
166
+
"enforcePermissions": {
167
+
"type": "boolean",
168
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
Copy file name to clipboardExpand all lines: docs/snippets/schemas/v3/connection.schema.mdx
+28Lines changed: 28 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -205,6 +205,10 @@
205
205
}
206
206
},
207
207
"additionalProperties": false
208
+
},
209
+
"enforcePermissions": {
210
+
"type": "boolean",
211
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
208
212
}
209
213
},
210
214
"required": [
@@ -407,6 +411,10 @@
407
411
}
408
412
},
409
413
"additionalProperties": false
414
+
},
415
+
"enforcePermissions": {
416
+
"type": "boolean",
417
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
410
418
}
411
419
},
412
420
"required": [
@@ -562,6 +570,10 @@
562
570
}
563
571
},
564
572
"additionalProperties": false
573
+
},
574
+
"enforcePermissions": {
575
+
"type": "boolean",
576
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
565
577
}
566
578
},
567
579
"required": [
@@ -669,6 +681,10 @@
669
681
}
670
682
},
671
683
"additionalProperties": false
684
+
},
685
+
"enforcePermissions": {
686
+
"type": "boolean",
687
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
672
688
}
673
689
},
674
690
"required": [
@@ -839,6 +855,10 @@
839
855
}
840
856
},
841
857
"additionalProperties": false
858
+
},
859
+
"enforcePermissions": {
860
+
"type": "boolean",
861
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
842
862
}
843
863
},
844
864
"required": [
@@ -1047,6 +1067,10 @@
1047
1067
}
1048
1068
},
1049
1069
"additionalProperties": false
1070
+
},
1071
+
"enforcePermissions": {
1072
+
"type": "boolean",
1073
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
1050
1074
}
1051
1075
},
1052
1076
"required": [
@@ -1116,6 +1140,10 @@
1116
1140
}
1117
1141
},
1118
1142
"additionalProperties": false
1143
+
},
1144
+
"enforcePermissions": {
1145
+
"type": "boolean",
1146
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
Copy file name to clipboardExpand all lines: docs/snippets/schemas/v3/genericGitHost.schema.mdx
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,6 +60,10 @@
60
60
}
61
61
},
62
62
"additionalProperties": false
63
+
},
64
+
"enforcePermissions": {
65
+
"type": "boolean",
66
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
Copy file name to clipboardExpand all lines: docs/snippets/schemas/v3/gerrit.schema.mdx
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -100,6 +100,10 @@
100
100
}
101
101
},
102
102
"additionalProperties": false
103
+
},
104
+
"enforcePermissions": {
105
+
"type": "boolean",
106
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
Copy file name to clipboardExpand all lines: docs/snippets/schemas/v3/gitea.schema.mdx
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -148,6 +148,10 @@
148
148
}
149
149
},
150
150
"additionalProperties": false
151
+
},
152
+
"enforcePermissions": {
153
+
"type": "boolean",
154
+
"description": "Controls whether repository permissions are enforced for this connection. When `PERMISSION_SYNC_ENABLED` is false, this setting has no effect. Defaults to the value of `PERMISSION_SYNC_ENABLED`. See https://docs.sourcebot.dev/docs/features/permission-syncing"
0 commit comments