Skip to content

UIAM API Key tests#4

Draft
kc13greiner wants to merge 1 commit intoazasypkin:issue-xxx-uiam-api-contracts-v2from
kc13greiner:issue-xxx-uiam-api-contracts-v2
Draft

UIAM API Key tests#4
kc13greiner wants to merge 1 commit intoazasypkin:issue-xxx-uiam-api-contracts-v2from
kc13greiner:issue-xxx-uiam-api-contracts-v2

Conversation

@kc13greiner
Copy link
Copy Markdown

Summary

Adding API tests for UIAM API Keys functionality

@kc13greiner kc13greiner marked this pull request as draft February 13, 2026 00:17
azasypkin pushed a commit that referenced this pull request Apr 2, 2026
Closes elastic#258318
Closes elastic#258319

## Summary

Adds logic to the alert episodes table to display `.alert_actions`
information.

This includes:
- New action-specific API paths.
- Snooze
  - **Per group hash.**
- Button in the actions column opens a popover where an `until` can be
picked.
  - **When snoozed**
    - A bell shows up in the status column.
- Mouse over the bell icon to see until when the snooze is in effect.
- Unsnooze
  - **Per group hash.**
  - Clicking the button removes the snooze.
- Ack/Unack
  - **Per episode.**
  - Button in the actions column
  - When "acked", an icon shows in the status column.
- Tags
- This PR only handles displaying tags. They need to be created via API.
- Resolve/Unresolve
  - **Per group hash.**
  - Button inside the ellipsis always
- The status is turned to `inactive` **regardless of the "real"
status.**

<img width="1704" height="672" alt="Screenshot 2026-03-25 at 16 04 12"
src="https://github.com/user-attachments/assets/5ef4111a-6e0c-4114-a60e-ce5f81a86ac6"
/>


## Testing


<details> <summary>POST mock episodes</summary>

```
POST _bulk
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:00:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:01:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "pending" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:02:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:03:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "inactive" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:04:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:05:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:06:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-001", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:07:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:08:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "active" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:09:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "recovering" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:10:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "recovering" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:11:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:12:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "recovering" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:13:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-2", "episode": { "id": "ep-002", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:14:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-003", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:15:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-1", "episode": { "id": "ep-003", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:16:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-4", "episode": { "id": "ep-004", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:17:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-4", "episode": { "id": "ep-004", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:18:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-4", "episode": { "id": "ep-004", "status": "recovering" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:19:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-4", "episode": { "id": "ep-004", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:20:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-5", "episode": { "id": "ep-005", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:21:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-5", "episode": { "id": "ep-005", "status": "pending" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:22:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "gh-5", "episode": { "id": "ep-005", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:23:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "elasticgh-9", "episode": { "id": "ep-006", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:24:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "elasticgh-9", "episode": { "id": "ep-006", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:25:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "elasticgh-9", "episode": { "id": "ep-006", "status": "active" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:26:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-1" }, "group_hash": "elasticgh-9", "episode": { "id": "ep-006", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:14:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-2" }, "group_hash": "elasticgh-7", "episode": { "id": "ep-007", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:15:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-2" }, "group_hash": "elasticgh-7", "episode": { "id": "ep-007", "status": "inactive" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:16:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-3" }, "group_hash": "elasticgh-8", "episode": { "id": "ep-008", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:17:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-3" }, "group_hash": "elasticgh-8", "episode": { "id": "ep-008", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:18:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-3" }, "group_hash": "elasticgh-8", "episode": { "id": "ep-008", "status": "recovering" }, "status": "recovered" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:20:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-4" }, "group_hash": "elasticgh-9", "episode": { "id": "ep-009", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:21:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-4" }, "group_hash": "elasticgh-9", "episode": { "id": "ep-009", "status": "pending" }, "status": "no_data" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:23:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-5" }, "group_hash": "elasticgh-10", "episode": { "id": "ep-010", "status": "pending" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:24:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-5" }, "group_hash": "elasticgh-10", "episode": { "id": "ep-010", "status": "active" }, "status": "breached" }
{ "create": { "_index": ".rule-events" }}
{ "@timestamp": "2026-01-27T16:25:00.000Z", "source": "internal", "type": "alert", "rule": { "id": "rule-5" }, "group_hash": "elasticgh-10", "episode": { "id": "ep-010", "status": "active" }, "status": "no_data" }
```

</details>

- In the POST above, episodes 1 and 3, and episodes 6 and 9 have the
same group hashes.
- Go to `https://localhost:5601/app/observability/alerts-v2` and try all
buttons.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
azasypkin pushed a commit that referenced this pull request Apr 9, 2026
## Summary

Part of: elastic/security-team#15982.
(Resolves requirement `#4`)

This change introduces a dedicated **`StepCategory.KibanaCases`**
(`kibana.cases`) so Cases workflow steps are grouped under **Kibana →
Cases** in the workflow actions menu instead of sitting in the flat
Kibana list.

**Actions menu (`workflows_management`)**

- Builds a **Cases** subgroup (`id: kibana.cases`) under the Kibana
group via **`nestedGroups`**, then merges any non-empty nested group
into the parent’s **`options`** so the UI stays a normal tree of groups.
- Assigns **`pathIds`** on every group (full path from the root) so
choosing a nested group from **search** opens the correct depth (Kibana
→ Cases → …) instead of only appending the last segment.
- **`ActionsMenu`** uses `selectedOption.pathIds ?? [...currentPath,
id]` when entering a group.

**Shared spec**

- Adds **`StepCategory.KibanaCases`** in `@kbn/kbn-workflows` so step
definitions and UI routing can target the Cases bucket explicitly.

**Cases plugin**

- Updates all Cases **common workflow step** definitions to use
**`StepCategory.KibanaCases`** instead of **`StepCategory.Kibana`**.

**Agent builder**

- **`get_step_definitions_tool`**: maps connector types **`cases.*`** →
**`KibanaCases`** and keeps **`kibana.*`** → **`Kibana`**.

**Tests**

- Extends **`get_action_options.test.ts`** for nested Cases, empty Cases
group hidden, **`pathIds`**, and ordering expectations.

---

## Demo


https://github.com/user-attachments/assets/dc14c35d-f63c-4165-9c23-1590a22edf80

---
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.

1 participant