Skip to content

[Security Solution][Attacks/Alerts] Attacks page tour (#17464)#275055

Open
e40pud wants to merge 4 commits into
elastic:mainfrom
e40pud:security/attack-alerts-alignment/17464-Attacks-Tour
Open

[Security Solution][Attacks/Alerts] Attacks page tour (#17464)#275055
e40pud wants to merge 4 commits into
elastic:mainfrom
e40pud:security/attack-alerts-alignment/17464-Attacks-Tour

Conversation

@e40pud

@e40pud e40pud commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a first-run onboarding experience to the Security Solution Attacks page, gated behind a new experimental feature flag (attacksPageTourEnabled). It introduces:

  • A "What's new in Attacks" welcome callout rendered above the filters, letting the user start the guided tour, open the docs, or dismiss the promotion.
  • A guided tour built on EuiTourStep that walks the user through the key parts of the page:
    1. Run & Schedule – manual and scheduled attack detection.
    2. New filters – the filters group (anchored dynamically to the filter button via data-test-subj).
    3. Attack details flyout – shown only when attacks are present.
  • Persistence of tour/callout state in local storage so progress survives reloads, plus reconciliation that cleanly completes the tour if the available steps shrink (e.g. attacks are filtered out).
  • Telemetry for callout actions (view, view_docs, dismiss, start) and per-step interactions.
  • Internationalization for all user-facing strings and a new siem.attacksPage documentation link.

The whole experience is off by default; flipping attacksPageTourEnabled enables it.

Closes #17464

Changes

  • Feature flag: added attacksPageTourEnabled (default false) in common/experimental_features.ts.
  • Doc link: added siem.attacksPage in @kbn/doc-links (types.ts, get_doc_links.ts).
  • Storage keys: added ATTACKS_PAGE / ATTACKS_PAGE_CALLOUT tour storage keys in common/constants.ts.
  • Telemetry: added TourCalloutAction / TourStepAction events and schemas.
  • Tour module (public/detections/components/attacks/tour/):
    • attacks_tour_provider.tsx – context provider, state persistence, reconciliation, anchor safety valve.
    • attacks_tour.tsx – renders the current EuiTourStep only when its anchor is mounted.
    • welcome_tour_callout.tsx – the welcome callout.
    • tour_steps_config.tsx, translations.ts, constants.ts, use_is_anchor_mounted.ts, index.ts.
    • images/ – callout and per-step illustrations.
  • Wiring: content.tsx mounts the provider, callout, and tour behind the flag; table/table_section.tsx surfaces filter-aware attack presence (onAttackIdsChange) used to drive the optional flyout step.
  • Tests: unit tests for the provider, the tour, and the welcome callout.

How to verify

  1. Enable the flag in config/kibana.dev.yml (or kibana.yml):
    xpack.securitySolution.enableExperimental: ['attacksPageTourEnabled']
  2. Make sure announcements are not globally hidden: in Stack Management → Advanced Settings, confirm hideAnnouncements is off.
  3. Start Kibana and navigate to Security → Attacks.
  4. Verify the "What's new in Attacks" callout appears above the filters with the illustration, Start tour and View docs buttons, and a dismiss (×) control.
  5. Click View docs – it should open the attacks page documentation in a new tab (middle-click / "open in new tab" / "copy link" should also work) and fire view_docs telemetry.
  6. Click Start tour and step through each step:
    • Step 1 anchors to the Run/Schedule action.
    • Step 2 anchors to the filters group.
    • Step 3 (Attack details flyout) appears only when attacks exist; with no attacks the tour completes after step 2.
  7. Reload the page mid-tour and confirm the tour resumes on the same step.
  8. Dismiss the callout and reload – it should stay dismissed.
  9. Disable the flag and confirm the callout and tour are completely absent.

Resetting a finished/dismissed tour

The tour and callout persist their state in the browser's local storage, so once completed or dismissed they won't reappear. To re-test from a clean slate, clear the relevant keys from the browser console (DevTools → Console) and reload:

// Resets the guided tour (active step / completed flag)
localStorage.removeItem('securitySolution.attacksPage.newFeaturesTour.v9.5');
// Resets the "welcome callout dismissed" flag
localStorage.removeItem('securitySolution.attacksPage.tourCalloutDismissed.v9.5');

Then reload the Attacks page — the welcome callout reappears and the tour can be started again. (You can inspect the same keys under DevTools → Application → Local Storage to see the persisted state.)

Screenshots

Screen.Recording.2026-06-25.at.14.55.44.mov

PR developed with Cursor + Claude Opus 4.8

@e40pud e40pud self-assigned this Jun 25, 2026
@e40pud e40pud requested review from a team as code owners June 25, 2026 13:00
@e40pud e40pud added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting Team:Threat Hunting Security Solution Threat Hunting Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. labels Jun 25, 2026
@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/security-threat-hunting (Team:Threat Hunting)

@infra-vault-gh-plugin-prod

Copy link
Copy Markdown

Pinging @elastic/security-solution (Team: SecuritySolution)

@github-actions github-actions Bot 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.

One non-blocking performance note left inline on the always-on MutationObserver in useIsAnchorMounted. Otherwise the change is well-structured: the tour is fully gated behind the attacksPageTourEnabled experimental flag (off by default), state persistence/reconciliation and the anchor safety valve are sound, and the provider/tour/callout each have focused unit coverage. Telemetry, i18n, and the doc link are wired correctly.

Generated by Claude Reviewer for issue #275055 · 235.8 AIC · ⌖ 10.4 AIC · ⊞ 3.9K

e40pud added 3 commits June 25, 2026 16:06
…ep illustrations out of the page-load bundle

The tour's illustration SVGs are all under webpack's 8KB inline threshold, so they were embedded as base64 into the page-load bundle (the Attacks page is statically imported), pushing the securitySolution plugin over its size limit.

Lazy-load the tour view components (`WelcomeTourCallout`, `AttacksTour`) via `React.lazy` + `Suspense` so their inlined SVGs land in async chunks instead of the page-load bundle, matching the onboarding cards pattern. The provider stays
eager since it has no images; the step config (which imports the SVGs) now lives only in the lazy `AttacksTour`, and the step count moved to a lightweight `ATTACKS_TOUR_STEP_COUNT` constant so the provider no longer needs to import it.

No optimizer limit bump required.
…ur to keep illustrations out of the page-load bundle"

This reverts commit e3475dd.
@kibanamachine

Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #25 / Dataset Quality Dataset Quality Details failed docs reflects the qualityIssuesChart field state in url
  • [job] [logs] FTR Configs #109 / lens app - group 4 lens share tests should preserve filter and query when sharing
  • [job] [logs] Scout Lane #14 - stateful-classic / default / local-stateful-classic - Hosts Page - Flyout - Overview Tab - KPI charts and collapsible sections
  • [job] [logs] Scout Lane #11 - stateful-classic / default / local-stateful-classic - Observability alerts - add to case (all privileges) - opens the create-case flyout from "Add to new case"
  • [job] [logs] Scout Lane #11 - stateful-classic / default / local-stateful-classic - Observability alerts - add to case (all privileges) - opens the existing-cases modal from "Add to existing case"
  • [job] [logs] Scout Lane #11 - stateful-classic / default / local-stateful-classic - Observability alerts - add to case (all privileges) - renders the case options in the row actions menu
  • [job] [logs] Scout Lane #11 - stateful-classic / default / local-stateful-classic - Observability alerts - summary widget - shows active and total alert counts

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 9680 9692 +12

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
aiAssistantManagementSelection 100.7KB 100.7KB +53.0B
securitySolution 12.2MB 12.3MB +34.7KB
total +34.7KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
core 546.3KB 546.4KB +53.0B
securitySolution 166.8KB 167.4KB +686.0B
total +739.0B

History

cc @e40pud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Threat Hunting Security Solution Threat Hunting Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DOCS] Fix links on Vega vs. VegaLite page

2 participants