Skip to content
Authreads Docs

Changelog

Every change that an integration can observe — new endpoints and scopes, changed responses, and corrected behaviour — with the date it landed and the environments that have it.

Check the availability column before you build. Changes reach dev first and a given environment only at its next deployment. An entry marked Development is not yet present on the production base URL. See Environments & base URLs for what each one currently serves.
Additive by default. New fields are added to existing responses rather than replacing them, so ignoring a field you do not use is always safe. Anything that could break an existing integration is called out explicitly in its entry.

2026-10-27 — Shared-browser trust and clearer email delivery

Development changes for the coordinated 6.2–6.6 batch release.

Added

ChangeWhat it means for youAvailability
Remember several people on one browserHosted and operator sign-in keep bounded, separate trust for each person. API v2 clients may send device_tokens while existing device_token clients remain supported. Each person still proves their own password and current sign-in requirements; forgetting a browser for yourself preserves other people’s trust.Development
See delivery evidence for a user or operatorPrivate Admin and Console views show the latest invitation, sign-in code and confirmation for the current address, within the configured retention window. Platform-sent mail retains its tenant attribution. A permanent bounce or complaint can block invitation resends with invite_delivery_blocked; committed provisioning reports delivery_blocked as a delivery warning.Development

Fixed

ChangeWhat it means for youAvailability
Choose usable recovery proof before sending an unnecessary setup emailWhen local setup needs recovery authority because the strongest factor is on another site, v2 preflight prefers an available recovery code. Follow next_method and alternatives; the existing setup proof and assurance requirements remain enforced.Development

2026-10-27 — Independent email delivery tracking

Email delivery status stays available when optional tenant sender settings are incomplete.

Fixed

ChangeWhat it means for youAvailability
Platform delivery tracking is independent of tenant sender readinessSES delivery events continue to be processed when optional tenant sender configuration is unavailable. Queue preflight and authentication-host DNS requirements remain enforced; no new environment keys are required.Development

2026-10-26 — Consistent sign-in proof, session and device-trust rules

Development changes for the coordinated 6.2–6.4 batch release.

Changed

ChangeWhat it means for youAvailability
Invalid reverify sessions have one terminal responseReverify now returns 401 session_invalid for unknown, expired or revoked sessions. Clear local confirmation state and require sign-in; 409 flow_superseded remains for stale flows.Development

Fixed

ChangeWhat it means for youAvailability
Setup respects the account-wide strongest factorA passkey on another RP also sets the setup proof floor. Handle stronger_proof_unavailable_here with recovery-code or original-site security guidance.Development
Hosted trust uses the same current server decision as API sign-inOffer trust only when the server permits it. Hosted and direct proofs report remember_device_unavailable when that choice is unavailable. Authenticator replacement sends a dedicated security notice.Development

2026-10-25 — Self-service factors and v2-only API sign-in

Backend-owned sign-in can manage the user's own strong factors with shared fresh-proof rules.

Added

ChangeWhat it means for youAvailability
App-bound factor management and one-time recovery codesSee self-service 2FA. First strong-factor binding returns recovery codes once in API, flow and hosted responses. Hosted TOTP confirm now returns HTTP 200 JSON.Development

Changed

ChangeWhat it means for youAvailability
Removed legacy email login, old session reverify and legacy invite mutationUse the v2 login flow and app-bound reverify. Removed endpoints return 410 endpoint_removed; preflight defaults to v2. The legacy protection switch is removed.Development

Fixed

ChangeWhat it means for youAvailability
Typed app mismatch and actionable trusted-device fieldsOther-app sessions return 403 session_app_mismatch. Verification steps expose effective remember-device availability and duration. Hosted passkey rename now requires fresh proof.Development

2026-10-22 — OAuth interoperability and legacy sign-in protection

Available in development; production rollout requires operator configuration and migration review.

Added

ChangeWhat it means for youAvailability
Public tenant IDs in signed installation payloadsNew enrolment receipts and installation revocation events add tenant_public_id beside the UUID tenant_id. Existing UUID validation stays unchanged; older payloads may omit the new field.Development

Changed

ChangeWhat it means for youAvailability
Policy protection and migration signals for legacy email-code loginNew tenants require the flow API for users with an enrolled authenticator or passkey. Existing tenants retain their setting until an operator enables protection. See the migration guide for the password-bound conflict and lifecycle headers.Development

Fixed

ChangeWhat it means for youAvailability
Standard Basic client authentication on the token endpointClient credentials now accept HTTP Basic as advertised by discovery. Client IDs and secrets use OAuth form encoding inside Basic; mixed credentials and inconsistent client IDs are rejected with a Basic challenge.Development

2026-10-21 — Generally available in production

Production now runs everything on this page. Every earlier entry is available on the production base URL, and passkeys, authenticator apps, recovery codes and sign-in strength are generally available.

Added

ChangeWhat it means for youAvailability
Passkeys, authenticator apps and recovery codes for end usersUsers can sign in with a WebAuthn passkey, an authenticator app (TOTP), an emailed one-time code or a single-use recovery code, on hosted login and through the API. Each organisation chooses which methods are allowed and can stage a requirement for a stronger method; a method the resolved policy disables is refused with a stable error code (see Errors).All environments
Requested sign-in strength and step-upTokens report how the user signed in in amr and acr. Request a minimum with acr_values on hosted login or min_acr on the API (urn:authreads:acr:mfa, urn:authreads:acr:phr), and a fresh proof with max_age; handle unmet_authentication_requirements when no method qualifies. Essential acr requests through the claims parameter remain unsupported and are rejected. See Requesting sign-in strength and Step-up re-verification.All environments

Changed

ChangeWhat it means for youAvailability
Earlier entries are now in productionEntries previously marked Development shipped with this deployment and are now marked All environments. Review relying-party claim allow-lists for the pop and mfa amr values introduced on 2026-10-09.All environments

2026-10-09 — Hosted passkey sign-in and verified authentication claims

Organisation-enabled passkeys can complete hosted sign-in on the exact login site where they were added.

Changed

ChangeWhat it means for youAvailability
User-verified passkeys include pop and mfaNewly issued tokens report pop and mfa for a cryptographically user-verified passkey. Password plus passkey also includes pwd. Existing tokens keep their claims. Review relying-party claim allow-lists before deployment. This does not assert hardware binding or change operator enforcement.All environments

2026-09-28 — Management rename requests reject unsupported fields

Role and package rename requests now report an invalid request when a caller supplies fields the operation cannot change.

Changed

ChangeWhat it means for youAvailability
Unknown fields in role and package PATCH bodies receive 422PATCH /api/v1/management/roles/{role_id} and PATCH /api/v1/management/packages/{package_id} accept only name. An unsupported key or any other unknown field now returns 422 instead of silently applying the rename. Body errors on these two routes are now application/problem+json with a code (invalid_request_body, malformed_json, unsupported_media_type, request_body_unreadable) instead of plain text.All environments

Fixed

ChangeWhat it means for youAvailability
Step-up retains a session's original authentication methodNewly minted token amr now includes the distinct methods verified when a session was created and at its latest step-up. auth_time continues to reflect the latest successful proof. No new authentication method is emitted by this change.All environments

2026-09-25 — Machine ownership and per-person admission

Tenant automation can assign a machine owner and enforce an audited active-machine limit per person.

Added

ChangeWhat it means for youAvailability
Machine ownership and tenant-managed person limitsMachine ownership can be assigned, transferred, cleared, or marked shared. The tenant default and per-person exceptions are managed with installations:manage. A verified binding claim that exceeds the limit now returns 409 person_installation_limit_reached with the limit, current count, and the person's active machine IDs; the binding is not consumed. Deleting a user who still owns active machines returns 409 user_owns_active_installations; release or transfer their machines before retrying.All environments

2026-09-16 — Verifiable enrolment and machine revocation delivery

Machine enrolment now produces proof a customer's backend can verify, and a configured customer endpoint can receive durable signed revocation events.

Added

ChangeWhat it means for youAvailability
Enrolment redemption returns a signed, key-bound receiptPOST /api/v1/enrolment/redeem now adds an enrolment_receipt JWT to its existing response. The receipt is valid for five minutes, is audience-bound to the enrolled app, and binds the installation, tenant, app, and SHA-256 fingerprint of the canonical enrolled public key. Verify it with the issuer's published JWKS before your backend accepts the agent's key. This is additive; no existing response field changed.All environments
Signed installation-revocation notificationsAn app may register one public HTTPS revocation destination. Retiring an installation then enqueues a signed secevent+jwt notification containing a unique jti, tenant, app, installation, and reason class. Delivery is retried and may be duplicated, so receivers must be idempotent. It remains best-effort: absence of an event is never proof that an installation is active. See the installation protocol for the receiver contract.All environments

Fixed

ChangeWhat it means for youAvailability
A stale out-of-range policy field no longer hides the entire policyA previously saved numeric policy value that is outside today's permitted range now resolves to the current platform default for that field only. The response reports the substitution in degraded_fields, and saving the policy repairs the stale override. Malformed policy data still fails visibly, and new writes remain range-validated.All environments

2026-09-15 — Complete machine lifecycle automation

Tenant backends can now issue bounded machine tickets and retire individual installations through the public Management API.

Added

ChangeWhat it means for youAvailability
Issue one-use machine enrolment ticketsPOST /api/v1/management/apps/{app_id}/machine-enrolment-tickets lets a tenant backend mint a one-hour, single-use ticket with the new enrolment:issuescope. The caller can provide only purpose and deployment campaign; lifetime and use count cannot be widened.All environments
Retire one machine installationPUT /api/v1/management/apps/{app_id}/installations/{installation_id}/revocation adds least-privilege machine retirement with installations:revoke. It is idempotent, releases capacity, requires an audit reason, and deliberately operates on one installation rather than an entire deployment campaign. Already-issued access tokens may remain valid for up to 15 minutes.All environments

2026-08-12 — Bounded fleet enrolment and Phase 4 write errors

Fleet enrolment now rejects database conflicts with stable codes, preserves retry accounting, and applies pre-database abuse controls plus operator-bounded tenant capacity.

Changed

ChangeWhat it means for youAvailability
Anonymous redemption and installation capacity are genuinely bounded/api/v1/enrolment/redeem now passes a two-bucket limiter before opening a database transaction. Tenant limit changes cannot exceed their operator-approved maximum; platform exceptions use a separate permission boundary and durable audit event.All environments

Fixed

ChangeWhat it means for youAvailability
Phase 4 constraint failures now have actionable codesDuplicate installation keys, concurrent external-principal claims, duplicate issuers, and invalid tenant-scoped app/workspace/identity references no longer collapse into an internal error. Values are additive and permanent; integrations should retain a default branch for future codes.All environments

2026-08-12 — Machine-readable login failures and consistent native logout

Direct and hosted login now share stable actionable codes, and native apps can use the same loopback redirect policy when signing out as when signing in.

Added

ChangeWhat it means for youAvailability
Local back-channel logout development guidanceUse a temporary public HTTPS tunnel to a local receiver. Local, private, non-HTTPS, and redirecting targets stay refused in every environment so production SSRF protection and development behavior cannot diverge.All environments

Changed

ChangeWhat it means for youAvailability
Credential and rate-limit responses now emit stable codesDirect problem responses now emit invalid_credentials for rejected login proofs and rate_limited for general limits. Hosted OAuth responses emit the same values in error_code; login_temporarily_locked remains unchanged. These fields are additive where no code was emitted before. Integrations with adefault: branch should add explicit cases if they want tailored user messages or retry behavior. Wrong passwords and unknown identities remain byte-identical.All environments

Fixed

ChangeWhat it means for youAvailability
Post-logout loopback redirects match authorization redirectsNative clients may register HTTP post-logout redirects on localhost, 127.0.0.1, or [::1], and may use a different runtime port. Scheme, host, path, and query still match; every non-loopback target remains exact HTTPS.All environments
Trusted-device alerts are branded and now name the device, time, and a way to actThe trusted-device notification your users receive previously arrived unbranded and told them to remove the device without saying where. It now carries the standard Authreads layout and states the device, platform, IP address and time, with a link to the hosted account-security page. The link is built from your configured hosted-login origin, so it points at the page your users already use.

Every Authreads email now also sends a plain-text alternative alongside the HTML part, which improves deliverability for one-time-code mail. A tenant administrator can still disable the trusted-device alert under Authentication → Security policy; doing so does not suppress the trusted_device.created audit record or the device inventory entry.
All environments
Set-password emails name the right sender, reason, and expiryOne template served two unrelated situations, so a user who requested a first password through forgot-password was told “You have been invited” and warned to be suspicious of a message they had just asked for. These are now separate emails. The self-service one states that the reader asked for it; the invitation one is subject-lined <your company name> invited you — set your password and names your company in the body, because your users were invited to your application and do not recognize Authreads.

Invitation and onboarding emails also stated the wrong lifetime: they promised one hour for links that are valid for seven days, so recipients abandoned working links and asked for re-sends they did not need. Every link email now states the lifetime its token is actually minted with. No token lifetime changed — only the wording, which was wrong.
All environments

2026-08-11 — Reliable OIDC session termination

Relying parties can now receive a signed, durable notification when an Authreads OIDC session is revoked or reaches its absolute expiry.

Added

ChangeWhat it means for youAvailability
OpenID Connect Back-Channel Logout 1.0Register an HTTPS backchannel_logout_uri on your OIDC client and implement the standard logout_token receiver. Authreads retries temporary delivery failures without delaying the user's logout, and the client settings show repeated failures. Verify the token signature, issuer, audience, lifetime and logout event; reject a token containing nonce; deduplicate on jti; then end the session identified by sid. See Sign in with Authreads.All environments

Changed

ChangeWhat it means for youAvailability
Hosted lockouts include a stable extension codeHosted OAuth lockouts still use the standards-compatible temporarily_unavailableerror, and now also include error_code: login_temporarily_locked. Branch on that extension instead of matching human-readable prose.All environments

Fixed

ChangeWhat it means for youAvailability
Idle-timeout scope is documented explicitlyAuthreads enforces idle timeout on hosted browser sessions and direct/BFF integrations that present x-session-activity. A hosted OIDC relying party must enforce human inactivity in its own session; read idle_timeout_minutes from the signed https://authreads.com/claims/session_policy ID-token claim. Back-channel logout carries Authreads revocation and absolute-expiry decisions, but does not turn a server-side token operation into proof of user activity.All environments

2026-08-11 — Live policy inheritance and honest login errors

A tenant's security policy now actually inherits platform-default changes, and a locked-out login is no longer indistinguishable from an expired OAuth grant.

Fixed

ChangeWhat it means for youAvailability
Tenant security policy inherits platform-default changes againA tenant's policy row previously stored a full copy of every platform default, not only the fields it deliberately chose, so a platform-default change never reached any tenant — password, MFA, lockout, and trusted-device enforcement were evaluated and then silently discarded. Policy rows are now sparse: only deliberate overrides are stored, and every other field resolves against the live platform default on each request. Deliberate tenant customizations are unaffected. See Authentication settings.All environments
Login failures return honest, distinguishable errorsHosted login failures previously collapsed almost everything into OAuth's generic invalid_grant / "grant invalid, expired, or already used". A temporary lockout is now its own explicit response on both planes, with Retry-After. If you pattern-matched on the old generic grant-error text to detect a lockout, that match will stop firing — branch on code (direct) or the documented OAuth error instead. See Errors & rate limits.All environments
New-trusted-device notification email now actually sendsThe notification introduced below never delivered in any environment where the database role is not a superuser — dev or production — because the throttle record backing it was written on the admin connection, which the row's own tenant-isolation policy silently rejects. It now writes on the correct tenant-scoped connection. If you depend on this email, re-verify delivery; nothing about the API contract changed.All environments

2026-08-11 — Account security for tenant backends

Self-service session and trusted-device management became reachable from a tenant's own backend, not only from our hosted login pages.

Added

ChangeWhat it means for youAvailability
Seven account-security endpoints on the tenant BFF surfaceUnder /api/v1/auth/users/{user_id}/apps/{app_id}/account-security/: list and revoke sessions, list and revoke trusted devices, a combined revoke-others-and-devices, and a policy read. Previously these existed only behind the hosted OIDC token shape, which a backend-for-frontend integration cannot mint. See Sessions & tokens.All environments
account-security:read and account-security:manage scopesBoth are opt-in and granted to no existing credential automatically. account-security:manage can end another person's access, so it is marked dangerous when granting. See API & credentials.All environments
Per-tenant control of the new trusted-device emailA tenant that would rather send its own branded notification can turn ours off. Delivery is enabled by default. Disabling delivery never suppresses the audit record — the security evidence is written in the same transaction that creates the device.All environments
Trusted devices on the hosted loginThe one-time-code step accepts remember_device, and the response returns the window your tenant actually resolved to — so your UI states the real number of days rather than mirroring a constant. Tenants choose any value up to a 90-day platform ceiling.All environments
Session idle timeoutAuthreads-hosted browser sessions now end after a period of real pointer or keyboard inactivity as well as at their absolute expiry. Direct/BFF clients enforce the same boundary with the signed activity contract — GET /api/v1/auth/me now requires the current x-session-activity token on every call and fails 401 without it; hosted OIDC relying parties enforce the resolved setting in their own browser session. Tenant-configurable from 15 minutes to 365 days; the platform default is 30 minutes. See Sessions & tokens.All environments

Changed

ChangeWhat it means for youAvailability
Session exchange returns session policy and activity statePOST /api/v1/auth/session/exchange now also returns session_policy (including the resolved idle timeout) and session_activity_token. The exchange response itself is additive — existing fields are unchanged — but a Direct/BFF client that discards session_activity_token will find its GET /me calls start failing once this reaches its environment, because that endpoint now requires it.All environments
RP-initiated logout no longer requires id_token_hintGET /oauth/logout now accepts client_id as an alternative, matching OpenID Connect RP-Initiated Logout 1.0, which marks id_token_hint RECOMMENDED rather than REQUIRED. At least one of the two is still required, because the client identity is what validates your post_logout_redirect_uri. Relying parties that discard the ID token after login can now end the session properly instead of receiving a 400.All environments

Fixed

ChangeWhat it means for youAvailability
Logout could leave the single-sign-on cookie aliveThe session cookie was cleared with attributes that did not always match how it was written, so in some deployments the browser kept it and the next sign-in skipped authentication entirely. The deletion now mirrors the write in every configuration.All environments

What is not listed here

Internal refactoring, test coverage, administrative console work and documentation edits are deliberately left out, however large. This page exists so you can tell at a glance whether something you integrate against has moved — a list of everything would defeat that.

If a change you depend on is missing, it is an omission rather than a policy. Tell us and we will add it.