Repository navigation
feat: session grants give read access; share with the tenant via a grant (AGE-2577) - #1123
Merged
Merged
Conversation
🦋 Changeset detectedLatest commit: 6677662 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
hary73
marked this pull request as ready for review
October 21, 2026 21:11
hary73
requested review from
chiragjn,
debajyoti-truefoundry,
heerambavi1998 and
thesujai
as code owners
October 21, 2026 21:11
hary73
force-pushed
the
haryahuja/age-2577-session-sharing-with-collaborators
branch
from
October 27, 2026 14:14
25826cd to
6c0cf64
Compare
thesujai
approved these changes
Oct 28, 2026
Base automatically changed from
haryahuja/age-2577-session-sharing-with-collaborators
to
main
October 28, 2026 04:43
hary73
force-pushed
the
haryahuja/age-2577-session-access-read-check
branch
from
October 28, 2026 05:16
3bdc8bf to
49a6ed5
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 49a6ed5. Configure here.
…ant (AGE-2577)
- Add `tenant` subject type; its subject_id must be the caller's tenant.
- canReadSession checks the creator, then a user or tenant grant, then agent managers.
- Session.shared is derived from the tenant grant.
- Remove PATCH { shared } and every read/write of session.shared; the column stays for a follow-up drop.
- Backfill shared sessions as tenant grants (20261027_000002_access_control_tenant_backfill).
- Add session_sharing.users capability so the UI can hide the user picker without a user source.
Co-authored-by: Cursor <cursoragent@cursor.com>
hary73
force-pushed
the
haryahuja/age-2577-session-access-read-check
branch
from
October 28, 2026 05:29
49a6ed5 to
57ddb33
Compare
…t (AGE-2577) Co-authored-by: Cursor <cursoragent@cursor.com>
…ssion-access-read-check
…E-2577) Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
ramantehlan
approved these changes
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
thesujai
reviewed
Oct 28, 2026
… (AGE-2577) - IAccessControlStore exposes createAccessGrants / listAccessGrants / deleteAccessGrants; the user-or-tenant read rule and the tenant-shared lookup move to the API layer. - Rename capability session_sharing.users to session_sharing.enabled. - Mark PATCH shared deprecated through the OpenAPI flag with a short description. - Keep the read-endpoint and PATCH route descriptions as on main. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
thesujai
approved these changes
Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Second part of AGE-2577, on top of #1122 (merged). This completes the backend: grants are now the only way a session is shared.
tenantgrant inaccess_control. Existing shared sessions are backfilled.PATCH /sessions/{id} { shared }is deprecated: it now grants or revokes the tenant grant, so released UIs keep working. It is removed in the next release.Session.sharedis still returned, derived from the tenant grant.Behaviour by mode
GET /users) and/or the whole tenant. Grants store servicefoundry's user id, which is the caller'ssubject.id, so grantees match.GET /usersis empty. The new capability tells the UI to show only the tenant toggle.API changes
SessionGrantSubjectTypeisuser | tenant. Atenantsubject'ssubject_idmust be the caller's tenant id, otherwise 422. It skips the user lookup.GET /api/v1/capabilitiesaddssession_sharing: { enabled: boolean }: whether sessions can be shared with specific users (true only when a user source exists, i.e. TrueFoundry mode). Sharing with the tenant is always available.UpdateSessionRequest.sharedis markeddeprecated.trueadds thetenantgrant,falseremoves it.Session.sharedis now read-only: true when the session has atenantgrant.Changes
IAccessControlStoreexposes genericcreateAccessGrants/listAccessGrants/deleteAccessGrants(Postgres and SQLite).listAccessGrantsfilters by sessions and, optionally, subjects. The read rule and the tenant-shared lookup live in the API layer, not the store.canReadSessionchecks the creator, then a grant, then agent managers (the only step that may call servicefoundry). Ausergrant only matches callers whose subject type isuser, so service accounts and agents only match tenant grants.session.sharedcolumn is no longer read or written: removed fromSessionRecord,UpdateSessionInput, the session stores and table types (core and backend). The column stays in the DB (DEFAULT false), unused.20261028_000003_access_control_tenant_backfill(both backends):upinserts atenantgrant for everyshared = truesession, attributed to its creator, idempotent.downcopies tenant grants back onto the column and removes them.Deploy note
During a rolling deploy, old pods still read and write
session.shared. A share toggled through an old pod after the migration won't be in the table. The next-release follow-up removes thePATCH { shared }alias and drops the column, re-running the backfill first, which closes that gap.UI
Not changed here. The share dialog in
trueforge-ui(and the version pinned by the platform frontend) keeps working through the deprecated alias. It moves toGET/POST /sessions/{id}/grantsand the new capability separately.How was this tested?
listAccessGrantsis checked across several sessions (with ordering), with a subjects filter (type and id matched together), and with empty inputs.main's server, created sessions A–D, and shared A and D throughPATCH { shared }(B shared then unshared, C never shared). I then started this branch's server on the same database:tenantgrants for A and D only, attributed to their creator.GET /grantslisted the tenant.POST /grantsand the capability all worked. A user grant and another tenant's id returned 422.truewhile the API reportedfalse, confirming the column is no longer read.sharedis derived on get and list; the legacy column alone grants nothing; the deprecatedPATCH { shared }grants and revokes the tenant and stays creator-only.usersis false with the empty store, true with the TrueFoundry store.pnpm typecheck(backend and core), ESLint and Prettier on changed files, backend unit suite (748), core suite (534), both store suites.Checklist
pnpm build,pnpm test,pnpm typecheck,pnpm lint:ci, andpnpm format:checkpass locallypackages/trueforge-sdk,python/trueforge_sdk,.github/fern/openapi/openapi.json,docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge.env.exampleupdated if configuration or behavior changedNote
High Risk
Changes authorization for session reads and migrates sharing state; incorrect grant checks or backfill could expose sessions or break existing shared links during rollout.
Overview
Session sharing moves off the stored
session.sharedflag ontoaccess_controlgrants, which now enforce read access (session, turns, and events). User grants share with specific collaborators; tenant grants replace “share with everyone,” and wireSession.sharedis computed from whether that tenant grant exists.POST /sessions/{id}/grantsacceptsuserandtenantsubjects (tenantsubject_idmust match the caller’s tenant). The deprecatedPATCH { shared }still toggles the tenant grant for older clients.GET /capabilitiesaddssession_sharing.enabled(per-user sharing only when a user directory exists).The session store no longer reads or writes
shared; a migration backfills tenant grants for rows that were previously shared. Read paths usecanReadSession+ grant lookup; mutations and grant management stay creator-only.Reviewed by Cursor Bugbot for commit 6677662. Bugbot is set up for automated code reviews on this repo. Configure here.