(Changelog)

What has changed

Changes to Nautilus that customers can see, newest first. Internal work is left out.

Is something broken right now? See the status page. For how things work, read the documentation. Entries marked Breaking or Contract change need something from you. Atom feed.

1.10.43

(Added)

  • Organizations and roles in the dashboard: create your users' organizations, define roles with permissions and add members, without writing code. See Organizations and roles.
  • Automatic deletion has its own place in the dashboard menu, and the dashboard home shows three first steps: a key, sign-in in your app, a deletion rule.
  • A support page in the dashboard with our address and the reply time of your plan.

(Changed)

  • The site, the docs and the dashboard now speak of one product, Nautilus: sign-in and users, with webhooks, scheduled jobs and Telegram sign-in as its parts.
  • Deleting your account is a mail to support from your account address; we delete it within 30 days.
  • The Legal tab, the Sandbox/Live switch and the key limit of 10 are gone from the dashboard: none of them did anything.

1.10.41

(Added)

(Changed)

  • The privacy policy is rewritten: it names each service that processes data, what for and where, and says how long each kind of data is kept.
  • Our site serves its fonts itself, so visiting it no longer sends your IP address to Google.
  • Analytics no longer loads on the pages your end users reach from Gate's emails (verification, recovery and account settings).

(Fixed)

  • A Clockwork job that sets its own Content-Type header is sent with that value only; before, application/json was added as a second value.
  • The status page shows "Checking…" while it loads instead of "Status unavailable".

1.10.40

(Added)

  • Two-factor sign-in for your Verne dashboard account: codes from an authenticator app, with backup codes, in your profile settings.
  • Clockwork jobs run in any IANA timezone, with daylight saving handled; see timezones and daylight saving.
  • Return URLs for social login can be edited in the dashboard, on the social-login tab.
  • Guides: Gate in a Next.js app, in a Laravel app, migrating from Auth0 with your users' passwords, and self-hosted Ory Kratos or Gate.
  • Comparison pages: Auth0, Clerk, Ory Network and Logto.
  • This changelog, with an Atom feed.

(Changed)

  • Roles and organizations are available on every plan, Free included.

(Fixed)

  • Switching MFA off for your project no longer leaves users who had enrolled unable to remove their second factor.

1.10.39

(Added)

(Changed)

  • The automatic deletion docs now say exactly when an inactive account is deleted (N months after the last sign-in, with the warning sent earlier) and list what remains after a deletion.

1.10.38

(Added)

  • Signed tokens for end users carry an orgs claim with the user's organizations, roles and permissions; see Signed tokens (JWT).
  • Token introspection and GET /v1/gate/auth/session return the user's current organizations, and the new GET /v1/gate/identities/{id}/organizations returns the full list, paged.
  • POST /v1/gate/authorize now answers "may this user do X in this organization" for resource: "organization:<uuid>", with a reason code; see Organizations and roles.
  • The 1.4 line of the Node.js, PHP, Python and Rust SDKs covers all of this.

(Changed)

  • The API now speaks one error shape, {"error": {"code", "message", "request_id"}}, with code always a string. The items below are the places where that changed what you receive.
  • Breakingreason in POST /v1/gate/authorize is a code for every resource (owned_by_tenant, subject_inactive, not_owned_by_tenant, not_a_known_identity); the old sentence moved to message.
  • BreakingDELETE /v1/gate/identities/{id}/sessions returns 204 when the user has no sessions, not 404.
  • Breakinga malformed request to POST /v1/gate/tokens, /tokens/introspect and /authorize is 400 invalid_payload with a request_id, not invalid_request.
  • BreakingPOST /v1/gate/tokens refuses ttl_seconds outside 1 to 86400 with 400 invalid_payload; before, 0 or a larger number was accepted and silently adjusted.
  • BreakingClockwork errors on /v1/clockwork/* are the envelope ({"error": {"code": "not_found", …}}) instead of {"error": "Job not found"}; HTTP statuses are unchanged.
  • BreakingPassepartout errors are the envelope too, and a malformed request is 400 invalid_payload instead of invalid_request; see the Passepartout API reference.
  • Breakingerrors on the Gate session, metadata, step-up and settings routes use string codes (not_found, unauthorized, forbidden, mfa_required, invalid_payload, upstream_unavailable) instead of the identity service's numeric ones.
  • Contract changemetadata_public.verne_tenant_id no longer appears in identity objects returned by /v1/gate/identities.
  • Contract changeGET /v1/gate/auth/session without X-Session-Token is 400 invalid_payload with a message that names the header.
  • A trait that does not exist is now named in the error, for example traits.custom_data is not a trait of an end user (the traits are email and locale).
  • GET /v1/clockwork/usage returns both plan and tier (equal values) and is now documented.

(Fixed)

  • The Gate and Clockwork pages in the docs now describe the real error format, show the Authorization header on POST /v1/gate/tokens (a key in the body was never read), and give the correct status for a Passepartout account with no bot (400 bot_not_configured).

1.10.35 – 1.10.37

(Changed)

  • Every dashboard page is translated into English, French, German, Spanish, Serbian and Italian, with numbers, dates and money formatted for the page language. Server messages and automatic-deletion emails stay in English.
  • Public pages download roughly half as much language data as before; the dashboard's text loads only after you open the dashboard.

(Fixed)

  • The dashboard opens in the language saved in your profile, and changing it in Profile Settings applies immediately.
  • A password change made through /auth/* is now recorded once in the audit log and fires one identity.password_changed event, whichever way the change was started.
  • The Gate rules page could occasionally load with no rules; it no longer does.

1.10.34

(Added)

  • An audit log of what happens in your account: API keys, projects and members, Gate and Telegram settings, automatic-deletion rules, role changes, and your end users' sign-ins and password changes. Entries cannot be edited or deleted early.
  • Read it in the dashboard under Audit log, or with GET /v1/gate/audit-log and a key that has the gate scope (filters, cursor paging, newest first).
  • Retention follows the plan: Free 7 days, Pro 30, Advanced 90, Contract as agreed. The account owner can shorten it, never lengthen it.
  • Not recorded, and documented as such: failed sign-ins and Telegram sign-ins.

1.10.33

(Added)

  • Signed session tokens (JWT, ES256) for end users: GET /auth/sessions/whoami?tokenize_as=gate_jwt returns a token valid for 15 minutes that you or a platform such as Supabase can verify offline against your tenant's published keys. See Signed tokens (JWT).
  • Each tenant has its own issuer, https://api.vernesoft.com/auth/{tenant_id}, with OpenID discovery and a JWKS under /.well-known/.
  • The token includes role: "authenticated", which PostgREST-style consumers use as the database role.

1.10.32

(Added)

  • An implementation services page, in English and French: Ory Kratos setup on your servers or on Nautilus, migration from Keycloak or a home-grown sign-in, and support. Prices start from €500 one-off and €150 a month.

(Changed)

  • The language switcher in the header lists only the languages the current page exists in.

1.10.29

(Changed)

  • The cookie banner, Cookie Policy and Privacy Policy now describe both analytics systems we use, our own and PostHog (EU Cloud), what accepting cookies changes, and what is counted without consent.
  • Sign-ups and plan upgrades are counted for product analytics with a pseudonymous ID; no name, email address or IP address is sent.

(Fixed)

  • The opt-out button on the Cookie Policy page now takes effect immediately instead of at the next page load.

1.10.28

(Fixed)

  • A key without the right scope gets the same 403 on all four APIs: {"error": {"code": "forbidden", "message": "This API key is not authorized for <API>.", "request_id": …}}. Clockwork and Passepartout used to answer with a bare string.
  • Clockwork's 400 for an invalid path parameter uses the error envelope as well, and the SDKs now surface the code and message of these refusals.

1.10.27

(Changed)

  • The documentation is organised by task: product overview, sign-in and users, webhook delivery, cron jobs, Telegram sign-in, and a new API keys and plans section. API names such as /v1/gate/* stay as the contract.
  • /docs/nautilus/plans-and-limits moved to /docs/api-keys-and-plans/plans-and-limits and redirects with a 301.

(Fixed)

  • The docs described API keys wrongly. A key carries a set of scopes chosen when you create it, a new key looks like vrn_<hex>, older vrn_<engine>_… keys still work, there is no test or live key mode, and a key without the scope gets 403. See API keys.

1.10.26

(Changed)

  • End users are separated by tenant. The same email address can be an end user of several tenants, and each is a different person with their own password, sessions and verification and recovery emails.
  • Contract change409 on creating an end user now means only that you already have a user with that address; the same address at another tenant gets 201.
  • Contract changean address longer than 208 bytes, with a quoted local part, or in the gate.invalid zone gets 400 invalid_payload, and so does a request that sets an internal trait.
  • A given Google or GitHub account can be an end user of one tenant only; a second tenant's login with it gets 403. Addresses are stored in lower case, and a Unicode domain must be sent as punycode. See the Gate API reference.

1.10.24

(Changed)

  • Verification, recovery and sign-in emails are queued and retried with back-off for up to 72 hours when mail delivery is briefly unavailable. The messages themselves are unchanged.

1.10.23

(Added)

  • Automatic deletion of inactive accounts: four rules per project (delete unconfirmed accounts, remind people to confirm their email, remove roles at their deadline, delete inactive accounts). Everything is off until you switch it on, and people get a warning email before any deletion.
  • A Rules tab under Users & sign-in in the dashboard, with a preview of how many people a rule would affect and a confirmation before you switch on a deletion.
  • The same rules through the API: GET /v1/gate/lifecycle/rules, PUT and DELETE /v1/gate/lifecycle/rules/{kind}, POST …/{kind}/preview and GET /v1/gate/lifecycle/actions. A rule your plan lacks returns 403 plan_required.
  • Organization members can have an expires_at; when it passes, the membership is removed.
  • identity.deleted webhooks carry payload.reason (unverified_account_expired or inactive_account_expired) when a rule deleted the user.
  • Free includes the rule for unconfirmed accounts; Pro and above include all four. Rule emails are currently sent in English.

1.10.22

(Changed)

  • Plans are priced by monthly active users instead of API requests: Free (€0, 1,000 active users), Pro (€99 a month, 10,000) and Advanced (€199 a month, 50,000), plus Contract by agreement. Relay messages, Clockwork jobs, projects and history limits scale with the plan; see /pricing.
  • An active user is an end user who signs in at least once in a calendar month (UTC), by any method. People created through the API who never sign in are not counted.
  • Signing in is never blocked for billing reasons: Passepartout login/start, login/status and tokens/introspect no longer return 402 for a past-due or suspended account.
  • The shared request quota and request packs are gone.

(Added)

  • Over the active-user limit, sign-in keeps working. You get emails at 80 % and 100 %, and after one full month to move up, only new registrations are refused, with 402 ACTIVE_USER_LIMIT_REACHED.
  • Relay messages over the monthly limit return 429 RELAY_MESSAGE_LIMIT_REACHED with Retry-After set to the start of next month. Clockwork job limits and a second project on Free return 402 UPGRADE_REQUIRED.
  • A new Billing page in the dashboard shows your plan, active users per project and month, the other limits and a banner for each over-limit state. The pricing page has a calculator. Every refusal is described in Plans, limits and refusals.

1.10.19 – 1.10.21

(Changed)

  • GET /v1/gate/auth/session returns 502 upstream_unavailable when the identity service cannot be reached, instead of 401.
  • Contract changeDELETE /v1/gate/sessions/{id} answers 404 No such session. for any session that is not one of your end users', and for a malformed id. Before, another account's session got 403 and a malformed id got 500.
  • The Gate MFA and settings flow pages describe these answers; 403 mfa_required is answered only to the user's own tenant.

(Fixed)

  • Revoking a single session works: DELETE /v1/gate/sessions/{id} returns 204 and the session then fails whoami, and so does the per-session Revoke button in the dashboard.

(Security)

  • Security: tightened how end-user sessions are tied to the customer whose key is used, including for users with a second factor.

1.10.17 – 1.10.18

(Added)

  • Gate webhook events are recorded before delivery and retried with back-off, so a short outage of the delivery service no longer loses them: they wait and go out when it is back, for up to 72 hours. See Gate webhooks.
  • The Webhooks tab (Users & sign-in) shows a notice when events have waited more than 5 minutes, and lists the events that could not be handed over in the last 30 days, with a plain-language reason.

1.10.14 – 1.10.16

(Fixed)

  • Deactivating an end user works: PATCH /v1/gate/identities/{id}/state with {"state": "inactive"} used to return 400 and now returns 200 with the identity.
  • A deactivated user cannot sign in by password, one-time code, social provider or recovery, their sessions are refused, and token introspection and authorize answer active: false and allowed: false. All of it reverses on reactivation.
  • The same holds for Passepartout: a deactivated person gets no token from a Telegram sign-in (403 account_disabled on login/status), and their earlier tokens introspect as inactive. Deactivate with a Gate key; see the Passepartout docs.

1.10.10 – 1.10.13

(Changed)

  • Contract changeon /v1, a failed call to an engine behind the API is 502 upstream_unavailable, not 500 internal_error. Clockwork uses the same error envelope when its backend is unavailable.
  • A request with a NUL character (\u0000 or %00) in its path, query or body is refused with 400 invalid_payload; Relay message payloads are exempt.

(Fixed)

  • request_url in Gate flow responses now carries your public API host.
  • Telegram sign-in works for people whose profile name contains a NUL character.

(Security)

  • Security: hardened input validation and error handling at the gateway, and narrowed /auth/* to the self-service and session paths the product uses; any other path answers 404.

1.10.7 – 1.10.9

(Added)

  • Sign-in and sign-up by one-time code, sent by email, for end users of a tenant that has passwordless_enabled on. The Gate API reference describes both flows.
  • A "Forgot password?" link on the dashboard sign-in page, in six languages.

(Changed)

  • Polling GET /v1/passepartout/login/status is limited to 3,000 polls a minute per account, and returns 429 with Retry-After above that. A login that has started can always finish.

(Fixed)

  • Sign-up verification and password-recovery emails are now delivered.
  • POST /v1/gate/identities answers 400 invalid_payload instead of 502 for a social identifier longer than 255 characters or an external_id longer than 64.

1.10.4

(Added)

  • GET /v1/clockwork/usage returns your active jobs and your plan's limits; the dashboard shows "N of M" active recurring and waiting delayed jobs.

(Changed)

  • Each plan limits how many Clockwork jobs can be active at once, recurring and delayed separately. Over the limit, creating or resuming a job returns 402 UPGRADE_REQUIRED. See Clockwork plan limits.
  • Moving to a smaller plan removes and stops nothing; only new jobs and resumes are refused until you are back under the limit.

1.10.2 – 1.10.3

(Fixed)

  • "Continue with Google" on the dashboard sign-in creates an account for a new person.
  • Someone who already has a password account and signs in with Google or GitHub is told "An account for {email} already exists. Sign in the way you did before…", and the provider is then added to the account.
  • The sign-in, registration, recovery, verification and settings pages keep the flow in the address (?flow=<id>) and start a fresh one when it has expired, instead of failing with a retry button that retried the same expired flow.

1.10.1

(Changed)

  • A login flow now expires after one hour.

(Security)

  • Security: tightened how a sign-in is tied to the customer whose API key started it.

1.10.0

(Changed)

  • The public site presents Nautilus as one product. /gate, /relay, /clockwork and /passepartout are pages about a task, not four separate products.
  • Performance and compliance claims we could not back with measurements were removed, and the latency figure on the home page is read live from the status data.

(Fixed)

  • The code examples on /gate now work as written.

(Security)

  • Security: hardened the Gate API.

1.9.0

(Added)

  • Organizations, roles and members in the Gate API (gate scope): group your customers, define roles with resource:action permissions, and move people between organizations.
  • An end user belongs to a project as well as to your account, so one person in two of your projects stays one identity and counts once.
  • Social login ends in your backend: the browser carries a one-time code and your backend trades it for a session token with its API key, so the token never appears in a URL. Return addresses are set per project and matched exactly.

(Changed)

  • Flow objects from /v1/gate/auth/{login,recovery,verification} carry "type": "api". X-Return-To is no longer documented because nothing ever read it.

(Fixed)

  • Sign-in, recovery and verification flows for end users can now be completed through the API: you submit to the flow's own ui.action and receive session_token.
  • Password recovery returns a session, resending a verification email actually sends it, and the identity.login webhook is delivered.
  • An end user who registers with a password no longer gets an account of their own, and is recorded in the project of the key that started the flow.

(Security)

  • Security: hardened ownership checks in the Gate API.

1.7.3

(Fixed)

  • POST /v1/relay/messages accepts the body the docs describe (event_type, payload), and idempotency_key now works: sending the same key again within 12 hours returns the original message.
  • Listing messages paginates with next_cursor and has_more and filters by event_type, as documented. Anything outside the three published Relay routes answers 404.
  • Every error on /v1 is the documented envelope, {"error": {"code", "message", "request_id"}}, and Gate errors have a string code. Quote the request_id in a support message and we can find the request.
  • The status page no longer marks the dashboard as degraded for an hour after each of our deploys.

1.7.1 – 1.7.2

(Added)

(Fixed)

  • The docs no longer describe POST /v1/gate/auth/login/submit, which never existed: login completes against the flow's own ui.action. They also say plainly that listing identities by API key is not available.
  • Code blocks on the public pages were double-spaced and now render normally.

1.7.0

(Changed)

  • Product analytics and session recording no longer run inside the dashboard.

1.6.1 – 1.6.5

(Fixed)

  • Status page: one failed probe no longer marks a component degraded (two in an hour do), and a component that stops answering still shows as down on the first probe.
  • The latency chart on the status page now reflects the service rather than the page's own probe, and the copy no longer claims sub-millisecond latency.

1.6.0

(Added)

  • A public status page: current state of each component, 24 hour, 7 day and 30 day uptime, 90 days of daily history, and a list of past incidents.

1.5.0

(Changed)

  • Contract changea cron schedule that restricts both day-of-month and day-of-week is refused with 400, because crontabs and our scheduler read that combination differently. Put * in one of the two.
  • Contract changea job URL must point at a publicly reachable address; private, loopback and link-local addresses are refused when the job is saved and again when it runs. See Target URLs.
  • A tenant blocked for billing gets 402, not a 429 that tells clients to retry.

(Fixed)

  • A cron job runs at the time its schedule says, not when it was created or last edited.
  • A Telegram polling restart no longer replays or duplicates updates.

(Security)

  • Security: hardened Clockwork job targets, request forwarding between services, webhook authentication and cross-origin defaults.

1.4.0 – 1.4.2

(Added)

  • Billing in the dashboard: your plan and its terms, usage, payment history, and checkout, plan change and cancellation, also from the pricing page when you are signed in.

(Fixed)

  • The dashboard header showed "Free Plan" to every account, and the usage figure was wrong for every account; both now follow your real plan.
  • Docs links written without the /docs prefix redirect to the right page instead of returning a 404.

1.3.3

(Added)

  • The Clockwork API: create and manage cron and delayed jobs with a Clockwork API key at /v1/clockwork/*. See the Clockwork API reference.

1.3.1

(Added)

  • Passepartout documentation: an overview, quick start and API reference, and the passepartout key in the SDK installation page.

1.3.0

(Added)

  • Telegram sign-in (Passepartout): passwordless login for your end users through your own Telegram bot, with login/start, login/status and tokens/introspect under /v1/passepartout/. Bot tokens are stored encrypted. See /passepartout.
  • A Telegram sign-in page in the dashboard.

1.2.1 – 1.2.3

(Fixed)

  • Social sign-in with GitHub and Google was sending placeholder credentials to the provider and failed; it works now.

(Changed)

  • SDK package names: Node.js is @verne-software/sdk on npm and Rust is nautilus-rs on crates.io (imported as nautilus_rs). The PHP (vernesoft/sdk) and Python (vernesoft) names are unchanged.
  • Contact addresses on the site and in the legal pages are consolidated to support@vernesoft.com.

1.1.0

(Added)

  • SDK methods for social sign-in in the Node.js, PHP, Python and Rust SDKs: read and update a tenant's social providers, list the enabled providers for your login buttons, and start a login flow. The social auth docs show each language.

1.0.0 – 1.0.5

(Added)

  • Gate: end-user registration, sign-in, social sign-in through GitHub, Google and other providers, password recovery, email verification and two-factor sign-in, through the API.
  • Session management, activating and deactivating end users, and custom metadata on end users.
  • Gate webhooks for identity events, signed with HMAC-SHA256.
  • SDKs for Node.js, PHP, Python and Rust, code examples across the API references, and llms.txt for AI assistants.

(Fixed)

  • Changing a password, and finishing account recovery, no longer ends on a 404 page.
  • The Update Identity docs now say the endpoint takes JSON Patch (RFC 6902), not a merge patch.