Skip to content

Authentication migration for 0.1.0

English | 한국어 | 日本語

ActivityPlug 0.1.0 accepts public API session identifiers only through the HTTP Authorization header. Browser applications use the /v1/browser/** boundary and its opaque cookie instead.

Required changes

Complete each item before upgrading a client or proxy:

  • Move the ActivityPlug session identifier to Authorization: Bearer <session-id> for HTTP, GraphQL, and WebSocket requests.
  • Remove sessionId from URL query parameters, GraphQL arguments, GraphQL input objects, JSON bodies, and multipart fields.
  • Keep the header available during WebSocket upgrade instead of placing the identifier in the WebSocket URL.
  • For browser code, stop exposing ActivityPlug session identifiers to JavaScript and move requests to /v1/browser/**.
  • Obtain the browser cookie and CSRF token from GET /v1/browser/session.
  • Send the configured CSRF header on browser mutations and authentication requests.
  • Confirm that access logs, analytics, error reports, and saved URLs no longer contain session identifiers.

There is no compatibility alias for query or body credentials. Requests that contain those inputs are rejected rather than ignored.

Public HTTP requests

Before 0.1.0:

http
GET /api/v1/timelines/home?sessionId=$ACTIVITYPLUG_SESSION HTTP/1.1
Host: proxy.example

In 0.1.0:

http
GET /api/v1/timelines/home HTTP/1.1
Host: proxy.example
Authorization: Bearer $ACTIVITYPLUG_SESSION

The top-level sessionId field was removed from every HTTP JSON and multipart request body. A body containing that field is rejected.

GraphQL and WebSocket requests

GraphQL HTTP requests use the same Bearer header and omit sessionId from arguments and input objects. WebSocket upgrades also use the Bearer header; credentials in WebSocket URLs are rejected.

The sessionId argument was removed from authenticated queries, mutations, notificationStream, and timelineStream. It was also removed from GraphQL input objects used for posts, media, polls, profiles, search, filters, lists, mutes, and reactions. Regenerate typed clients against the 0.1.0 schema rather than maintaining local copies of the removed fields.

Browser applications

Browser applications must use /v1/browser/**. They must not read or store an ActivityPlug session identifier.

Start with GET /v1/browser/session. ActivityPlug returns a CSRF token in the response and sets the Secure, HttpOnly __Host-activityplug cookie. Start and complete authentication through /v1/browser/auth/**, then use /v1/browser/api/**. Browser routes reject both Authorization credentials and sessionId query parameters.

Server and storage checklist

  • Enable public token import only when it is required, and protect it with a tokenImport.guard.
  • Choose an AuthSessionStore that matches the deployment topology.
  • Configure browser-session, OAuth-state, challenge, stream-ticket, and rate limit stores when enabling the browser boundary.
  • Initialize PostgreSQL lifecycle tables before calling createActivityPlugServer().
  • Use shared PostgreSQL or Redis stores when several processes serve the same sessions.
  • Await server.ready, and call server.close() before closing backing database clients.

Verification

Verify at least one authenticated HTTP or GraphQL request, one rejected query-credential request, and the WebSocket upgrade path used by the application. Browser deployments should also verify session issuance, CSRF rejection, authentication completion, logout, and replay rejection for an already consumed OAuth callback.

Released under the Apache-2.0 OR MIT license.