Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
61b61d1
feat(governance): add Governance getPolicyEvaluationTraces service
ashishupadhyay88 May 26, 2026
540bcac
fix(governance): use camelCase traceId in test overrides
ashishupadhyay88 May 26, 2026
7c1976d
refactor(governance): rename getPolicyEvaluationTraces to getTraces
ashishupadhyay88 May 26, 2026
4797e91
refactor(governance): rename getTraces back to getPolicyTraces
ashishupadhyay88 May 26, 2026
bc0243f
chore(governance): drop misleading Snowflake-format mock constants
ashishupadhyay88 May 26, 2026
2054b86
refactor(governance): extract GovernanceFilterOptions base type
ashishupadhyay88 May 26, 2026
37b66bc
refactor(governance): rename PolicyTracesGetAllOptions to PolicyTrace…
ashishupadhyay88 May 27, 2026
121c015
refactor(governance): make raw startTime required and trim internal-t…
ashishupadhyay88 May 27, 2026
fb85aac
fix(governance): drop RawPolicyTracesResponse from test mock
ashishupadhyay88 May 27, 2026
95ececc
docs(governance): trim implementation detail from service JSDoc
ashishupadhyay88 May 29, 2026
740e8eb
docs(governance): clarify trace row description
ashishupadhyay88 May 29, 2026
8d3182d
docs(governance): trim implementation detail from service JSDoc
ashishupadhyay88 May 29, 2026
ae87c19
docs(governance): clarify filter value mapping
ashishupadhyay88 May 29, 2026
bd4b2e6
docs(governance): trim redundant trace row JSDoc
ashishupadhyay88 May 29, 2026
47a3c1d
docs(governance): clarify getPolicyTraces example comment
ashishupadhyay88 Jun 2, 2026
41080bc
docs(governance): clarify bare-minimum example comment
ashishupadhyay88 Jun 2, 2026
13715d0
refactor(governance): route getPolicyTraces through shared pagination…
ashishupadhyay88 Jun 3, 2026
8cc9711
docs(governance): expand getPolicyTraces JSDoc summary
ashishupadhyay88 Jun 3, 2026
1db3484
fix(governance): derive excludeFromPrefix from request keys
ashishupadhyay88 Jun 3, 2026
bb00ebf
docs(governance): clarify getPolicyTraces JSDoc and field descriptions
ashishupadhyay88 Jun 3, 2026
fb59b91
docs(governance): fix run-on sentence in getPolicyTraces JSDoc
ashishupadhyay88 Jun 3, 2026
4ace5e4
fix(governance): type policyEvaluationResult as string to match API c…
ashishupadhyay88 Jun 4, 2026
04b54b8
test(governance): fix misleading test names for getPolicyTraces
ashishupadhyay88 Jun 4, 2026
f21b77e
refactor(governance): prefix governance types and mocks with Governan…
ashishupadhyay88 Jun 5, 2026
1b5fef2
docs(governance): link to Automation Ops governance policies guide
ashishupadhyay88 Jun 5, 2026
fdf3c0d
docs(governance): add @default tag to fullOrganization
ashishupadhyay88 Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/oauth-scopes.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ The `ConversationalAgents` scope is required for real-time WebSocket sessions (`
| `getById()` | `Traces.Api` |
| `getSpansByIds()` | `Traces.Api` |

## Governance

| Method | OAuth Scope |
|--------|-------------|
| `getPolicyTraces()` | `Insights.RealTimeData Insights OR.Folders.Read` |

## Processes

| Method | OAuth Scope |
Expand Down
1 change: 1 addition & 0 deletions docs/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,4 @@ console.log(`Total count: ${allAssets.totalCount}`);
| Feedback | `getCategories()` | ✅ Yes |
| Traces | `getById()` | ❌ No |
| Traces | `getSpansByIds()` | ❌ No |
| Governance | `getPolicyTraces()` | ✅ Yes |
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ nav:
- Entities:
- api/interfaces/entity/index.md
- Choice Sets: api/interfaces/ChoiceSetServiceModel.md
- Governance: api/interfaces/GovernanceServiceModel.md
- Maestro:
- Processes: api/interfaces/MaestroProcessesServiceModel.md
- Process Instances: api/interfaces/ProcessInstancesServiceModel.md
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@
"types": "./dist/document-understanding/index.d.ts",
"default": "./dist/document-understanding/index.cjs"
}
},
"./governance": {
"import": {
"types": "./dist/governance/index.d.ts",
"default": "./dist/governance/index.mjs"
},
"require": {
"types": "./dist/governance/index.d.ts",
"default": "./dist/governance/index.cjs"
}
}
},
"files": [
Expand Down
5 changes: 5 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ const serviceEntries = [
name: 'document-understanding',
input: 'src/models/document-understanding/index.ts',
output: 'document-understanding/index'
},
{
name: 'governance',
input: 'src/services/governance/index.ts',
output: 'governance/index'
}
];

Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './models/action-center';
export * from './models/conversational-agent';
export * from './models/agents';
export * from './models/document-understanding';
export * from './models/governance';

// Export error handling functionality (public API only)
export * from './core/errors';
Expand Down
23 changes: 23 additions & 0 deletions src/models/governance/governance.internal-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Raw policy evaluation trace item as returned by API before transformation.
*/
export interface RawGovernancePolicyTraceItem {
tenantId?: string;
startTime: string;
finalEnforcement?: string;
policyId?: string;
policyEnforcement?: string;
policyEvaluationResult?: string;
Comment thread
ashishupadhyay88 marked this conversation as resolved.
policyName?: string;
policyStatus?: string;
policyEvaluationDetails?: string;
actorProcessId?: string;
actorProcessType?: string;
actorIdentityId?: string;
resourceId?: string;
resourceType?: string;
folderKey?: string;
traceId?: string;
processKey?: string;
jobKey?: string;
}
81 changes: 81 additions & 0 deletions src/models/governance/governance.models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type {
GovernancePolicyTrace,
GovernancePolicyTraceGetAllOptions,
} from './governance.types';
import type {
PaginatedResponse,
NonPaginatedResponse,
HasPaginationOptions,
} from '../../utils/pagination';

/**
* Service for inspecting governance policy enforcement on the UiPath platform.
Comment thread
ashishupadhyay88 marked this conversation as resolved.
*
* See [Define governance policies](https://docs.uipath.com/automation-ops/automation-cloud/latest/user-guide/define-governance-policies)
* for how governance policies are configured in Automation Ops.
*
* All methods require the caller to be an organization administrator.
*
* ### Usage
*
* Prerequisites: Initialize the SDK first - see [Getting Started](/uipath-typescript/getting-started/#import-initialize)
*
* ```typescript
* import { Governance } from '@uipath/uipath-typescript/governance';
*
* const governance = new Governance(sdk);
* const traces = await governance.getPolicyTraces(new Date('2024-01-01'));
* ```
*/
export interface GovernanceServiceModel {
/**
* Gets per-policy enforcement decisions across the requested time range.
*
* Each result row represents one policy's verdict within a single governance enforcement event.
* A single user action can produce multiple rows when multiple policies were consulted.
* Results are ordered by event start time, descending.
*
* @param startTime - Inclusive lower bound on the trace start time.
* @param options - Optional filters and pagination options
* @returns Promise resolving to {@link NonPaginatedResponse} of {@link GovernancePolicyTrace}
* without pagination options, or {@link PaginatedResponse} of
* {@link GovernancePolicyTrace} when pagination options are used.
*
* @example
* ```typescript
* import { Governance, PolicyEvaluationResult } from '@uipath/uipath-typescript/governance';
*
* const governance = new Governance(sdk);
*
* // Get all policy traces from the specified start time
* const recent = await governance.getPolicyTraces(new Date('2024-01-01'));
* console.log(recent.items.length);
*
* // Get all denied decisions across the whole organization
* const page1 = await governance.getPolicyTraces(
* new Date('2024-01-01'),
* {
* endTime: new Date(),
* evaluationResult: [PolicyEvaluationResult.Deny, PolicyEvaluationResult.SimulatedDeny],
* fullOrganization: true,
* pageSize: 25,
* },
* );
*
* if (page1.hasNextPage) {
* const page2 = await governance.getPolicyTraces(
* new Date('2024-01-01'),
* { cursor: page1.nextCursor },
* );
* }
* ```
*/
getPolicyTraces<T extends GovernancePolicyTraceGetAllOptions = GovernancePolicyTraceGetAllOptions>(
startTime: Date,
options?: T,
): Promise<
T extends HasPaginationOptions<T>
? PaginatedResponse<GovernancePolicyTrace>
: NonPaginatedResponse<GovernancePolicyTrace>
>;
}
113 changes: 113 additions & 0 deletions src/models/governance/governance.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* Governance Service Types
*
* Public types exposed via `@uipath/uipath-typescript/governance`.
*/

import { PaginationOptions } from '../../utils/pagination/types';

export enum PolicyEvaluationResult {
/** Active policy permitted the action. */
Allow = 'Allow',
/** Active policy blocked the action. */
Deny = 'Deny',
/** Simulated (NoOp) policy would have permitted the action. */
SimulatedAllow = 'SimulatedAllow',
/** Simulated (NoOp) policy would have blocked the action. */
SimulatedDeny = 'SimulatedDeny',
}

/**
* Each trace row represents one policy's verdict within a governance
* enforcement event. One enforcement event can produce multiple trace rows
* when multiple policies contributed to the final verdict.
*/
export interface GovernancePolicyTrace {
/** Tenant the trace was recorded in. Present even when `fullOrganization` is `true`. */
tenantId?: string;
Comment thread
ashishupadhyay88 marked this conversation as resolved.
/** The start time of governance enforcement event. */
startTime: string;
/** Final enforcement verdict for the parent governance event. */
finalEnforcement?: string;
/** ID of the policy this trace row evaluates. */
policyId?: string;
Comment thread
Raina451 marked this conversation as resolved.
/** This individual policy's enforcement contribution to the parent verdict. */
policyEnforcement?: string;
/** The outcome of one policy evaluation — whether it allowed or denied the action, and whether that decision was actively enforced or just simulated (NoOp). */
policyEvaluationResult?: string;
Comment thread
ashishupadhyay88 marked this conversation as resolved.
/** Display name of the policy. */
policyName?: string;
/** Enforcement mode of the policy at the time of evaluation. */
policyStatus?: string;
Comment thread
ashishupadhyay88 marked this conversation as resolved.
Comment thread
ashishupadhyay88 marked this conversation as resolved.
/** Opaque details payload describing the evaluation result. */
policyEvaluationDetails?: string;
/** Process or executable that triggered the evaluation. */
actorProcessId?: string;
/** Type of the actor process (e.g. coded agent, RPA process). */
actorProcessType?: string;
Comment thread
Raina451 marked this conversation as resolved.
/** Identity (user/principal) that triggered the evaluation. */
actorIdentityId?: string;
/** Resource being acted on. */
resourceId?: string;
/** Type of the resource being acted on. */
resourceType?: string;
/** Orchestrator folder key associated with the evaluation, if any. */
folderKey?: string;
/** Distributed-tracing ID covering the governance enforcement event. */
traceId?: string;
/** Process key associated with the evaluation, if any. */
processKey?: string;
/** Job key associated with the evaluation, if any. */
jobKey?: string;
}

/**
* Common filter options shared across Governance APIs.
*
* Holds filters that are not specific to any single governance resource, so
* other governance endpoints can reuse them.
*/
export interface GovernanceFilterOptions {
/**
* Inclusive upper bound on trace start time. When omitted, the upper bound
* is open.
*/
endTime?: Date;
/**
* Whether to query the whole organization instead of just the current tenant.
*
* Defaults to tenant-scoped:
* - omitted → tenant-scoped (default)
* - `false` → tenant-scoped (explicit, same result)
* - `true` → org-wide across all tenants; requires an organization admin,
* otherwise the request returns 403
*
* @default false
*/
fullOrganization?: boolean;
}

/**
* Filter and pagination options for fetching policy traces.
*
* All filters combine with AND semantics. Array filters match any value in
* the array (OR within a single filter).
*/
export type GovernancePolicyTraceGetAllOptions = PaginationOptions & GovernanceFilterOptions & {
/** Filter by one or more policy evaluation results. */
Comment thread
ashishupadhyay88 marked this conversation as resolved.
evaluationResult?: PolicyEvaluationResult[];
/** Filter by one or more policy IDs. */
policyId?: string[];
/** Filter by one or more actor process IDs. */
actorProcessId?: string[];
/** Filter by one or more actor process types (e.g. coded agent, RPA process). */
actorProcessType?: string[];
/** Filter by one or more actor identity IDs. */
actorIdentityId?: string[];
/** Filter by one or more resource IDs. */
resourceId?: string[];
/** Filter by one or more resource types. */
resourceType?: string[];
/** Filter by one or more distributed-trace IDs. */
traceId?: string[];
};
8 changes: 8 additions & 0 deletions src/models/governance/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Governance Types
*
* Public type surface for the Governance service.
*/

export * from './governance.types';
export * from './governance.models';
5 changes: 4 additions & 1 deletion src/services/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@
/**
* Prepares request parameters for pagination based on pagination type
*/
private preparePaginationRequestParams(

Check failure on line 221 in src/services/base.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-typescript&issues=AZ6XLe4KdapTw3k_z_Fm&open=AZ6XLe4KdapTw3k_z_Fm&pullRequest=464
paginationType: PaginationType,
params: InternalPaginationOptions,
paginationConfig?: RequestWithPaginationOptions['pagination']
Expand All @@ -237,14 +237,17 @@
// When true (default), converts pageNumber to a skip/offset value (e.g., page 3 with pageSize 10 → skip 20).
// When false, passes pageNumber directly as the offset param — used by APIs that accept a page number instead of a record offset.
const convertToSkip = paginationParams?.convertToSkip ?? true;
// When true, sends pageNumber - 1 (for 0-based APIs). Default false (1-based).
const zeroBased = paginationParams?.zeroBased ?? false;

Check warning on line 241 in src/services/base.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unexpected lexical declaration in case block.

See more on https://sonarcloud.io/project/issues?id=UiPath_uipath-typescript&issues=AZ6XLe4KdapTw3k_z_Fn&open=AZ6XLe4KdapTw3k_z_Fn&pullRequest=464

requestParams[pageSizeParam] = limitedPageSize;
if (convertToSkip) {
if (params.pageNumber && params.pageNumber > 1) {
requestParams[offsetParam] = (params.pageNumber - 1) * limitedPageSize;
}
} else {
requestParams[offsetParam] = params.pageNumber || 1;
const sdkPageNumber = params.pageNumber || 1;
requestParams[offsetParam] = zeroBased ? sdkPageNumber - 1 : sdkPageNumber;
}
if (countParam) {
requestParams[countParam] = true;
Expand Down
Loading
Loading