Skip to content

Add Step-up rechallenge implementation#2869

Merged
rinatkhaziev merged 35 commits into
trunkfrom
feat/rechallenge-v2-defensive-mode
Jul 6, 2026
Merged

Add Step-up rechallenge implementation#2869
rinatkhaziev merged 35 commits into
trunkfrom
feat/rechallenge-v2-defensive-mode

Conversation

@rinatkhaziev

@rinatkhaziev rinatkhaziev commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Description

This pull request implements step-up rechallenge support end-to-end for elevated-permission operations, and wires it into the shipped CLI experience.

Shipped behavior

  • Adds a rechallenge flow in the GraphQL request path so protected mutations can trigger step-up verification and then retry automatically with elevated authorization.
  • Adds operation-scoped elevated-token caching with keychain-backed persistence (scoped by API host), so repeated protected operations can reuse a valid elevation window.
  • Clears elevated-token cache on both login and logout so cached elevation cannot carry across user identity changes.
  • Introduces the vip defensive-mode command group with enable, disable, and configure subcommands.
  • Adds production safety guards for defensive-mode mutations, including explicit confirmation requirements in non-interactive contexts.
  • Adds non-interactive rechallenge fail-fast behavior by default, with explicit opt-in wait support via --rechallenge-wait / VIP_RECHALLENGE_WAIT=1.
  • Extracts API host constants into a dedicated module to support rechallenge integration without circular dependency regressions.

Test coverage included

  • Adds unit tests for rechallenge client, flow orchestration, Apollo link integration, token cache behavior, defensive-mode API and commands, API-chain retries, and logout/login cache clearing paths.

Changelog Description

Added

  • Added new vip defensive-mode commands to enable, disable, and configure defensive mode for an environment.
  • Added step-up verification support for protected actions, including automatic retry after verification succeeds.

Changed

  • Non-interactive runs now fail fast when step-up verification is required, unless you explicitly opt in to wait with --rechallenge-wait or VIP_RECHALLENGE_WAIT=1.
  • Production defensive-mode mutations in non-interactive workflows now require explicit confirmation bypass via --skip-confirmation.

Fixed

  • Login and logout now clear cached elevated permissions to prevent reuse across account switches on the same machine.

Pull request checklist

New release checklist

Steps to Test

Outline the steps to test and verify the PR here.

Example:

  1. Check out PR.
  2. Run npm run build
  3. Run ./dist/bin/vip-cookies.js nom
  4. Verify cookies are delicious.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new “step-up / rechallenge” elevated-permissions flow that integrates with the existing Apollo GraphQL client (via a custom ApolloLink), adds an elevated-token cache, and wires the flow into logout. It also adds a new vip defensive-mode CLI command group backed by new defensive-mode GraphQL mutations, along with a broad suite of unit tests around these behaviors.

Changes:

  • Add rechallenge (step-up) client, flow orchestration, ApolloLink integration, error types, and elevated-token keychain cache.
  • Add defensive-mode GraphQL mutation helpers and new CLI commands (vip defensive-mode enable|disable|configure).
  • Add unit tests for rechallenge components, defensive-mode API, logout behavior, and defensive-mode command behavior.

Reviewed changes

Copilot reviewed 22 out of 30 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/lib/token.ts Switches API host/constants import to avoid pulling full api.ts graph.
src/lib/rechallenge/types.ts Defines rechallenge protocol/types and constants.
src/lib/rechallenge/token-cache.ts Implements keychain-backed elevated-token cache keyed by scope.
src/lib/rechallenge/open-browser.ts Adds wrapper around ESM-only open for browser launching.
src/lib/rechallenge/link.ts Adds ApolloLink that pre-attaches cached elevated token and runs rechallenge on elevated-permission errors.
src/lib/rechallenge/index.ts Exposes rechallenge module exports.
src/lib/rechallenge/flow.ts Implements rechallenge orchestration (session create → poll → exchange → cache).
src/lib/rechallenge/errors.ts Adds typed rechallenge error classes.
src/lib/rechallenge/client.ts Adds HTTP client for rechallenge session/status/exchange endpoints.
src/lib/logout.ts Clears elevated-token cache on logout in addition to primary token purge.
src/lib/defensive-mode/api.ts Adds GraphQL mutations/helpers to update defensive-mode status/config.
src/lib/api/http.ts Switches API_HOST import to new constants module (reduces circular deps).
src/lib/api/feature-flags.ts Lazy-initializes Apollo client to break a circular dependency chain.
src/lib/api/constants.ts Introduces shared API host/URL constants (re-exported by api.ts).
src/lib/api.ts Re-exports constants and injects rechallenge link via lazy require() to avoid Jest mock timing issues.
src/bin/vip.js Registers the new defensive-mode top-level CLI command.
src/bin/vip-defensive-mode.js Adds vip defensive-mode parent command and subcommand wiring.
src/bin/vip-defensive-mode-enable.js Adds vip defensive-mode enable command implementation.
src/bin/vip-defensive-mode-disable.js Adds vip defensive-mode disable command implementation.
src/bin/vip-defensive-mode-configure.js Adds vip defensive-mode configure command implementation with flag validation/prompting.
package.json Adds new vip-defensive-mode* bin entries for distribution.
tests/lib/rechallenge/token-cache.test.ts Unit tests for elevated-token cache behavior and corruption handling.
tests/lib/rechallenge/link.test.ts Unit tests for rechallenge ApolloLink preflight, retry, and error propagation.
tests/lib/rechallenge/flow.test.ts Unit tests for rechallenge flow polling/exchange/caching and interactivity detection.
tests/lib/rechallenge/client.test.ts Unit tests for rechallenge HTTP client request shapes and non-2xx error handling.
tests/lib/logout.test.ts Verifies logout clears both primary token and elevated-token cache + telemetry.
tests/lib/defensive-mode/api.test.ts Verifies defensive-mode mutation input formatting and optional field omission.
tests/bin/vip-defensive-mode-enable.js Tests command registration and enable behavior (including non-interactive production safety).
tests/bin/vip-defensive-mode-disable.js Tests command registration and disable behavior (including non-interactive production safety).
tests/bin/vip-defensive-mode-configure.js Tests configure flag validation, non-interactive behavior, logging, and telemetry.

Comment thread src/lib/defensive-mode/api.ts
Comment thread src/lib/defensive-mode/api.ts
Comment thread src/lib/rechallenge/errors.ts
Comment thread src/lib/rechallenge/link.ts
Comment thread __tests__/lib/rechallenge/client.test.ts
Comment thread src/bin/vip-defensive-mode-configure.js Outdated
Comment thread src/lib/logout.ts Outdated
Comment thread package.json
Comment thread src/lib/rechallenge/flow.ts Outdated
Comment thread src/bin/vip-defensive-mode-configure.js Outdated
Comment thread src/bin/vip-defensive-mode-configure.js Outdated
Comment thread src/lib/rechallenge/link.ts
Comment thread src/lib/rechallenge/flow.ts Outdated
Comment thread src/lib/rechallenge/flow.ts
Comment thread __tests__/bin/vip-defensive-mode-configure.js
Comment thread src/lib/rechallenge/flow.ts Outdated
@sjinks sjinks force-pushed the feat/rechallenge-v2-defensive-mode branch from 36c8952 to 291ed25 Compare July 1, 2026 15:17
Comment thread __tests__/lib/rechallenge/token-cache.test.ts Fixed
Comment thread __tests__/lib/rechallenge/token-cache.test.ts Fixed
Comment thread __tests__/lib/rechallenge/token-cache.test.ts Fixed
Also extracts API_HOST/API_URL/PRODUCTION_API_HOST into a leaf constants
module and lazy-requires the rechallenge link inside API() to break a
circular-dependency cycle that caused Jest mocks to misfire in the
rechallenge test suite.
Implements `vip defensive-mode configure` with full flag validation,
interactive prompting for missing required flags, and non-interactive
hard-error mode.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 35 changed files in this pull request and generated 3 comments.

Comment thread src/lib/defensive-mode/cli-helpers.ts
Comment thread src/lib/rechallenge/flow.ts
Comment thread src/lib/rechallenge/flow.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 35 changed files in this pull request and generated 2 comments.

Comment on lines +58 to +62
super(
`Step-up verification is required for ${ scope }, but this is a non-interactive session. ` +
'Re-run the command interactively, or pass --rechallenge-wait (or set VIP_RECHALLENGE_WAIT=1) ' +
'to print the verification URL and wait for you to complete it on another device.',
scope

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what to do with this one. This is the third reviewer who flags this issue.

I have verified that no other command triggers rechallenge, but I understand why reviews flag this issue.

@rinatkhaziev, what do you think?

Comment thread src/lib/rechallenge/flow.ts Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 35 changed files in this pull request and generated 4 comments.

Comment thread src/lib/rechallenge/open-browser.ts
Comment on lines +58 to +63
super(
`Step-up verification is required for ${ scope }, but this is a non-interactive session. ` +
'Re-run the command interactively, or pass --rechallenge-wait (or set VIP_RECHALLENGE_WAIT=1) ' +
'to print the verification URL and wait for you to complete it on another device.',
scope
);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as #2869 (comment)

Comment thread src/lib/rechallenge/token-cache.ts
Comment thread src/lib/rechallenge/flow.ts
@sjinks sjinks requested review from Copilot and sjinks and removed request for sjinks July 1, 2026 22:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 36 changed files in this pull request and generated 3 comments.

Comment thread src/lib/rechallenge/errors.ts
Comment thread src/lib/defensive-mode/api.ts
Comment thread src/lib/api.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 36 changed files in this pull request and generated 4 comments.

Comment thread src/lib/rechallenge/flow.ts
Comment thread src/lib/rechallenge/flow.ts
Comment thread src/lib/rechallenge/errors.ts
Comment thread src/lib/rechallenge/token-cache.ts
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 36 changed files in this pull request and generated 1 comment.

Comment thread src/lib/rechallenge/errors.ts
@rinatkhaziev rinatkhaziev merged commit ed01bc5 into trunk Jul 6, 2026
22 of 23 checks passed
@rinatkhaziev rinatkhaziev deleted the feat/rechallenge-v2-defensive-mode branch July 6, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants