From 2acf7cacf929118f2b9b5962b623ade9eb9ea32f Mon Sep 17 00:00:00 2001 From: msukkari Date: Thu, 21 May 2026 18:08:31 -0700 Subject: [PATCH 1/7] docs: surface known security quirks as info notes Five small Note cards documenting accepted security trade-offs that surfaced during the BB Cloud profile acceptance run, so customers can plan for them without surprise. None are bugs to fix; they are upstream constraints or design choices worth flagging in-line where users would otherwise have to derive them empirically. - Session lifetime: JWT verifier clock-skew tolerance means sessions may be accepted briefly past AUTH_SESSION_MAX_AGE_SECONDS. - Bitbucket Cloud: Atlassian's 14-day account-deletion grace period can leave a closed user in BB permission lists until purge or until the next permission sync sees an auth error. - enforcePermissionsForPublicRepos: clarify that this is a host-level membership check, not a per-repo permission check. - Visibility changes are refreshed by connection sync, not permission sync, so public/private flips converge on resyncConnectionIntervalMs. - Permission sync fails closed only on auth-related errors; transient rate-limit and 5xx responses leave the previous state in effect. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/docs/configuration/auth/overview.mdx | 4 ++++ docs/docs/features/permission-syncing.mdx | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/docs/configuration/auth/overview.mdx b/docs/docs/configuration/auth/overview.mdx index 117eed4f6..8ad30d7f1 100644 --- a/docs/docs/configuration/auth/overview.mdx +++ b/docs/docs/configuration/auth/overview.mdx @@ -22,6 +22,10 @@ Sourcebot's built-in authentication system gates your deployment, and allows adm +# Session lifetime + +Session cookies are guaranteed to be valid for at least `AUTH_SESSION_MAX_AGE_SECONDS`, but may be accepted for a brief additional window before expiring. This is because the JWT verifier applies a small clock-skew tolerance when checking expiry. + # Troubleshooting - If you experience issues logging in, logging out, or accessing an organization you should have access to, try clearing your cookies & performing a full page refresh (`Cmd/Ctrl + Shift + R` on most browsers). diff --git a/docs/docs/features/permission-syncing.mdx b/docs/docs/features/permission-syncing.mdx index 2f261edb3..153a0da24 100644 --- a/docs/docs/features/permission-syncing.mdx +++ b/docs/docs/features/permission-syncing.mdx @@ -102,6 +102,8 @@ These users **will** still gain access via [user-driven syncing](/docs/features/ 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. +When a Bitbucket Cloud account is closed by its owner, Atlassian applies an account-deletion grace period (currently 14 days for consumer accounts) before the account is fully purged. During this window, Bitbucket's permission APIs may continue to return the closed user in repository permission lists. Sourcebot revokes that user's access once the next permission sync receives an authentication error from Bitbucket, or once Atlassian fully purges the account. + **Notes:** - A Bitbucket Cloud [external identity provider](/docs/configuration/idp#bitbucket-cloud) must be configured to (1) correlate a Sourcebot user with a Bitbucket Cloud user, and (2) to list repositories that the user has access to for [User driven syncing](/docs/features/permission-syncing#how-it-works). - OAuth tokens require the `account` and `repository` scopes. The `repository` scope is required to list private repositories during [User driven syncing](/docs/features/permission-syncing#how-it-works). @@ -176,6 +178,10 @@ These flags are useful when you want different enforcement behavior across conne } ``` +When `enforcePermissionsForPublicRepos` is `true`, public repositories are visible to any user who has linked an account on the same code host. The check is at the host level rather than per-repo, so users do not need explicit upstream read access to each public repository individually. + +A repository's public-vs-private state is refreshed by [connection sync](/docs/connections/overview#connection-syncing), not by permission sync. After a visibility change at the code host, Sourcebot continues to apply its previous classification until the next connection sync runs (configurable via `resyncConnectionIntervalMs`, default 24 hours). Lower this value if your deployment expects faster propagation of visibility changes. + The table below shows when permissions are enforced based on the combination of `PERMISSION_SYNC_ENABLED`, `enforcePermissions`, and `enforcePermissionsForPublicRepos`: | `PERMISSION_SYNC_ENABLED` | `enforcePermissions` | `enforcePermissionsForPublicRepos` | Private repos enforced? | Public repos enforced? | @@ -202,4 +208,6 @@ The sync intervals can be configured using the following settings in the [config | Setting | Type | Default | Minimum | |-------------------------------------------------|---------|------------|---------| | `repoDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | -| `userDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | \ No newline at end of file +| `userDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | + +Permission syncing fails closed only on authentication-related errors (`401`, `403`, `410`, or OAuth token refresh failures), in which case Sourcebot clears the affected account's permission rows immediately. Transient errors such as rate limits or `5xx` responses leave the previous permission state in effect until the next successful sync, so that brief upstream incidents do not strand users without access. \ No newline at end of file From 4d7e2da3582aa5df05ded745be645577560a542c Mon Sep 17 00:00:00 2001 From: msukkari Date: Fri, 22 May 2026 15:42:11 -0700 Subject: [PATCH 2/7] docs: expand Session lifetime section with default + clock-skew note --- docs/docs/configuration/auth/overview.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/docs/configuration/auth/overview.mdx b/docs/docs/configuration/auth/overview.mdx index 8ad30d7f1..3b138e35b 100644 --- a/docs/docs/configuration/auth/overview.mdx +++ b/docs/docs/configuration/auth/overview.mdx @@ -24,7 +24,11 @@ Sourcebot's built-in authentication system gates your deployment, and allows adm # Session lifetime -Session cookies are guaranteed to be valid for at least `AUTH_SESSION_MAX_AGE_SECONDS`, but may be accepted for a brief additional window before expiring. This is because the JWT verifier applies a small clock-skew tolerance when checking expiry. +By default, session cookies remain valid for 30 days from the time they are issued, after which the user is signed out and must authenticate again. + +You can change this by setting the [`AUTH_SESSION_MAX_AGE_SECONDS`](/docs/configuration/environment-variables) environment variable to the desired lifetime in seconds. + +A session is guaranteed to remain valid for at least its configured lifetime. The JWT verifier applies a small clock-skew tolerance when checking expiry, so a session may continue to be accepted for a brief additional window past that point before it is rejected. # Troubleshooting From 2b392dea0bbae9042b853dbd918229fa833bee83 Mon Sep 17 00:00:00 2001 From: msukkari Date: Fri, 22 May 2026 15:47:47 -0700 Subject: [PATCH 3/7] docs: refine permission-syncing notes and add transient-error FAQ --- docs/docs/features/permission-syncing.mdx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/docs/features/permission-syncing.mdx b/docs/docs/features/permission-syncing.mdx index 153a0da24..7a1def482 100644 --- a/docs/docs/features/permission-syncing.mdx +++ b/docs/docs/features/permission-syncing.mdx @@ -18,6 +18,8 @@ that they have access to on the code host. Practically, this means: - Ask Sourcebot (and the underlying LLM) will only have access to repositories that the user has access to. - File browsing is scoped to the repositories that the user has access to. +A repository's public-vs-private state is refreshed by [connection sync](/docs/connections/overview#connection-syncing), not by permission sync. After a visibility change at the code host, Sourcebot continues to apply its previous classification until the next connection sync runs (configurable via `resyncConnectionIntervalMs`, default 24 hours). Lower this value if your deployment expects faster propagation of visibility changes. + Permission syncing can be enabled by setting the `PERMISSION_SYNC_ENABLED` environment variable to `true`. ```bash @@ -178,10 +180,6 @@ These flags are useful when you want different enforcement behavior across conne } ``` -When `enforcePermissionsForPublicRepos` is `true`, public repositories are visible to any user who has linked an account on the same code host. The check is at the host level rather than per-repo, so users do not need explicit upstream read access to each public repository individually. - -A repository's public-vs-private state is refreshed by [connection sync](/docs/connections/overview#connection-syncing), not by permission sync. After a visibility change at the code host, Sourcebot continues to apply its previous classification until the next connection sync runs (configurable via `resyncConnectionIntervalMs`, default 24 hours). Lower this value if your deployment expects faster propagation of visibility changes. - The table below shows when permissions are enforced based on the combination of `PERMISSION_SYNC_ENABLED`, `enforcePermissions`, and `enforcePermissionsForPublicRepos`: | `PERMISSION_SYNC_ENABLED` | `enforcePermissions` | `enforcePermissionsForPublicRepos` | Private repos enforced? | Public repos enforced? | @@ -210,4 +208,13 @@ The sync intervals can be configured using the following settings in the [config | `repoDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | | `userDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | -Permission syncing fails closed only on authentication-related errors (`401`, `403`, `410`, or OAuth token refresh failures), in which case Sourcebot clears the affected account's permission rows immediately. Transient errors such as rate limits or `5xx` responses leave the previous permission state in effect until the next successful sync, so that brief upstream incidents do not strand users without access. \ No newline at end of file +How Sourcebot handles errors during a permission sync depends on the type of error. Authentication errors (such as `401`, `403`, `410`, or a token refresh failure) cause Sourcebot to immediately revoke the affected user's access to repositories on that code host. Other errors (such as rate limits or `5xx` responses) are treated as transient: Sourcebot keeps the user's existing access until the next successful sync, so that a brief code host outage does not lock users out. + +# FAQ + +### What happens if there are transient errors with the code host? + +It depends on the type of error. + +- **Authentication errors** (such as `401`, `403`, `410`, or a token refresh failure): Sourcebot immediately revokes the affected user's access to repositories on that code host. +- **Rate limits or `5xx` responses**: Sourcebot keeps the user's existing access until the next successful sync runs. \ No newline at end of file From feebca1bacf827758dca1dab936e407756c7450f Mon Sep 17 00:00:00 2001 From: msukkari Date: Fri, 22 May 2026 15:52:00 -0700 Subject: [PATCH 4/7] docs: fold visibility-change note into FAQ --- docs/docs/features/permission-syncing.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/docs/features/permission-syncing.mdx b/docs/docs/features/permission-syncing.mdx index 7a1def482..29bfa9413 100644 --- a/docs/docs/features/permission-syncing.mdx +++ b/docs/docs/features/permission-syncing.mdx @@ -18,8 +18,6 @@ that they have access to on the code host. Practically, this means: - Ask Sourcebot (and the underlying LLM) will only have access to repositories that the user has access to. - File browsing is scoped to the repositories that the user has access to. -A repository's public-vs-private state is refreshed by [connection sync](/docs/connections/overview#connection-syncing), not by permission sync. After a visibility change at the code host, Sourcebot continues to apply its previous classification until the next connection sync runs (configurable via `resyncConnectionIntervalMs`, default 24 hours). Lower this value if your deployment expects faster propagation of visibility changes. - Permission syncing can be enabled by setting the `PERMISSION_SYNC_ENABLED` environment variable to `true`. ```bash @@ -214,7 +212,11 @@ The sync intervals can be configured using the following settings in the [config ### What happens if there are transient errors with the code host? -It depends on the type of error. +It depends on the type of error: - **Authentication errors** (such as `401`, `403`, `410`, or a token refresh failure): Sourcebot immediately revokes the affected user's access to repositories on that code host. -- **Rate limits or `5xx` responses**: Sourcebot keeps the user's existing access until the next successful sync runs. \ No newline at end of file +- **Rate limits or `5xx` responses**: Sourcebot keeps the user's existing access. + +### When is a visibility change of a repo (switching from public to private) reflected within Sourcebot? + +The visibility state of a repository is updated when the [connection](/docs/connections/overview#connection-syncing) belonging to that repository is synced, not when the repository's permissions are synced. Until the next connection sync runs, Sourcebot continues to apply the repository's previous public-or-private classification. The connection sync interval is configurable via the `resyncConnectionIntervalMs` setting in the [config file](/docs/configuration/config-file) and defaults to 24 hours. Lower this value if your deployment expects faster propagation of visibility changes. From 4824323f951c69b4bf2e409c8930045af55712a5 Mon Sep 17 00:00:00 2001 From: msukkari Date: Fri, 22 May 2026 15:53:04 -0700 Subject: [PATCH 5/7] cleanup --- docs/docs/features/permission-syncing.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/docs/features/permission-syncing.mdx b/docs/docs/features/permission-syncing.mdx index 29bfa9413..72cf90dea 100644 --- a/docs/docs/features/permission-syncing.mdx +++ b/docs/docs/features/permission-syncing.mdx @@ -206,8 +206,6 @@ The sync intervals can be configured using the following settings in the [config | `repoDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | | `userDrivenPermissionSyncIntervalMs` | number | 24 hours | 1 | -How Sourcebot handles errors during a permission sync depends on the type of error. Authentication errors (such as `401`, `403`, `410`, or a token refresh failure) cause Sourcebot to immediately revoke the affected user's access to repositories on that code host. Other errors (such as rate limits or `5xx` responses) are treated as transient: Sourcebot keeps the user's existing access until the next successful sync, so that a brief code host outage does not lock users out. - # FAQ ### What happens if there are transient errors with the code host? @@ -219,4 +217,4 @@ It depends on the type of error: ### When is a visibility change of a repo (switching from public to private) reflected within Sourcebot? -The visibility state of a repository is updated when the [connection](/docs/connections/overview#connection-syncing) belonging to that repository is synced, not when the repository's permissions are synced. Until the next connection sync runs, Sourcebot continues to apply the repository's previous public-or-private classification. The connection sync interval is configurable via the `resyncConnectionIntervalMs` setting in the [config file](/docs/configuration/config-file) and defaults to 24 hours. Lower this value if your deployment expects faster propagation of visibility changes. +The visibility state of a repository is updated when the [connection](/docs/connections/overview#connection-syncing) belonging to that repository is synced, not when the repository's permissions are synced. Until the next connection sync runs, Sourcebot continues to apply the repository's previous public/private classification. The connection sync interval is configurable via the `resyncConnectionIntervalMs` setting in the [config file](/docs/configuration/config-file) and defaults to 24 hours. Lower this value if your deployment expects faster propagation of visibility changes. From e178bb724dc7109d7edaf618d6f55f26f57207b1 Mon Sep 17 00:00:00 2001 From: msukkari Date: Fri, 22 May 2026 15:54:25 -0700 Subject: [PATCH 6/7] grammer --- docs/docs/features/permission-syncing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/features/permission-syncing.mdx b/docs/docs/features/permission-syncing.mdx index 72cf90dea..1491274a8 100644 --- a/docs/docs/features/permission-syncing.mdx +++ b/docs/docs/features/permission-syncing.mdx @@ -217,4 +217,4 @@ It depends on the type of error: ### When is a visibility change of a repo (switching from public to private) reflected within Sourcebot? -The visibility state of a repository is updated when the [connection](/docs/connections/overview#connection-syncing) belonging to that repository is synced, not when the repository's permissions are synced. Until the next connection sync runs, Sourcebot continues to apply the repository's previous public/private classification. The connection sync interval is configurable via the `resyncConnectionIntervalMs` setting in the [config file](/docs/configuration/config-file) and defaults to 24 hours. Lower this value if your deployment expects faster propagation of visibility changes. +The visibility state of a repository is updated when the [connection](/docs/connections/overview#connection-syncing) belonging to that repository is synced, not when the repository's permissions are synced. Until the next connection sync runs, Sourcebot continues to apply the repository's previous public/private classification. The connection sync interval is configurable via the `resyncConnectionIntervalMs` setting in the [config file](/docs/configuration/config-file) and defaults to 24 hours. Lower this value if you require faster propagation of visibility changes. From 13d84dd4be9b4d4c1a6edf0c3a895036659d1a6e Mon Sep 17 00:00:00 2001 From: msukkari Date: Fri, 22 May 2026 15:55:22 -0700 Subject: [PATCH 7/7] docs: add CHANGELOG entry for docs PR --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 199b2f1d7..7c75db3a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- Documented session lifetime, repository visibility refresh behavior, and how permission sync handles transient code-host errors. [#1218](https://github.com/sourcebot-dev/sourcebot/pull/1218) + ## [4.17.3] - 2026-05-22 ### Fixed