Release Notes

v2.39.0

Release date: April 08, 2026

New features

Plain chat in studio

When logged into studio, a new chat icon appears in the bottom right corner of the screen. Use it to chat directly with support, your studio email is used for authentication and remembering conversations.

Transition-aware status policy filters

Status policies now support a filter field that can reference the record's current and incoming state — not just its static data fields. This lets you write policies that activate only during specific status transitions.

The filter context exposes the full record DTOs for both sides of the transition:

  • old — the record DTO before the transition (old.meta.status, old.data.schema, old.data.*, …)
  • new — the record DTO after the incoming proof is appended. Same shape as old.
  • ctx.req — the HTTP request context

ctx.req is only present when the transition is triggered by a direct API call. Transitions that occur internally — such as during settlement, reconciliation, or bridge processing — carry no request context. A filter that references ctx.req will not match in those cases, causing the policy or value to be excluded. Only use ctx.req if you explicitly want to restrict a transition to direct API calls.

Fields from old.data are also available at the root level without any prefix for backward compatibility (e.g. schema is equivalent to old.data.schema).

The filter can be set at the policy root (excludes the entire policy when it does not match) or inside an individual value (excludes just that value). A typical use case is allowing a custom status only from a specific starting state — for example, permitting an intent to be committed only when the intent is already prepared. If the filter does not match, the policy or value is excluded from evaluation; if no remaining policy grants the target status, the transition is rejected.

See Filtering by status transition for full details and examples.

OAuth2 Token impersonation for mutation requests

OAuth2 bearer tokens issued via the /oauth/token client credentials endpoint also trigger impersonation. In this case the injected proof carries origin: oauth2-token, with signer set to the token's sub and issuer set to the token's iss.

External IdP tokens (such as Auth0) are also supported. The sub claim is used directly as the impersonated signer handle.

Note: the token kid must match an existing key pair signer factor that contains the public key to validate the JWT.

SDK support for OAuth2 authentication

OAuth2 authentication is supported via the SDK through sdk.oauth.exchangeToken(clientId, clientSecret). See Authenticate with OAuth for more details.

OAuth2 tokens JWT claims available directly in bearer access rules

Bearer access rules can now match against OAuth2 tokens arbitrary JWT payload claims directly. Any claim present in the token is accessible as a top-level key in the bearer expression, supporting the full set of MongoDB-style query operators.

// Grant read access when the token carries the required scope
{
  "action": "read",
  "bearer": {
    "scopes": {
      "$in": "manage-all-signers"
    }
  }
}

Improvements

Fixes

  • Ledger: Supporting intent proofs with any kind of status. Supported statuses check is deferred to status policies.

On this page