Skip to content

[Bug]: T3 Connect devices keep pre-split permissions after the host updates #17310

Open

Description

@kroqdotdev

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Run a T3 Code host on a version from before the permission split (for example 0.0.45). Connect another device to it through T3 Connect, so the host mints a cloud-connect session for that device.
  2. Within the hour that session is valid, update the host to a granular-permissions nightly (observed with 0.0.46-nightly.20261008.2833, a6ec88f7a716) and let the device reconnect.
  3. On the device, open Add project → Local folder and type a path such as ~/.

Expected behavior

The device can browse host folders after the host updates. A fresh T3 Connect mint on the updated host grants AuthStandardClientScopes, which includes filesystem:read. The user never chose a narrower grant for this connection, so there is nothing to keep.

Actual behavior

The folder browser shows "This connection cannot browse host folders." and other newly separated features stay unavailable until the device's DPoP access token expires (up to an hour).

The host's auth_sessions row for the device (subject = 'cloud-connect', method = 'dpop-access-token') still has the grant the previous server minted:

["orchestration:read","orchestration:operate","terminal:operate","review:write","relay:read"]

The updated server reports that list as permissions, so sessionGrantsScope(..., "filesystem:read") is false on the client. RpcScopeAuthorization also denies filesystem.browse on the server. The client caches the token and keeps reusing it, and nothing tells it the grant model changed. PermissionUpdateNotice treats the session as a legacy grant and tells the user to pair again with a new link. T3 Connect users cannot act on that advice.

Timeline on the affected host (UTC):

19:39:38  cloud-connect session minted for the macOS client by the 0.0.45 server (pre-split scopes, expires 20:39:38)
19:44:24  host restarts on 0.0.46-nightly.20261008.2833
19:44:25  next cloud-connect pairing link is minted with the full standard grant (includes filesystem:read)
~20:15    macOS client, still on the 19:39 session, gets "This connection cannot browse host folders."

Keeping stored grants after the split is intended for paired clients, because the user chose those grants (#10298). T3 Connect sessions are short-lived and minted by the server, so the same rule only delays the current grant here.

Impact

Minor bug or occasional failure

Version or commit

Host: 0.0.46-nightly.20261008.2833 (a6ec88f). Session minted by the host's previous 0.0.45 server.

Environment

Host: Linux x64 desktop app (AppImage). Client: macOS desktop app 0.0.46-nightly.20261008.2833, connected through T3 Connect. The host had iOS (2.0.0) and Windows (0.0.45) T3 Connect sessions in the same state.

Workaround

Wait for the T3 Connect token to expire (at most an hour), or revoke that device's session from the host's Connections settings so it mints a new one.

Activity

  1. kroqdotdev commented on Oct 8, 2026

    @kroqdotdev
    Author

    Question for maintainers before #17308 can be considered.

    #10298 set the policy that existing credentials keep exactly their recorded scopes across the split, and removed 050_ExpandLegacyAuthScopes (comment). For paired clients that is clearly intended. Should T3 Connect (cloud-connect) sessions fall under the same rule?

    How they differ from paired sessions:

    • The server chooses their grant at mint time (AuthStandardClientScopes in CloudLink). The user never picks it.
    • They last at most an hour.
    • A fresh mint on an updated host already returns the split permissions.

    Right now, a device that connected shortly before the host updated loses folder browsing and other split permissions until its token renews. Meanwhile PermissionUpdateNotice tells the user to pair again with a link, which T3 Connect users can't do.

    Options I see:

    1. Exempt them. Revoke live pre-split cloud-connect sessions once on upgrade so clients mint replacements (fix(server): T3 Connect devices get new permissions after an update #17308, a one-time migration). Paired sessions are untouched and no stored grant is widened. Older clients that request pre-split scopes get the same narrowed grant back.
    2. Keep the policy, fix only the recovery advice. For T3 Connect connections, the notice would say permissions update when the connection renews, instead of asking for a new pairing.
    3. Leave it as is.

    This mostly matters for stable users upgrading from 0.0.45 to the first release with the split. I can rework #17308 for whichever direction you prefer, or close it.

  2. juliusmarminge commented on Oct 22, 2026

    @juliusmarminge
    Member

    Reproduced on main 49e97d48f9 using an isolated Linux dev server and persisted cloud-connect DPoP session fixtures. The pre-split grant authenticates, but GET /api/auth/session omits filesystem:read and filesystem.browse for ~/ fails with that missing permission. A fresh standard-grant session browses the same path successfully.

    This exercises the real host HTTP and WebSocket paths. The original cloud-account/desktop upgrade sequence has not been verified. The existing #17341 addresses fresh pairing exchanges and leaves stored credentials unchanged.

  3. juliusmarminge commented on Oct 24, 2026

    @juliusmarminge
    Member

    Verified the historical five-scope grant from v0.0.45 against the real Linux server on ff1f6fd884: authentication succeeds and folder browsing is denied. On 8401f6460b, the one-time migration revokes that session; a fresh standard grant browses successfully. Paired and narrowed grants remain unchanged, including after restart.

    Fix: #24311. Reproducible server evidence. The original cloud-account/desktop upgrade and automatic client renewal were not verified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions