Native session logout
ENG-2741 transfers
DELETE /accounts/sign_out and both first-party sign-out controls to API2.
The response remains either 200 { logout_url } or 204. Login, organization
switching and identity lifecycle are still Rails-owned. ENG-2516’s original
logout fix already shipped in Rails PR #10374; this package preserves it.
Security and compatibility
- Require an exact, non-null
OrigininAPI2_CORS_ORIGIN. Missing origins, trusted-looking Referer headers and same-site hints do not authorize logout. No CSRF token endpoint is needed for this origin-checked DELETE contract. - Revoke the supplied production and staging cookies in one database statement, including Rack’s private digest and legacy raw-ID rows. No account/tenant hydration or session-expiry check may prevent logout. A stored digest is not accepted as a bearer cookie. Other sessions remain untouched.
- Commit revocation before WorkOS I/O; concurrent native activity refresh cannot
insert or resurrect the row. Clear API2-host and
.rulebase.cobrowser cookies and invalidate the local cache. Every other process still checks the authoritative session row before its own cache hit. - The installed Ruby WorkOS SDK uses AES-256-GCM, while the Node sealed-session helper uses an incompatible envelope. Decrypt the authenticated Ruby envelope, then verify the access token with client-specific WorkOS JWKS before extracting its logout SID. Expired access tokens are allowed only for logout; this helper never authenticates an application request. Token-only legacy sessions use one bounded WorkOS refresh request, with no automatic retries or credential write.
- Preserve the existing local-only logout fallback on provider errors. Emit
native_logout_workos_failed,native_logout_with_workosandnative_logout_local; never log session data, cookies, upstream error bodies, tokens or the logout URL. A durable database deletion failure returns 500 and leaves the browser cookie available for retry.
Validation
The Ruby SDK generated a synthetic, expired RS256 token and AES-GCM fixture; no private signing key or real credential is committed. Tests exercise the actual checked-in Rails sessions DDL, raw/private cookie compatibility, revocation isolation, stale refresh fencing, origin rejection, no-tenant and already-signed-out routing, WorkOS signature verification/refresh failures, and both UI controls. API2 OpenAPI and UI types are regenerated.
Deployment gate and observation
Do not merge the caller cutover until configuration has been verified.
API2’s regional Infisical environments must contain the same WorkOS client,
secret key and 32-byte cookie password used by their existing Rails deployment:
WORKOS_CLIENT_ID, WORKOS_SECRET_KEY, WORKOS_COOKIE_PASSWORD. Verify
RULEBASE_APP_BASE_URL points to the appropriate regional app, and its origin is
in API2_CORS_ORIGIN. Optional schema entries keep unrelated API2 boot paths
compatible; a supplied cookie password must be exactly 32 UTF-8 bytes or startup
fails. Missing configuration is not acceptable rollout evidence.
Confirm the deployed Rails cookie domain is .rulebase.co in each region,
matching config/environments/production.rb’s domain: :all (also present in
the July 22 repository snapshot). API2 cannot receive or clear a host-only
cookie scoped to a different host, including the Rails API or app hostname.
The host-only deletion in this route covers API2’s own host and localhost;
it is not a compatibility mechanism for other-host cookies. If a deployed
override produces those cookies, hold the caller cutover until a same-host
revocation path is supplied and verified. Do not infer cookie scope from
request cookie headers, which omit it.
Read-only checks at September 3 09:57 UTC found missing API2 settings. The user subsequently copied the existing values within each region. HMAC-only comparison at 10:40 confirmed all three match regional Rails exactly, with 32-byte cookie passwords and matching app URLs/origins/shared-cookie settings. #11073 merged 10:46; its containing release succeeded EU 11:05 / US 11:06. Fresh runtime reads confirm the native module and configuration. This supersedes the earlier gate; no configuration writes were performed by the automation.
After automatic API2/UI deployment, require actual sign-out events in both regions, upstream logout redirects, immediate rejection of the old cookie and 24 hours without a new logout failure. Production secrets and tokens must not be printed or captured. A successful deployment or absence of Sentry errors is not proof of actual use. Observe login again after upstream logout.
Rollback the two UI callers to the retained Rails endpoint first. Rails retains its route/controller throughout this package. Deleted sessions cannot be restored; users sign in again. Do not replay sessions or mutate production data.