Skip to content

Upgrading to 3.5.2

3.5.2 is a patch release that changes what an OAuth2 token may do. Sites that only use Studio sessions and API tokens need nothing but the version bump. Sites where people sign in through the CLI, the MCP server or an application of their own need the steps below.

  • OAuth2 tokens hold their scopes. A token’s rights are its scopes intersected with its user’s permissions. Before, approving “read content” gave an admin’s token full admin power.
  • Applications never manage the account. An OAuth2 token is refused on account and security routes and on administration: users, API tokens, webhooks, settings changes. GET /auth/me gives it a minimal profile.
  • Every approval is a grant that people see and revoke in Studio under Connected applications. Tokens issued before 3.5.2 belong to no grant, so they are refused.
  • The person approving chooses the scopes on the consent screen, and a narrowing sticks.
  • Device sign-in works across processes. Device and authorization codes are kept in the data adapter, so it works on Workers and behind several replicas.
  • Status codes are consistent. A permission denial is 403 and an authentication failure 401 everywhere. Some routes answered 400, 401 or 500 before.

The details are in Users and authentication.

Your own applications. If an application of yours signs people in through Trokky and relies on its tokens acting as the full user, for example calling auth: 'admin' custom routes, mark its client trusted, or those calls will be refused:

oauth2: {
enabled: true,
issuer: 'https://cms.example.com',
clients: [
{ id: 'staff-portal', name: 'Staff portal', redirectUris: ['https://staff.example.com/auth/callback'], trusted: true },
],
}

A trusted client acts as the user but is still refused administration. If it created users or API tokens through the API with an OAuth2 token, that now needs a Studio session or an API token.

A narrowed CLI client. If your config has an entry with id: 'trokky-cli' to restrict its scopes, allow content:publish and media:delete, which trokky restore and trokky clean now need, and make sure it lists the device grant:

{
id: 'trokky-cli',
name: 'Trokky CLI',
redirectUris: [],
allowedScopes: ['profile', 'content:read', 'content:write', 'content:publish', 'content:delete', 'media:read', 'media:write', 'media:delete', 'offline_access'],
grantTypes: ['urn:ietf:params:oauth:grant-type:device_code', 'refresh_token'],
}

Clients of the API. A client that treated a 400 or a 500 from an account route as “signed out” now gets 401 for that, and 403 for a denial. Refresh on 401 only.

Everyone signed in through an application signs in again, once.

  • CLI users update to CLI 0.3.0 (brew upgrade trokky), then run trokky login <url>. Older CLIs do not ask for the publish and media delete scopes.
  • MCP users tell the agent to add the site again, or run npx @trokky/mcp@3 login <url> --replace.
  • Your own applications send their users through sign-in again.

Studio sessions and API tokens keep working. Nobody is signed out of Studio.

Then look at Users & Access > Connected applications: each new sign-in appears there, with the machine it came from.

  • GET /auth/me no longer returns the TOTP secret or backup-code hashes, to anyone. mfa.backupCodesRemaining gives the count.
  • /audit-logs/documents/:id and /audit-logs/actors/:id return only entries from collections the caller can read.
  • User responses no longer include the server’s _oauth2* records in preferences, and the users API cannot write them.
  • Changes made through an application are recorded with metadata.via, and Studio’s history names the application.
  • Linking a Google account needs a link flow started by the signed-in user.
  • The Postgres adapter stores sign-in flow state in its own table, created on start. Until now every flow on Postgres silently fell back to process memory.