Files
cve-dashboard/docs/ivanti-api-reference.md

107 lines
4.1 KiB
Markdown
Raw Normal View History

# Ivanti / RiskSense API Reference
Base URL: `https://platform4.risksense.com/api/v1`
Swagger: `https://platform4.risksense.com/doc/swagger.json`
Auth: `x-api-key` header. Error codes: 401 bad key, 419 insufficient privileges, 429 rate limited.
## Endpoints Used
### Search Workflow Batches
```
POST /client/{clientId}/workflowBatch/search
Content-Type: application/json
```
Standard JSON body with filters, projection, sort, page, size. Used by `ivantiWorkflows.js` for the daily sync.
### Create False Positive Workflow
```
POST /client/{clientId}/workflowBatch/falsePositive/request
Content-Type: multipart/form-data
```
This endpoint does NOT accept JSON. It requires `multipart/form-data` with the following fields:
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `name` | string | yes | Workflow batch name (max 255) |
| `reason` | string | yes | Reason for the FP determination |
| `description` | string | yes | Description (can be empty string but field must be present) |
| `expirationDate` | string | yes | ISO-8601 date, e.g. `2026-06-01` |
| `overrideControl` | string | yes | `AUTHORIZED`, `NONE`, or `AUTOMATED`. Use `AUTHORIZED` for standard FP workflows. `NONE` with `isEmptyWorkflow=true` is rejected (400). |
| `isEmptyWorkflow` | boolean | yes | `true` if no findings attached, `false` otherwise |
| `subjectFilterRequest` | string | yes | Stringified JSON (see format below) |
| `files` | file | no | Attachments sent inline in the same request |
#### subjectFilterRequest format
This is the critical field. It must be a stringified JSON object with this exact structure:
```json
{
"subject": "hostFinding",
"filterRequest": {
"filters": [
{
"field": "id",
"exclusive": false,
"operator": "IN",
"value": "2283734550,2283734551"
}
]
}
}
```
Key details:
- `subject` must be `"hostFinding"` — without this, the API returns 500
- `filters` is nested inside `filterRequest`, NOT at the top level — `{"filters":[]}` at the top level returns 500
- `value` for multiple IDs is comma-separated as a single string, not an array
- `operator` values: `EXACT`, `IN`, `LIKE`, `WILDCARD`, `RANGE`, `CIDR`
- For empty workflows, use `{"subject":"hostFinding","filterRequest":{"filters":[]}}` with `isEmptyWorkflow=true`
#### Response (200/202)
```json
{
"id": 33418832,
"created": "2026-04-08T18:16:08"
}
```
Returns HTTP 200 or 202 (Accepted — async job creation). Response contains a numeric `id` (the workflow batch job ID) and `created` timestamp. No `generatedId` or `uuid` in this response.
### Other Workflow Endpoints (from Swagger)
These are available but not currently used by the dashboard:
| Endpoint | Purpose |
|----------|---------|
| `/workflowBatch/acceptance/request` | Risk acceptance workflow |
| `/workflowBatch/remediation/request` | Remediation workflow |
| `/workflowBatch/severityChange/request` | Severity change workflow |
| `/workflowBatch/{workflowType}/approve` | Approve a workflow (needs `workflowBatchUuid`) |
| `/workflowBatch/{workflowType}/reject` | Reject a workflow |
| `/workflowBatch/{workflowType}/rework` | Send back for rework |
| `/workflowBatch/{workflowType}/update` | Update a workflow |
| `/workflowBatch/{workflowType}/{workflowBatchUuid}/map` | Map findings to workflow |
| `/workflowBatch/{workflowType}/{workflowBatchUuid}/unmap` | Unmap findings |
| `/workflowBatch/{workflowType}/{workflowBatchUuid}/attach` | Attach file to existing workflow |
| `/workflowBatch/{workflowType}/{workflowBatchUuid}/detach` | Detach file |
| `/workflowBatch/model` | Get model/schema |
| `/workflowBatch/filter` | Get available filter fields |
| `/workflowBatch/suggest` | Get suggested values for a filter field |
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `IVANTI_API_KEY` | — | Required. API key for authentication |
| `IVANTI_CLIENT_ID` | `1550` | Client ID in the Ivanti platform |
| `IVANTI_SKIP_TLS` | `false` | Set `true` to skip TLS verification |
| `IVANTI_FIRST_NAME` | — | Used for workflow search filter (sync) |
| `IVANTI_LAST_NAME` | — | Used for workflow search filter (sync) |