Agent doc: Auth JS SDK
Package
- Name:
@spectra-platform/auth-sdk - Version:
0.1.10, published and install-verified on 2026-09-05. - Registry: GitHub Packages
@spectra-platform/auth-sdk@0.1.10 was manually published to GitHub Packages at 2026-09-05T11:14:21Z.
Role 70 verified registry latest, clean-cache installation, public imports/types and identical downloaded tarball bytes.
Consuming environments need GitHub Packages registry configuration and read access because the package is private.
There is no Actions run for this manual publication; the existing automatic publish permission issue is separate.
Purpose
Auth JS SDK handles app-user Google/Apple login, callback relay, session access token retrieval, service token retrieval, refresh, and logout.
API tree
Auth JS SDK
├─ setup
│ ├─ new SpectraAuthClient(config)
│ ├─ createSpectraAuth(config)
│ ├─ createLocalStorageSessionStore()
│ └─ createMemorySessionStore()
├─ login
│ ├─ signInWithGoogle(options?)
│ ├─ preflightSignIn(options?)
│ ├─ signInWithApple(options?)
│ ├─ relaySpectraAuthCallback()
│ └─ readSpectraAuthCallback()
└─ session
├─ getSession()
├─ getAccessToken({ service?, forceRefresh? })
├─ refresh()
└─ logout()
└─ error
├─ SpectraAuthError
├─ isSpectraAuthError(error)
├─ retryAfterSeconds
└─ requestId
Public setup inputs
projectIdpublicClientIdenvironment:testorliveredirectUri- optional
baseUrl - optional
sessionStore
Provider secret, Apple private key, and Keycloak client secret are not browser/mobile setup inputs. Secret Key exposure requires an explicit consuming-project architecture decision. Project Secret Keys are environment-bound, shown once, and have no expiration date.
publicClientId is a current Auth SDK compatibility field, not a primary user-managed product key.
redirectUri is the consuming app callback URL. It is not the Google/Apple provider redirect URL generated by Spectra.
For local browser QA, localhost and 127.0.0.1 are different origins. Register the full app callback URL.
Deployed Auth 63cf46f automatically uses eligible active Test callback origins for Auth SDK CORS.
Preserve existing static/loopback permissions. Same-origin is required for the new insecure HTTP fallback;
it does not remove existing HTTPS cross-origin callback support.
Agent integration order
1. Install @spectra-platform/auth-sdk@0.1.10.
2. Create one SpectraAuthClient for the current app runtime.
3. Configure only public values: projectId, current package compatibility publicClientId if required, environment, redirectUri, optional baseUrl, optional sessionStore.
4. Implement the callback route and call relaySpectraAuthCallback() there.
5. Start with signInWithGoogle(options?) unless the task explicitly includes Apple credentials.
6. After callback relay, verify getSession() returns the app-user session.
7. Verify getAccessToken() returns a user access token.
8. For consuming-backend login verification, send only await auth.getAccessToken() with no service option to the app backend.
9. Pass the same Auth object to Notification, Chat, and Storage SDK clients.
10. Verify logout() clears local session state.
Backend login verification token
The official consuming-backend verification path is:
const token = await auth.getAccessToken();
The app backend then calls:
GET https://auth.spectra.kr/platform/v1/auth/sessions/current
Authorization: Bearer <token>
Do not pass getAccessToken({ service: "chat" }), getAccessToken({ service: "storage" }), or any other service token
to this endpoint. Auth rejects service tokens with 403 AUTH_SESSION_SCOPE_FORBIDDEN.
The backend must compare project_id, public_client_id, and environment from the response with its own expected
configuration before issuing an app session. The endpoint currently does not return email, email_verified, or
email_source.
Local Google QA checklist
Use this checklist when integrating a consuming app such as modo-camp:
1. Use public baseUrl: "https://auth.spectra.kr" unless the task explicitly asks for producer-local Auth.
2. Set redirectUri to the exact local app callback URL.
- http://127.0.0.1:5174/auth/callback
- http://localhost:5174/auth/callback
3. Do not mix localhost and 127.0.0.1 in the same test run.
4. Confirm the same callback URL is saved as the Auth App/Web Callback in Console.
5. Check the new server deployment, active Test callback registration and actual OPTIONS/SDK responses. Do not infer CORS readiness from SDK publication alone.
6. If Apple key/client secret is not issued, skip Apple and verify Google only.
7. Click signInWithGoogle() and confirm the popup reaches Google account chooser.
8. Complete user credential input only with explicit user involvement.
9. After callback, verify getSession() and getAccessToken().
The 2026-08-02 public-test record includes these SDK origins: https://console.spectra.kr, http://localhost:5173,
http://localhost:5174, http://127.0.0.1:5173, and http://127.0.0.1:5174.
Mobile local HTTP contract
Status on 2026-09-05: SDK 0.1.10 is published and install-verified, source
7a7e521aba34e08d7c23a4c46abe64246e7d0546, tag auth-sdk-v0.1.10. Auth/Console 63cf46f deployment and
JWT self-check passed. Registered HTTPS returned five OPTIONS204 and Google/Apple challenge201;
unregistered LAN returned five OPTIONS404 and actual422 without ACAO; owner requests remained401.
The real LAN callback has only been added as a Console draft: save confirmation is pending and no PUT occurred.
Registered LAN CORS, real provider completion and physical-device E2E remain unverified.
77 unit tests, typecheck/build/pack, clean-cache registry installation and public imports/types passed.
Installed-tarball LAN HTTP Chrome desktop/Pixel 7 emulation passed mock Google/Apple login, gates, popup activation and cancellation.
These results are not actual iPhone or public Auth/provider E2E. Read the release table
for final producer commits and separate verification layers. App adapter/configuration alignment is also required.
- Public input in 0.1.10 source:
development?: { allowInsecureHttp?: boolean }; Vite example:development: { allowInsecureHttp: import.meta.env.DEV }. - The SDK cannot automatically identify a consuming app's development build. It checks explicit opt-in, test and the actual local HTTP/fallback callback conditions. The Vite example makes the option false in production builds.
- Check the actual Auth App Client environment first. If already Test, use it; Secret Key environment is independent. If actually Live, preserve it and prepare a separate Test Project/client/provider rather than changing only the SDK environment. The current public client ID supports one App Client environment. No Secret Key issuance/reissue or live key replacement is needed. Modo was confirmed already Test; this is a case-specific observation, not a universal default.
- Permit the SHA-256 JavaScript fallback only with explicit opt-in, Auth
environment: "test", the actual browser page on HTTP RFC1918 IPv4 or existing loopback, and a same-origin callback including per-call overrides. - The same-origin restriction applies only to the new insecure HTTP fallback. Preserve existing HTTPS cross-origin callbacks and existing localhost native Web Crypto behavior without making opt-in mandatory.
- Existing loopback means localhost, 127.0.0.1 and [::1] only; do not extend this to .localhost subdomains or 127.0.0.2.
- Public API in 0.1.10 source:
auth.preflightSignIn(options?: SpectraSignInOptions): void, synchronous, throws SpectraAuthError on failure, no popup/network; local tests passed. - Call signInWithGoogle/Apple directly in the click handler; the SDK performs preflight then obtains the popup. Modo does not need its own preliminary popup. Only if the app retains a custom popup flow should it call preflightSignIn before creating that popup, with the same options used for sign-in.
- This patch strengthens mobile popup login; it does not add full-page redirect login. A passing preflight does not guarantee CORS, provider or popup success.
- Retain secure randomness via
crypto.getRandomValues(), PKCE S256, state/source/origin validation. No Math.random, plain PKCE or wildcard postMessage workaround. Public HTTP and live are unsupported by this exception. - Auth test must accept only exactly registered private IPv4 app callbacks and reflect them in Keycloak redirectUris/webOrigins. Keep provider broker callbacks unchanged.
- Auth SDK CORS derives exact HTTP loopback/RFC1918 or HTTPS origins from active Test App Clients of active Projects with Auth enabled for Test and matching current public clients. It does not edit
AUTH_SDK_ALLOWED_ORIGINS; existing static/loopback grants remain independent. Provider readiness is checked for login, not used as a CORS grant. - Dynamic origin lookup is uncached on the server and repeated for actual responses. OPTIONS Max-Age remains 600; cached preflight does not override later actual-response CORS evaluation. Deletion removes the dynamic grant only after the last eligible callback with that origin is gone. Other Test clients/projects or static/loopback grants can keep the origin allowed. DB/Control inspection failure denies the dynamic grant. Header removal is not session revocation or a guarantee that the request was not processed.
- CORS is an origin union, not tenant authorization. Preserve actual project/client/PKCE/session checks and owner API CORS boundaries. A passing OPTIONS request does not authorize an unregistered callback.
- Console procedure: inspect Auth environment, use
Test 개발 Callback 설정to reachApp/Web Callback URL 목록, add the real callback, preserve the whole existing list including internal callbacks, save withCallback URL 목록 저장, then상태 새로고침.Callback 변경 취소restores the saved list without API calls. Draft edits are not registration. See the Console steps. http://192.168.0.10:5174/auth/callbackis an illustrative Modo URL, not an allocated address or verified runtime. Preserve existing localhost/127.0.0.1 callbacks and origins when adding an actual LAN address.- Keep existing frontend local dev flags/env. Phone-side localhost targets the phone; use the app's same-origin dev proxy for its local Backend. Keep the Auth SDK default HTTPS endpoint.
- Verify the consumer adapter actually passes development.allowInsecureHttp and that a fixed environment redirect does not override the current LAN origin. Align package/lock/runtime and any ambient types/stubs. SDK publication and Auth deployment do not change consumer configuration.
- Browser Auth login does not require a Secret Key or provider credentials. No external tunnel or paid infrastructure is required for this path.
- Missing requestId can mean a client crypto/local preflight rejection, popup blocking, or browser CORS failure before the main request. Record the stage and sanitized metadata; never invent a requestId.
- Read error.status, error.requestId and error.retryAfterSeconds directly, not error.details. SpectraAuthErrorDetails is the constructor input type; absent metadata is undefined.
- Handle INSECURE_HTTP_NOT_ALLOWED with local opt-in/test checks, REDIRECT_URI_INVALID with exact callback checks, SIGN_IN_IN_PROGRESS by avoiding duplicate sign-in, POPUP_BLOCKED by direct click-triggered login, and POPUP_CLOSED/SIGN_IN_TIMEOUT by ending loading and allowing a user retry. SIGN_IN_CANCELLED is confirmed for provider access_denied; SIGN_IN_FAILED covers other provider errors without exposing their raw text.
- Real iPhone Safari/Chrome Google/Apple completion, cancellation, popup blocking, failure, callback/state plus PC localhost/HTTPS regression are unverified until individually recorded.
Use the mobile local HTTP guide for setup, release status and the complete QA checklist.
Public operations
signInWithGoogle(options?): opens Hosted Login popup and stores Spectra app-user session.signInWithApple(options?): same session flow using Apple.relaySpectraAuthCallback(): call from the app callback page to relay result to opener.getSession(): SpectraAuthSession | null: synchronous session snapshot.getAccessToken(options?: SpectraGetAccessTokenOptions): Promise<string>: await the auth token or service token foremail,notification,storage,chat,call; rejects with SESSION_UNAVAILABLE if there is no session.refresh(): refreshes session and clears service token cache.- New Chat self-leave is
undeployed:chat.rooms.leaveis an app-user-only Chat service-token grant, not a Secret Key grant. Existing tokens are not upgraded in place. Chat SDK retries 401/403 once with forceRefresh to mint a new token from the current Auth session; consumers do not set scopes. Token validity does not replace current Chat membership checks. Activate only after coordinated Auth/Chat deployment and Chat SDK0.2.0 publication; see the Chat leave contract. logout(): revokes current session if possible and clears local state.isSpectraAuthError(error): narrows SDK errors so agents can safely readcode,status,retryAfterSeconds, andrequestId.
Consumer example
import {
SpectraAuthClient,
createLocalStorageSessionStore,
} from "@spectra-platform/auth-sdk";
const auth = new SpectraAuthClient({
projectId,
// Current Auth SDK compatibility field. It is not a primary product key.
publicClientId,
environment: "test",
redirectUri,
sessionStore: createLocalStorageSessionStore(),
});
await auth.signInWithGoogle();
const token = await auth.getAccessToken();
const chatToken = await auth.getAccessToken({ service: "chat" });
Error handling example
import { isSpectraAuthError } from "@spectra-platform/auth-sdk";
try {
await auth.signInWithGoogle();
} catch (error) {
if (isSpectraAuthError(error) && error.code === "RATE_LIMITED") {
console.warn("Spectra Auth is rate limited", {
status: error.status,
retryAfterSeconds: error.retryAfterSeconds,
requestId: error.requestId,
});
return;
}
throw error;
}
Do not collapse this to only Try again later. in QA output. The request ID and retry window are the useful escalation
fields.
Callback page
import { relaySpectraAuthCallback } from "@spectra-platform/auth-sdk";
relaySpectraAuthCallback();
Backend verification
Backend services should verify Auth access tokens using JWKS or introspection. App profile/domain data is not owned by Auth.
Prohibited implementation shortcuts
- Do not put Google client secret, Apple private key/client secret, or Keycloak client secret into browser/mobile code.
- Secret Key exposure in browser/mobile code requires an explicit consuming-project architecture decision, and the raw value must not be logged. Do not model app-user/session token expiry as Project Secret Key expiry.
- Do not call internal callback/exchange endpoints directly unless a public SDK doc explicitly exposes them.
- Do not copy Console-only or E2E-test callback code into a consuming app.
- Do not treat Apple setup failure as an app bug when Apple credentials are not in the task scope.
Current caveats
- Public-test Google and Apple Hosted Login E2E passed previously.
- Auth SDK
0.1.6source single-flights concurrentrefresh()and same-servicegetAccessToken({ service, forceRefresh })requests plus 429 retry cooldown within one SDK instance. - On 2026-08-02, public test social challenge smoke for
Origin: http://127.0.0.1:5174returned OPTIONS204and Google POST201. - modo-camp local Google login reached
accounts.google.com /v3/signin/accountchooserafter Auth APIsocial_login_challengerate limit was separated from the stricter shared policy. - If
getSession()is non-null but downstream SDK service-token issuance returnsAPP_SESSION_UNAUTHORIZED, collect the SDKrequestIdand ask Platform CS to inspect Auth API auditdenial_reason. - Live/production repeated provider E2E and downstream production-like JWT/introspection evidence remain separate gates.
Escalate to Platform CS when
signInWithGoogle()completes butgetSession()isnull.getAccessToken()cannot refresh or returns a token with an unexpected audience/service boundary.- A downstream SDK reports
APP_SESSION_UNAUTHORIZEDeven thoughgetSession()is non-null; include the SDK errorrequestId. - The SDK package version does not expose an API listed in this document.
- The runtime asks the consuming app for a prohibited secret.
- Local login fails with
RATE_LIMITEDafter the expected retry window. - The exact local origin is allowlisted but browser preflight still fails.