Why
Tokens only store readOnly and a list of teams, so permissions can't differ per team or per tool group.
How
AccessToken.toolPermissions (JSON): the token default, applied to every reachable team without an override.
- New table
AccessTokenToolPermissions (AccessTokenId, TeamId, nullable ApplicationId reserved for application scoping, permissions JSON): per-team overrides, only stored where they differ from the default.
- Shape:
{ platform: { read, write, destructive }, flow_building: { read, write, destructive } }. Destructive implies Write, Write implies Read, normalised on save.
- Lookup order: team override, then token default, then deny.
- The consent endpoint accepts
toolPermissions: { default, teams } instead of readOnly. readOnly is derived: true when nothing allows Write, so REST access for the token behaves as today.
- Tokens created before this change (
toolPermissions null) resolve to Read + Write if not read-only, Read only if read-only, Destructive off in both cases.
- Permissions are loaded onto the session in
verifySession and returned in the token summary.
Done when
Consent stores default and overrides, legacy tokens resolve as above, unit tests cover validation, normalisation and loading.
Why
Tokens only store
readOnlyand a list of teams, so permissions can't differ per team or per tool group.How
AccessToken.toolPermissions(JSON): the token default, applied to every reachable team without an override.AccessTokenToolPermissions(AccessTokenId,TeamId, nullableApplicationIdreserved for application scoping,permissionsJSON): per-team overrides, only stored where they differ from the default.{ platform: { read, write, destructive }, flow_building: { read, write, destructive } }. Destructive implies Write, Write implies Read, normalised on save.toolPermissions: { default, teams }instead ofreadOnly.readOnlyis derived: true when nothing allows Write, so REST access for the token behaves as today.toolPermissionsnull) resolve to Read + Write if not read-only, Read only if read-only, Destructive off in both cases.verifySessionand returned in the token summary.Done when
Consent stores default and overrides, legacy tokens resolve as above, unit tests cover validation, normalisation and loading.