本文へ移動
cccskills
無料GitHub で公開

refresh-token-transports

Change AuthCrunch refresh/logout HTTP routes, secure cookies, native JSON credential transport, browser Web Locks, continuation pages, fresh login, or cross-tab session coordination.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md16.3 KB
  • agents/openai.yaml287 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Refresh Token Transports

HTTP Ownership

pkg/authn/handle_api_refresh_token.go owns refresh and logout parsing, transport checks, response delivery, cookie creation/deletion, and revocation of an earlier browser family. respond_api.go dispatches these reserved routes before ordinary access authorization so expired access tokens can renew or log out. Preserve authorization and access-expiry checks on all other APIs.

Routes are POST <mount>/api/refresh_token, <mount>/api/refresh_session, and <mount>/api/logout. The session endpoint is browser-only and returns only the current family ID without rotating its credential; it uses the same origin, header, JSON, mount, and cookie checks. It does not establish fresh identity authorization. Known spent credentials retain normal lookup replay revocation; never use this endpoint to recover an uncertain exchange.

The embedded profile client also uses a top-level GET navigation to <mount>/api/refresh_token after a 401. Canonical, query-free requests with Sec-Fetch-Mode: navigate and Sec-Fetch-Dest: document redirect to <mount>/login?fresh=1, including when refresh is disabled. With refresh enabled, the configured origin and mount must match. This compatibility path never rotates credentials; ordinary API GETs retain their method/availability errors. A fresh=1 login page does not probe the identity endpoint for a login completed in another tab; ordinary login pages do. A continue page reached from the login page with a trusted redirect_url replaces itself with that destination after the refresh, else with the portal, and deletes the shared redirect cookie when it holds that destination. The renderer supplies data-next for older filesystem themes too. Empty/rejected choices use portal?redirect_url= and fresh-login links retain an explicit empty marker, preventing a later cookie write from changing the continuation; see per-flow login destinations.

Refresh exchanges require the exact configured HTTPS origin, effective host, and canonical mount. Browser requests require matching Origin, X-Authcrunch-Refresh: 1, JSON, and compatible Fetch Metadata. Reject query parameters, unknown/duplicate JSON fields, trailing data, bodies over 1 KiB, duplicate refresh cookies, and mixed cookie/body credentials. Embedding servers still own forwarded-host/protocol normalization; never broaden trust merely to make a proxy setup pass.

Cookie transport returns session/expiry metadata only. Cookie names come from the portal factory's RefreshTokenCookieName, defaulting to AUTHP_REFRESH_TOKEN. The shared cookie contract owns cookie prefix, cookie refresh token name, and the reusable cookie parser. Honor the common prefix and explicit name settings. An enabled token refresh cookie name directive overrides the shared refresh-cookie setting before factory construction. Read that effective name for request extraction, browser session detection, issuance, native response metadata, revocation, and deletion. Never derive an independent name from the origin/mount or require a browser security prefix. Explicit __Host- names still require root scope.

Refresh cookies are Secure, HttpOnly, host-only, SameSite=Lax, and mount-scoped. Access cookies retain configured domain/path with bounded access expiry. Refresh cookie lifetime is independent of access cookie configuration. Responses use Cache-Control: no-store.

Native body transport requires explicit config and refresh_transport: body at initial JSON login and every sandbox checkpoint. Pin that choice through issuance and rotation. Reject browser Origin, Fetch Metadata, and Cookie headers for native requests; return credentials in JSON and set no cookies. Never accept a cookie-family token through body transport or vice versa.

Explicitly selected OAuth/OIDC snapshot realms issue cookie families from their verified browser-bound callbacks. The callback can be a cross-site GET navigation; its origin/mount and optional navigation Fetch Metadata checks follow completed state redemption. Keep ordinary refresh POST protections unchanged. Callback delivery omits bearer Authorization and upstream identity-token cookies must be disabled. Provider native token exchange and renewable cross-device requester sessions are unavailable. Use the identity owner's provider snapshot contract for proof and selection requirements. Existing browser coordination applies to provider families too.

API key JSON /login is a separate access-only path owned by authentication-client. It does not enter sandbox refresh issuance, sets no cookies, and rejects refresh_transport: body, even in a refresh-enabled realm. Do not treat possession of an API key as completed password/MFA login evidence.

Use the status contract: 400 malformed/ambiguous request, 401 login required, 403 origin/transport violation, 404 disabled/wrong mount, 405 wrong method, 415 wrong content type, and 503 transient signing/storage/backend failure. No response delivers credentials before the store commits.

After a cookie rotation commits, failure to reconstruct or cache the user must discard the undelivered family with bounded cleanup independent of request cancellation. Keep the current HTTP request context for reconstruction so issuer/address-dependent provider transforms see the same metadata as signing. If cleanup also fails, return 503 even when reconstruction denied identity or policy; a joined denial must not hide unavailable storage. The provider renewal completion-cleanup unit/TLS tests cover cancellation, recovered admission without presenting an old credential, and persistent cleanup failure.

Completed browser logout also invalidates outstanding cross-device approvals tied to that access session or refresh family. Keep this after successful logout checks; merely rendering a logout confirmation page does not revoke approval. The transfer also checks authoritative family liveness, so logout after a fresh login page clears the access cookie still prevents redemption. This remains true after healthy rotation and when replay or account replacement revokes the family. Do not make invalidation depend solely on an access JWT accompanying logout.

Browser Lifecycle

pkg/authn/ui/core/js/refresh.js exposes AuthCrunchSession.refresh() and .logout(). Preserve the same-page promise and shared cross-tab Web Lock for both operations. Browser storage holds only session/expiry metadata and an in-flight marker, never access or refresh secrets. Another tab may reuse a completed result; it must not rotate the same credential concurrently.

Persist the pending marker before dispatch. A lost response can mean the server already rotated, so do not automatically retry an ambiguous result, including after navigation or reload. Browsers without Web Locks or usable local storage fail closed to login. Never introduce a spent-token grace window to hide client coordination defects.

Bootstrap reads and writes session metadata under the shared Web Lock. Treat HTML data-session/data-expires values as stale hints, never authority to replace storage. The client confirms the current signed access cookie through GET <mount>/whoami?probe=true. A different confirmed SID identifies a new login and can replace an older SID's pending/blocked marker; the same SID cannot clear uncertainty, including when a lost response updated its access cookie. Failed access confirmation cannot look up an uncertain refresh token. If access expired before initial portal use and there is no uncertainty, the protected session endpoint obtains a family ID before the first rotation.

Each JavaScript rotation sends X-Authcrunch-Refresh-Session with the SID saved in its pending marker. Manager.RefreshForSession checks that precondition before identity verification/signing/rotation, so a concurrent login that changes cookies cannot redirect an old pending request to a new valid family. Unknown or different expected IDs fail without consuming a valid current credential. The existing Manager.Refresh and requests omitting the header retain their contract; embedding browser coordinators must opt into the precondition too. Serve the matching JavaScript and HTTP surface together; embedding adapters must forward the metadata route and precondition header. Do not assume older handlers implement the precondition merely because they accept extra headers. An empty/duplicate header, or use on native/logout/lookup requests, is malformed. Known spent-token lookup retains ordinary replay-revocation semantics.

Storage events clear timers for pending/blocked state and reconfirm a different healthy SID under the lock. A previously rejected tab can reconfirm access on an explicit refresh/focus even before the storage event is delivered. Those access probes do not rotate or look up uncertain refresh credentials. Preserve the same-page flight promise and the response SID check. Use the current signed access deadline when confirming metadata, and reject nonnumeric expiry state before scheduling or rotating. Logout retains its SID in the blocked marker and remains available after bootstrap refuses rotation. Malformed or pre-release uncertain records without a SID fail closed; never relabel them using a document's ID or assume they refer to a new login.

handle_http_session.go and ui/page_templates/basic/session.template own continuation/confirmation UI; handle_http_portal.go, handle_http_login.go, and the portal template load the client conditionally. Expired portal access can renew through top-level continuation; fresh=1 starts a new login without looping back to renewal. Fresh login also works on access-only portals and deletes the old access cookie so the next form submission can start a sandbox. Retain refresh cookies until login completion can revoke the previous family. Preserve CSP and trusted destination checks. External apps must explicitly integrate this flow; a same-origin portal client does not automatically renew arbitrary cross-origin applications.

GET logout shows confirmation when refresh state exists. The protected POST revokes the family before clearing cookies and following a trusted destination. A revocation failure returns 503 without claiming success. A completed new browser login revokes the previous family even when the new realm is access-only. Clear legacy refresh cookies at <mount>/api/refresh_token without deleting the active credential at <mount>: the two cookies can share the same factory name. Keep explicit security-prefix compatibility without making those prefixes defaults. Provider logout retains its separate protocol behavior.

Account replacement coverage must include JSON password/MFA login with browser cookies and Origin, including transitions to realms outside the refresh list. The shared issuer stages signing and atomically replaces presented cookie families through Manager.IssueReplacing, including at full capacity. Use the implementation owner's terminal-retention and optional-adapter contract. handleIssueTokens also retires prior refresh authority on access-only completion, then completes OIDC login and delivers browser credentials. Revocation failure returns 503 without claiming success or changing authentication cookies. These components do not share one transaction. JSON completion revokes its new, undelivered refresh family when a later step fails, with bounded cleanup that survives request cancellation. Cleanup failure returns unavailable. Require a fresh login; never restore a previously replaced family. Keep OIDC-capacity recovery, canceled-request cleanup, and cleanup-outage regressions in token_refresh_completion_test.go and real TLS coverage in token_refresh_completion_e2e_test.go. When an existing refresh cookie identifies a browser switching to an access-only realm, update its access cookie as well as returning the existing access-only JSON result. Use the factory's effective names and delete both active and legacy refresh paths. HTML and JSON login validate the refresh origin when a refresh cookie is present even if the new realm is unselected.

Check the previous credential at the real refresh endpoint after successful replacement; checking only the new access token or response headers misses retained authority. Keep API-key and explicit native body authentication outside browser replacement. A cookie-free access-only JSON login retains its existing response contract and does not acquire an access cookie through replacement.

Validation

Run make test TEST_DIR='./pkg/authn/... ./pkg/apiauth' and make test-ui. The Go route suite is pkg/authn/handle_api_refresh_token_test.go; cookie and embedded inventory tests live in pkg/authn/cookie and pkg/authn/ui. pkg/authn/ui/testdata/token_refresh_client_test.cjs simulates DOM, storage, fetch, and Web Locks. Keep concurrent refresh/logout, stored-pending failure, continuation, fresh-login recovery before/after storage events, different IDs, delayed initialization, and lost/malformed responses. Assert all metadata writes occur under the lock. This simulation is distinct from the real browser suite. Update UI asset inventories when adding embedded files.

token_refresh_session_test.go and token_refresh/session_test.go cover lookup and precondition boundaries. TestE2ERefreshSessionPrecondition uses a real TLS portal with default/custom cookie names and checks that an older SID cannot consume another account's current credential.

TestE2ERefreshBrowserBootstrap runs in the default Go suite and requires Node 24 and headless Chrome, following the browser engine policy. Do not use Firefox. Set AUTHCRUNCH_TEST_BROWSER to the Chrome executable if it is not on PATH or at the standard macOS Chrome location. Missing engines fail rather than substituting the VM simulation. The Go fixture owns the browser process and a temporary profile, trusts only its test certificate's SPKI, and uses mock/basic key storage without changing OS trust or browser profiles. The launcher waits up to 45 seconds for DevToolsActivePort within the existing 90-second E2E deadline and detects process exit while waiting. Failed startup stops and reaps the process before reporting its output, so diagnostics cannot race with subprocess writes. TestE2ERefreshBrowserStartup exercises delayed partial readiness, early exits, deadline cleanup, and missing executables with local process fixtures; the bootstrap test retains the real Chrome journey. Its standard-library Node CDP driver is ui/testdata/token_refresh_browser_e2e.cjs. Two real tabs use actual cookies, storage events, and Web Locks while the server holds previously rendered HTML and truncates an already committed refresh response. Assert the old HTML preserves the new family's pending state, sends no repeated rotation, and recovers both tabs after a real new login; then verify logout blocks further refresh. The fixture also checks Whoami authorization. This proves local Chrome behavior, not every browser or production proxy.

make test-ui
make test TEST_DIR='./pkg/authn' TEST='TestE2ERefreshBrowserBootstrap|TestE2ERefreshSessionPrecondition' COVERAGE_DIR='.coverage/refresh-browser'

TestE2ETokenRefreshCookieLifecycle in pkg/authn/token_refresh_config_parser_e2e_test.go uses a real TLS client and cookie jar with both public configuration parsers to check prefix/name overrides, legacy-path cleanup, rotation, logout, and revocation. Keep ordinary fixtures on the common portal cookie convention. login_replacement_e2e_test.go covers actual TLS browser replacement across accounts and realms, same-account MFA login, default/custom names, old-path cleanup, OIDC replacement, foreign-Origin denial, and native/API-key isolation. login_replacement_test.go injects a revocation outage and checks both selected and access-only completion, including preservation of the prior OIDC session. token_refresh_provider_e2e_test.go adds real verified OAuth callback issuance, provider/local replacement, cookie-only renewal, replay, logout and deadline coverage. Keep its cross-site navigation headers and independent expired-access authorization check.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

authdb

無料

Maintain the standalone cmd/authdb server, pkg/httpserver listener and portal routing, HTTP configuration parser, TLS, shutdown, executable tests, and deployment guidance. Use authdbctl for the management client.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

authdbctl

無料

Maintain cmd/authdbctl commands, flags, configuration, terminal input, management retries, output, and executable E2E tests. Use authentication-client for the reusable portal login protocol.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain or embed pkg/authclient for portal login, password/TOTP and API-key authentication, native credential transport, configuration parsing, and credential files. Covers authdbctl login wiring; management commands and the admin API have separate owners.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain conditional authentication challenge policies, reusable authchal and user-transform FromDirectives parsers, safe claim substitution, GitHub ID/organization transforms, registered-factor inventory, passwordless WebAuthn selection, verified AMR access claims, and policy revalidation across portal login, refresh, OIDC, and direct authentication.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain portal cookie configuration, reusable cookie directive parsing, common prefixes and explicit names, domain attributes, factory issuance/deletion, and cookie interoperability with OIDC, refresh, OAuth, and gatekeepers.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain optional cross-device portal login, its directive parser, QR and polling UI, approving-browser binding, single-use transfers, MFA and provider evidence, logout invalidation, and TLS/browser tests.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

greenpau のスキルをすべて見る

このスキルの問題を報告する