Skip to content

Persist AI Gateway default passphrase security banner dismissal to localStorage#21292

Merged
TomeHirata merged 3 commits intomasterfrom
copilot/fix-gateway-banner-dismissal
Mar 5, 2026
Merged

Persist AI Gateway default passphrase security banner dismissal to localStorage#21292
TomeHirata merged 3 commits intomasterfrom
copilot/fix-gateway-banner-dismissal

Conversation

Copy link
Contributor

Copilot AI commented Mar 3, 2026

The security warning banner shown when AI Gateway uses the default KEK passphrase reappears on every navigation back to the gateway tab because dismissed state was stored only in component-local React state (useState(false)), which resets on unmount.

What changes are proposed in this pull request?

  • DefaultPassphraseBanner.tsx: Use the project's useLocalStorage hook to initialize and persist dismissed state, with key mlflow.gateway.default-passphrase-warning.dismissed (stored as mlflow.gateway.default-passphrase-warning.dismissed_v1 after versioning). This handles storage failures gracefully (e.g., when localStorage is blocked by browser privacy settings) and follows project conventions that ban direct localStorage access.
  • DefaultPassphraseBanner.test.tsx (new): Tests for banner render, localStorage persistence on dismiss, and suppression when already dismissed.

How is this PR tested?

  • New unit/integration tests

Does this PR require documentation update?

  • No. You can skip the rest of this section.

Does this PR require updating the MLflow Skills repository?

  • No. You can skip the rest of this section.

Release Notes

Is this a user-facing change?

  • Yes. Give a description of this change to be included in the release notes for MLflow users.

AI Gateway security warning banner for default KEK passphrase now stays dismissed across navigation once a user closes it.

What component(s), interfaces, languages, and integrations does this PR affect?

Components

  • area/gateway: MLflow AI Gateway client APIs, server, and third-party integrations
  • area/uiux: Front-end, user experience, plotting, JavaScript, JavaScript dev server

How should the PR be classified in the release notes? Choose one:

  • rn/bug-fix - A user-facing bug fix worth mentioning in the release notes

Should this PR be included in the next patch release?

  • Yes (this PR will be cherry-picked and included in the next patch release)
  • No (this PR will be included in the next minor release)

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue with gateway banner persistence Persist AI Gateway default passphrase security banner dismissal to localStorage Mar 3, 2026
@TomeHirata TomeHirata marked this pull request as ready for review March 3, 2026 06:07
@github-actions github-actions bot added area/uiux Front-end, user experience, plotting, JavaScript, JavaScript dev server rn/bug-fix Mention under Bug Fixes in Changelogs. size/S Small PR (10-49 LoC) labels Mar 3, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Persists dismissal state for the AI Gateway “default KEK passphrase” security warning banner so it remains dismissed across navigation by storing the state in localStorage.

Changes:

  • Read banner dismissed state from localStorage on mount and persist dismissal on close.
  • Add unit/integration tests covering render, dismissal persistence, and suppression when previously dismissed.

Reviewed changes

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

File Description
mlflow/server/js/src/gateway/components/DefaultPassphraseBanner.tsx Persist banner dismissal state to localStorage and use a memoized close handler.
mlflow/server/js/src/gateway/components/DefaultPassphraseBanner.test.tsx Add tests validating rendering and localStorage-backed dismissal behavior.

Comment on lines 9 to 15
const [isDismissed, setIsDismissed] = useState(
() => localStorage.getItem(DEFAULT_PASSPHRASE_BANNER_DISMISSED_KEY) === 'true',
);

const handleClose = () => {
const handleClose = useCallback(() => {
localStorage.setItem(DEFAULT_PASSPHRASE_BANNER_DISMISSED_KEY, 'true');
setIsDismissed(true);
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

🟡 MODERATE: localStorage.getItem/setItem are called unguarded during render and in the close handler. In environments where storage is unavailable/blocked (e.g., browser privacy settings), these can throw and crash the banner (and potentially the page). Consider wrapping the reads/writes in try/catch or using the existing useLocalStorage helper (which already handles failures) to make dismissal persistence non-fatal.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +11
const [isDismissed, setIsDismissed] = useState(
() => localStorage.getItem(DEFAULT_PASSPHRASE_BANNER_DISMISSED_KEY) === 'true',
);
Copy link
Collaborator

@daniellok-db daniellok-db Mar 4, 2026

Choose a reason for hiding this comment

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

can we use useLocalStorage hook instead? i discovered during backsync that direct localstorage access is banned in universe. i intend to align the lint rules some time in the next sprint

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to useLocalStorage hook in 76d2112. It handles storage failures gracefully and follows the project conventions.

… localStorage access

Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com>
Copy link
Collaborator

@daniellok-db daniellok-db left a comment

Choose a reason for hiding this comment

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

Lg

@TomeHirata TomeHirata enabled auto-merge March 5, 2026 01:01
@TomeHirata TomeHirata added this pull request to the merge queue Mar 5, 2026
Merged via the queue into master with commit 7b39099 Mar 5, 2026
32 checks passed
@TomeHirata TomeHirata deleted the copilot/fix-gateway-banner-dismissal branch March 5, 2026 01:17
daniellok-db pushed a commit to daniellok-db/mlflow that referenced this pull request Mar 5, 2026
…calStorage (mlflow#21292)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com>
daniellok-db pushed a commit to daniellok-db/mlflow that referenced this pull request Mar 5, 2026
…calStorage (mlflow#21292)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com>
daniellok-db pushed a commit that referenced this pull request Mar 5, 2026
…calStorage (#21292)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: TomeHirata <33407409+TomeHirata@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/uiux Front-end, user experience, plotting, JavaScript, JavaScript dev server mlflow-fix-it-q1fy27 rn/bug-fix Mention under Bug Fixes in Changelogs. size/S Small PR (10-49 LoC) v3.10.1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants