You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(uipath-audit): add audit skill
Skill teaches agents how to drive `uip admin audit org|tenant {sources|events|export}`
from natural-language audit / investigation prompts. Mirrors the structure of the
existing uipath-gov-aops-policy skill.
Adds:
- skills/uipath-audit/SKILL.md
- skills/uipath-audit/references/audit-commands.md
- skills/uipath-audit/references/audit-workflow-guide.md
- tests/tasks/uipath-audit/{audit_sources_smoke,audit_events_pagination_smoke,audit_export_e2e}.yaml
- CODEOWNERS entry
Drive-by: hooks/ensure-uip.sh now respects SKIP_UIP_AUTO_INSTALL=1 so
contributors developing CLI features against a `bun link`'d workspace
binary don't have their link clobbered every session.
Moved audit skills inside uipath-admin
Fixes based on comment
Added tests
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
description: "Always invoke for `uip admin` commands or audit-investigation prompts (who/when/where on a resource, login history, compliance dumps). UiPath Admin via `uip admin <subject> <verb>` — Identity Server (users, groups, robot accounts, external OAuth2 apps, credential generation) and Audit Service (event sources, paginated event queries, long-term-store ZIP exports). For Orchestrator folders/jobs→uipath-platform. For RPA workflows→uipath-rpa."
> **Preview** — Under active development. Command coverage will expand.
10
10
11
-
Identity Server management via `uip admin`. Users, groups, robot accounts, external OAuth2 apps.
11
+
Administrative operations on UiPath via `uip admin` — Identity Server (users, groups, robot accounts, external OAuth2 apps) and Audit Service (event sources, event queries, long-term-store ZIP exports).
-**Generate Client ID/Secret** — credentials for API or robot authentication
23
25
26
+
### Audit
27
+
28
+
Activate on both **explicit audit requests** and **natural-language investigation intent** — users rarely say "audit events" by name.
29
+
30
+
-**Explicit** — `uip admin audit` commands; list sources / targets / types; query, filter, paginate, or export events; CSV/ZIP dump of audit history for a window.
31
+
-**Investigation intent** — "Who deleted the X folder last Tuesday?", "Show me failed logins for user Y this month.", "What changed on tenant Z between Jan 1 and Feb 1?", "Give me the audit log for the last 30 days.", "Was the API key rotated by someone in our org?", "Export everything for compliance for Q4."
32
+
24
33
## Critical Rules
25
34
35
+
### Identity
36
+
26
37
1.**Verify login first.** Run `uip login status --output json`. If not logged in: `uip login`.
27
38
2.**Organization ID is resolved automatically from login.** CLI reads org ID from active session.
28
39
3.**Discover before creating.**`list` before `create` to avoid duplicates. Applies to robot accounts, groups, and external apps — not to `users invite`.
@@ -33,12 +44,28 @@ Identity Server management via `uip admin`. Users, groups, robot accounts, exter
33
44
8.**Confirm before delete.** Always confirm with user before running `delete` on users, groups, robot accounts, or external apps.
34
45
9.**Stop on error (interactive use).** If any command fails, show error to user. Do not retry auth failures — ask user to run `uip login`.
35
46
47
+
### Audit
48
+
49
+
10.**Pick scope before any other audit call — and don't silently default.** Use the [Disambiguation rule](#audit-scope-disambiguation) below: if the prompt is vague about `org` vs `tenant` AND there's no prior conversational context, **ask** which scope (and which tenant if `tenant`). `tenant` requires either a tenant in the login context or `--tenant-id <guid>`. `org` ignores `--tenant-id`.
50
+
11.**Discover source IDs with `sources` before filtering `events`.** Never invent GUIDs for `--source`/`--target`/`--type` — the SDK won't help you guess.
51
+
12.**`events` returns `{ auditEvents, next, previous }` — NOT a bare array.** Cursor naming is **chronological**: `next` = newer, `previous` = older. The default newest-backward walk follows `previous`.
52
+
13.**`events` server-clamps `maxCount` to `[10, 200]`.** When the user wants more than 200, the tool paginates internally — pass `--limit N` and the tool fetches `ceil(N/200)` pages. Do **not** re-implement pagination in the agent.
53
+
14.**`export` writes a ZIP from the long-term store.**`--from-date`, `--to-date`, and `--output-file` are required and ISO 8601 (for the dates). Never overwrite a path the user did not explicitly approve.
54
+
15.**ISO 8601 for time bounds, UTC by default.** Date-only (`2026-04-01`) or with time (`2026-04-01T14:30:00Z`). `--to-date` is inclusive of the exact instant — pass the start of the next day (or `T23:59:59.999Z`) to capture a full final day.
55
+
36
56
## What NOT to Do
37
57
38
58
1.**Never delete built-in groups.**`type: "BuiltIn"` groups cannot be deleted. Only custom groups.
39
59
2.**Never pass IDs as flags.** Resource IDs and names are positional arguments: `groups members add <GROUP_ID> --user-ids ...`, NOT `--group-id <GROUP_ID>`. Same for all `get`, `update`, `delete`, `create` subcommands.
60
+
3.**Do NOT assume audit `events` returns a bare array.** It's `{auditEvents, next, previous}`.
61
+
4.**Do NOT loop on `--from-date`/`--to-date` to "paginate".** Bump `--limit` and the CLI handles cursor pagination internally.
62
+
5.**Do NOT silently default audit scope** to `tenant` or `org` when the prompt is ambiguous. Ask once, then proceed.
63
+
6.**Do NOT invent audit source/target/type GUIDs.** Always discover via `sources` first.
64
+
7.**Do NOT call audit `events` with no time bound** on a noisy tenant — default to a bounded window.
65
+
8.**Do NOT pass `--tenant-id` to `org`-scoped audit commands** — it's silently ignored. If you find yourself doing this, you probably meant `tenant` scope.
66
+
9.**Do NOT retry on 401 auth errors.** The token is missing the required scope (`Audit.Read` for audit). Tell the user to `uip logout && uip login` so the new scope is included.
40
67
41
-
## Quick Start
68
+
## Quick Start — Identity
42
69
43
70
The most common identity flow is **user management** — inviting users, assigning them to groups, and managing access.
44
71
@@ -76,6 +103,58 @@ uip admin groups members add <GROUP_ID> \
76
103
--output json
77
104
```
78
105
106
+
## Quick Start — Audit
107
+
108
+
For the canonical "find events in a window then export" flow. For specific scenarios jump to the [Task Navigation](#task-navigation) table.
109
+
110
+
### Audit scope disambiguation
111
+
112
+
The `org` vs `tenant` choice matters — they hit different basePaths and surface different events.
113
+
114
+
| User says... | Likely scope | Why |
115
+
|---|---|---|
116
+
| "who joined / left the organization", "who was made an admin", "license changes", "cross-tenant audit" |**org**| Org-level admin events (memberships, license, tenant lifecycle) live under `/orgaudit_`. |
117
+
| "what happened on tenant X", "logins on this tenant", "policy changes within a tenant", "asset/queue/folder edits" |**tenant**| Tenant-scoped events (Orchestrator, AOps, AI Trust, etc.) live under `/{tenantId}/tenantaudit_`. |
118
+
| "everything everywhere" |**both** — run the same flow once per scope and present combined results. |
119
+
120
+
If the prompt is **vague about scope** AND no prior turn has established it, **stop and ask** (one yes/no question, two clarifications max). Don't assume `tenant` just because it's the more common case.
Each entry has `id` (a GUID — pass to `events --source`), `name` (human-readable), and `eventTargets[]` (each with their own GUIDs and `eventTypes[]`).
133
+
134
+
### Step 2 — Query events with filters
135
+
136
+
```bash
137
+
uip admin audit tenant events \
138
+
--source <SOURCE_GUID_FROM_STEP_1> \
139
+
--from-date 2026-04-22T00:00:00Z \
140
+
--to-date 2026-04-29T00:00:00Z \
141
+
--limit 50 \
142
+
--output json
143
+
```
144
+
145
+
The response is `{ "auditEvents": [...], "next": null, "previous": "..." }`. For more than 200 events, pass `--limit 500` (or larger) — the tool paginates internally. Do **not** write a manual loop in the agent.
146
+
147
+
### Step 3 — Export for compliance / sharing
148
+
149
+
```bash
150
+
uip admin audit tenant export \
151
+
--from-date 2026-01-01 \
152
+
--to-date 2026-02-01 \
153
+
--output-file ./audit-jan.zip
154
+
```
155
+
156
+
One HTTP call per UTC day inside the window, aggregated into a single flat ZIP at `--output-file`. The result envelope reports `{Path, Bytes, Format: "zip", Days, NonEmptyDays}`. On any chunk failure (e.g. HTTP 504), no file is written and the error identifies which day failed.
157
+
79
158
## Key Concepts
80
159
81
160
### Organization Hierarchy
@@ -101,9 +180,26 @@ These are separate concepts — do not conflate them.
101
180
102
181
Robot credentials are provisioned automatically by Orchestrator when connecting a robot to a machine — not by creating external apps.
|`audit <scope> export`| object `{Path, Bytes, Format, Days, NonEmptyDays}`|
197
+
198
+
`events` is the one verb that legitimately returns an object — pagination cursors live alongside the rows.
199
+
104
200
## Completion Output
105
201
106
-
After any mutation (create, update, delete, invite, members add, members revoke, generate-secret):
202
+
### After identity mutations (create, update, delete, invite, members add/revoke, generate-secret)
107
203
108
204
1. Show the command result (success or failure)
109
205
2. For creates: display the new resource ID
@@ -113,20 +209,34 @@ After any mutation (create, update, delete, invite, members add, members revoke,
113
209
- After creating an external app → "Generate an additional secret?"
114
210
- After inviting a user → "Check user list to see when they accept?"
115
211
212
+
### After an audit query or export
213
+
214
+
1.**Operation & result** — e.g. `Found 47 audit events on tenant T in the last 7 days` or `Wrote 123,456 bytes to /path/to/audit.zip (3 days, 2 non-empty)`.
215
+
2.**Scope used** (`org` or `tenant`) and any `--tenant-id` override.
216
+
3.**Time window** — explicit ISO bounds, even if they came from a relative phrase ("last 7 days").
5.**Cursor state** — for `events`, mention whether `Data.previous` is null (start of audit history) or populated (more older events available — re-run with a larger `--limit`).
219
+
6.**Next step** — "Want me to widen the window?", "Want me to export this slice?", "Want me to filter by user X?". Wait for the user's choice; do not chain mutations.
-**[identity-commands.md](references/identity-commands.md)** — Complete CLI reference for all `uip admin` commands with flags, arguments, and output codes
236
+
-**[identity-commands.md](references/identity-commands.md)** — Complete CLI reference for all `uip admin`identity commands with flags, arguments, and output codes
-**[audit-commands.md](references/audit-commands.md)** — Single source of truth for every `uip admin audit` subcommand: signature, every flag with required/optional, the `Code` value, and the exact `Data` shape returned
242
+
-**[audit-workflow-guide.md](references/audit-workflow-guide.md)** — Narrative playbook for the four canonical investigations: who-did-X, login-history, date-range-dump, and org-vs-tenant comparison
0 commit comments