@W-20893868 feat(auth): migrate browser login to Authorization Code + PKCE#574
Draft
clavery wants to merge 11 commits into
Draft
@W-20893868 feat(auth): migrate browser login to Authorization Code + PKCE#574clavery wants to merge 11 commits into
clavery wants to merge 11 commits into
Conversation
Adds Authorization Code + PKCE as the default user-auth flow, replacing
the OAuth implicit flow in the default chain. New AuthMethod 'user' maps
from --user-auth.
Unifies the per-flow session caches into a single pluggable
AuthSessionStore (file-backed by default, VS Code SecretStorage in the
extension). Sessions are tagged with flow ('pkce' | 'implicit' |
'client-credentials') to discriminate refresh policy.
- PKCE: persists access + refresh tokens; refreshes silently across
invocations, falling back to the browser flow only if refresh fails.
- Implicit: persists access token; emits a deprecation WARN suggesting a
public client + --user-auth.
- Client-credentials (auth client): persists access token only. Client
secret is NEVER persisted. --renew flag and `auth client renew`
command removed accordingly.
Other:
- New default public client a40a7a9b-... for PKCE; legacy implicit
client retained as LEGACY_IMPLICIT_PUBLIC_CLIENT_ID.
- OAuth client-id mismatch protection at config merge: drops a base
clientSecret when override clientId differs (mirrors hostname mismatch
protection).
- Test coverage: oauth-pkce.test.ts mirrors implicit tests plus refresh,
hydration, and persist; session-store.test.ts; oauth-command tests
for the implicit deprecation WARN; auth login command test.
- Docs updated for new auth flow, removed --renew references.
Covers hydrate/find/save/delete/list/clearAll against fake SecretStorage + Memento. Verifies sync-snapshot reads, async write-through, replacement of prior records by clientId, and graceful handling of corrupted JSON.
…ce command - dw.json gains "user-auth": true shorthand for "auth-methods": ["user"] (mutually exclusive with auth-methods; rejected during config mapping) - b2c auth login gains --auth-methods flag to opt into legacy implicit flow (emits deprecation warning) - remove POC b2c auth pkce command - add changeset and update auth/config docs
# Conflicts: # docs/cli/auth.md # packages/b2c-tooling-sdk/src/auth/stateful-oauth-strategy.ts # packages/b2c-vs-extension/src/extension.ts
…est harness Land the Authorization Code + PKCE swap for browser-based OAuth: - PkceWithImplicitFallbackStrategy transitional fallback (gated by SFCC_DISABLE_PKCE_FALLBACK), wired into resolve/oauth-command/login. - Session-file hardening (0o600 file / 0o700 dir) and H4 fix (invalidateToken preserves the refresh token so stale tokens refresh silently instead of reopening the browser). - Swap the pod5 default public client to the PKCE-capable 3f41a930-b2bb-42c9-907d-f06a33c85849 (was implicit-only c44527fe...). - Docs + changeset updated for the new default chain and public-client registration guidance. Add a manual smoke-test harness (not shipped): - SMOKE-TEST.md reference plan and scripts/pkce-smoke-test.sh, an interactive, session-isolated runner covering new (PKCE, fallback, hardening, forced refresh_token grant) and legacy (implicit, client-credentials, JWT, default-client) flows, plus WebDAV/OCAPI instance operations.
…rors The transitional PKCE→implicit fallback was triggering on ANY OAuth 4xx, which was wrong in both directions: - invalid_scope (bad scopes on a working PKCE client) incorrectly fell back and told the user to re-register a fine client. - access_denied (user cancel) at the authorize step would have fallen back, contradicting the intended "user cancel must not fall back" rule. Fallback now fires ONLY on OAuth errors that genuinely indicate the client is not a PKCE-capable public client: invalid_client (Account Manager demands client authentication at the token exchange — the common case for legacy implicit-only clients), unauthorized_client, unsupported_response_type, unsupported_grant_type. Everything else (invalid_scope, access_denied, invalid_grant, non-JSON bodies) surfaces directly, since it would fail identically under implicit. Also: - Deprecation messages no longer say "re-register this client" (an AM client's type can't be changed); they recommend creating a NEW public client and link to a dedicated docs section. - Add "Implicit Flow Deprecation (PKCE Migration)" guide section (guide/authentication.md) documenting the migration, the create-new constraint, and the exact fallback trigger rules. - Update stale b2c-dx.salesforce.com deprecation URLs to the canonical docs host. - Smoke-test harness: add default-client use cases (sandbox realm list, slas client list) and a forced-refresh check; refine fallback docs.
# Conflicts: # packages/b2c-cli/src/commands/auth/client/index.ts # packages/b2c-cli/src/commands/auth/login.ts # packages/b2c-tooling-sdk/src/cli/base-command.ts
# Conflicts: # docs/guide/authentication.md # packages/b2c-tooling-sdk/src/cli/oauth-command.ts # packages/b2c-tooling-sdk/test/cli/oauth-command.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the default browser-based OAuth flow from the deprecated implicit grant to Authorization Code + PKCE (S256), per OAuth 2.1. The
userauth method now uses PKCE by default, persists a refresh token, and hardens the on-disk session store. A transitional fallback keeps users on not-yet-migrated clients working during the rollout.What changed
b2c auth loginand theuserauth method use Authorization Code + PKCE and persist a refresh token, so subsequent commands refresh silently without reopening the browser. Default auth-method chain is nowclient-credentials,jwt,user.--auth-methods implicit(ordw.json) for backward compatibility, with a deprecation warning; it cannot obtain refresh tokens.user-authshorthand indw.json("user-auth": true="auth-methods": ["user"]), and a--auth-methodsflag onauth login. The POCauth pkcecommand is removed.0o600in a0o700directory; a stale token refreshes silently instead of reopening the browser.userflow falls back to implicit and warns. The fallback triggers only on OAuth errors that genuinely indicate the client can't do the code grant —invalid_client,unauthorized_client,unsupported_response_type,unsupported_grant_type. Other errors (invalid_scope,access_denied,invalid_grant, …) surface directly, since they would fail identically under implicit. Disable withSFCC_DISABLE_PKCE_FALLBACK=1.SecretStorage.Manual testing
A companion smoke-test harness is included (
SMOKE-TEST.md+scripts/pkce-smoke-test.sh, not shipped). Run it against a real Account Manager / instance to validate:b2c auth login <public-client>opens the browser, completes viacode_challenge_method=S256, saves a session with a refresh token; no deprecation warning.auth token; expect[Auth] PKCE token refreshed silentlyand a rotated token, no browser.invalid_clientat token exchange) warns and falls back to implicit; a working PKCE client with a bad scope (invalid_scope) surfaces the error directly with no fallback and no browser re-attempt.--client-id) —am users list,sandbox realm list,slas client list --tenant-id … --short-code …all authenticate via the default public client + PKCE.code list,bm whoami,webdav ls, awebdav put→ls→rmround-trip, andjob exportall succeed with a user/PKCE token (WebDAV and OCAPI both), plus client-credentials and Basic-auth regression paths.Full scenario reference and a menu-driven runner are in
SMOKE-TEST.md.