# Policy Waiver REST API

This API can be used to create, retrieve, update and delete policy waivers.

**NOTE: The GET Method currently does not support retrieval of expired waivers.**

## GET

### By OwnerId

```
GET /api/v2/policyWaivers/{ownerType: application|organization|repository|repository_container}/{ownerId}
```

The scope of the waiver is determined by the parameters _ownerType_ and _ownerID_. Possible values for _ownerType_ and _owner ID_ are application, organization, root organization, repository or repository container.

**Examples:**

1. Retrieve all policy waivers for the root org

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/organization/ROOT_ORGANIZATION_ID
```

2. Retrieve all policy waivers that are applied to the application with application id `787c2e3dc8e745c48743926251eef00b`.

NOTE: The results do not include inherited waivers, i.e. those applied at the organization or root level.

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/application/787c2e3dc8e745c48743926251eef00b
```

3. Retrieve all policy waivers for repository container

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/repository_container/REPOSITORY_CONTAINER_ID
```

4. Retrieve all policy waivers for repository id 6891f877e254428c991d9be640a32969

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/repository/6891f877e254428c991d9be640a32969
```

**Response:**

```
[\
    {\
        "policyWaiverId": "f29f2e2927d64f1a91a7c06c3f52dad3",\
        "comment": "",\
        "createTime": "2022-10-07T21:28:10.418+0000",\
        "expiryTime": "2022-11-07T04:59:59.999+0000",\
        "scopeOwnerType": "application",\
        "scopeOwnerId": "0d3fa305cb8d4ff4b9442d29816cf24c",\
        "scopeOwnerName": "Application - TestApp",\
        "hash": null,\
        "policyId": "8ed35daa437349d8ac08688842fe922f",\
        "vulnerabilityId": "sonatype-2020-0926",\
        "creatorId": "admin",\
        "creatorName": "Admin BuiltIn",\
        "matcherStrategy": "ALL_VERSIONS",\
        "associatedPackageUrl": "pkg:maven/com.google.guava/guava@25.1-android?type=jar",\
        "componentIdentifier": {\
            "format": "maven",\
            "coordinates": {\
                "artifactId": "guava",\
                "extension": "jar",\
                "groupId": "com.google.guava",\
                "version": "25.1-android"\
            }\
        },\
        "reasonText": "Acknowledged violation",\
        "displayName": {\
            "parts": [\
                {\
                    "field": "Group",\
                    "value": "com.google.guava"\
                },\
                {\
                    "value": " : "\
                },\
                {\
                    "field": "Artifact",\
                    "value": "guava"\
                },\
                {\
                    "value": " : "\
                },\
                {\
                    "field": "Version",\
                    "value": "25.1-android"\
                }\
            ],\
            "name": "guava"\
        }\
    },\
    {\
        "policyWaiverId": "405790725d4d4fc6878a919c3b189f2f",\
        "comment": "",\
        "createTime": "2022-10-07T21:28:49.860+0000",\
        "scopeOwnerType": "application",\
        "scopeOwnerId": "0d3fa305cb8d4ff4b9442d29816cf24c",\
        "scopeOwnerName": "Application - TestApp",\
        "hash": "6fdf25b9d89b961d217a",\
        "policyId": "c4a13a490a21435581124b2f9c4ea99c",\
        "creatorId": "admin",\
        "creatorName": "Admin BuiltIn",\
        "matcherStrategy": "EXACT_COMPONENT",\
        "associatedPackageUrl": null,\
        "componentIdentifier": null,\
        "displayName": null\
    }\
]
```

Matcher strategy indicates if the retrieved waiver applies to a specific component, all components that exist at the chosen level of hierarchy (root, org, application,) or all versions (past, present and future) of a component.

associatedPackageUrl, displayName, and componentIdentifier are null when a waiver is of all components type and for unknown components.

### By policyWaiverId

```
GET /api/v2/policyWaivers/{ownerType: application|organization|repository|repository_container}/{ownerId}/{policyWaiverId}
```

The scope of the waiver is determined by the parameters ownerType and ownerID. Possible values for ownerType and owner ID are application, organization, root organization, repository or repository container.

**Examples:**

1. Retrieve a policy waiver with root org scope and policyWaiverId b0864840e52e41fa9eb80214222ba5e5

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/organization/ROOT_ORGANIZATION_ID/b0864840e52e41fa9eb80214222ba5e5
```

2. Retrieve a policy waiver with application scope 28fa2fc995784480a781e601b00ebc5c and policyWaiverID ad8aecc1ba2f4ef686f117bf4a05e0e7

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/application/28fa2fc995784480a781e601b00ebc5c/ad8aecc1ba2f4ef686f117bf4a05e0e7
```

3. Retrieve a policy waiver with repository container scope and policyWaiverID a564d1bd4db734a6ec2b41e9243b8996

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/repository_container/REPOSITORY_CONTAINER_ID/a564d1bd4db734a6ec2b41e9243b8996
```

4. Retrieve a policy waiver with repository scope ce43cd92d0348c73e27bca58c3ee93a9 and policyWaiverId 76d34c0e3f5230e6ef8fb54ed4c1ee30

```
curl -u admin:admin123 http://localhost:8070/api/v2/policyWaivers/repository/ce43cd92d0348c73e27bca58c3ee93a9/76d34c0e3f5230e6ef8fb54ed4c1ee30
```

**Response:**

```
{  
  "policyWaiverId": "9fc1ee3f2761458380d2135ef01135f4",  
  "comment": "",  
  "createTime": "2022-10-07T21:49:00.051+0000",  
  "expiryTime": "2022-10-22T04:59:59.999+0000",  
  "scopeOwnerType": "organization",  
  "scopeOwnerId": "e40aed6067cc431491d42154c1257ed6",  
  "scopeOwnerName": "MyOrg",  
  "hash": "686ef3410bcf4ab8ce7f",  
  "policyId": "d378f2c0bb2d404bbec04cd5f894188b",  
  "vulnerabilityId": "CVE-2014-0114",  
  "policyName": "Security-High",  
  "constraintFacts": [\
    {\
      "constraintId": "6b68cdbe13884c779e44d643062b4b1c",\
      "constraintName": "High risk CVSS score",\
      "operatorName": "AND",\
      "conditionFacts": [\
        ...\
      ]\
    }\
  ],  
  "constraintFactsJson": "...",  
  "creatorId": "admin",  
  "creatorName": "Admin BuiltIn",  
  "matcherStrategy": "EXACT_COMPONENT",  
  "associatedPackageUrl": "pkg:maven/commons-beanutils/commons-beanutils@1.8.3?type=jar",  
  "componentIdentifier": {  
    "format": "maven",  
    "coordinates": {  
      "artifactId": "commons-beanutils",  
      "extension": "jar",  
      "groupId": "commons-beanutils",  
      "version": "1.8.3"  
    }  
  },  
  "threatLevel": 9,  
  "displayName": {  
    "parts": [\
      {\
        "field": "Group",\
        "value": "commons-beanutils"\
      },\
      {\
        "value": " : "\
      },\
      {\
        "field": "Artifact",\
        "value": "commons-beanutils"\
      },\
      {\
        "value": " : "\
      },\
      {\
        "field": "Version",\
        "value": "1.8.3"\
      }\
    ],  
    "name": "commons-beanutils"  
  }  
}
```

NOTES:

1. associatedPackageUrl, displayName, and componentIdentifier are null when a waiver is of type "all components" and "unknown components."

2. threatLevel should reflect the threat level of the policy violation.

## POST

### Create a New Waiver

```
POST /api/v2/policyWaivers/{ownerType: application|organization|repository|repository_container}/{ownerId}/{policyViolationId}
```

The scope of the waiver is determined by the parameters _ownerType_ and _ownerID_ . Possible values for _ownerType_ and _owner ID_ are application, organization, root organization, repository or repository container.To obtain the _policyViolationID_ , use [Policy Violation REST API](https://help.sonatype.com/en/policy-violation-rest-api.html "Policy Violation REST API") or [Report REST APIs](https://help.sonatype.com/en/report-rest-api.html "Report REST APIs").

Refer table below for the properties of the JSON object payload that can be sent with the POST request.

| Property | Default Value | Description |
| --- | --- | --- |
| matcherStrategy |  | Enumeration field.Possible values:EXACT_COMPONENT, ALL_COMPONENTS, ALL_VERSIONS |
| expiryTime | null | Optional, datetime to indicate expiry time of the waiver. |
| comment | null | Optional, describes the waiver. |
| applytoAllComponents | null | Boolean flag.Possible values true/false.<br>If ‘true’ the waiver will be applied to all components |
| waiverReasonId | null | The Id associated with the _Waiver Reason_.<br>Use the [Waiver Reason REST API](https://help.sonatype.com/en/waiver-reason-rest-api.html "Waiver Reason REST API") to view the available _Waiver Reasons_ and the corresponding Id. |

**Examples:**

1. JSON payload:

```
{
    "comment": "adding a waiver",
    "expiryTime": "2020-12-26T00:00:00.000+0000",
    "matcherStrategy": "ALL_COMPONENTS",
    "waiverReasonId": "5810538dfd311b6da17557360a10dc64"
}
```

2. Create a waiver with scope as root org

```
curl -u admin:admin123 -X POST http://localhost:8070/api/v2/policyWaivers/organization/ROOT_ORGANIZATION_ID/14f3e0fbc3884c21ac19bce74d7107c1
```

3. Create a waiver with a scope on a repository container

```
curl -u admin:admin123 -X POST http://localhost:8070/api/v2/policyWaivers/repository_container/REPOSITORY_CONTAINER_ID/8124f0f6f0544f7bbe65447bd3ca59ec
```

4. Create a waiver with a scope on a repository

```
curl -u admin:admin123 -X POST http://localhost:8070/api/v2/policyWaivers/repository/84a7c181efac4a94a33bd698f1dbbc33/30817d2b37cd47a3a6931effa1cd71bf
```

5. Create a waiver with scope as application having public ID `WebGoat-6.0.1` and policyViolationId `14f3e0fbc3884c21ac19bce74d7107c1`

```
curl -u admin:admin123 -X POST -H "Content-Type: application/json" -d '{"comment": "adding waiver for all components"}' http://localhost:8070/api/v2/policyWaivers/application/WebGoat-6.0.1/14f3e0fbc3884c21ac19bce74d7107c1
```

6. Create a time-based waiver

```
curl -u admin:admin123 -X POST -H "Content-Type: application/json" -d '{"comment": "adding a time-based waiver", "expiryTime": "2020-12-26T13:00:00.000+0000"}' http://localhost:8070/api/v2/policyWaivers/application/WebGoat-6.0.1/14f3e0fbc3884c21ac19bce74d7107c1
```

**Response:**

**HTTP status 204**: (No content) to indicate that the waiver has been successfully created.

## PUT to Update an Existing Waiver

```
PUT api/v2/policyWaivers/{ownerType: application|organization|repository|repository_manager|repository_container}/{ownerId}/{policyWaiverId}
```

The scope of the waiver is determined by the parameters _ownerType_ and _ownerID_ . Possible values for _ownerType_ and _owner ID_ are application, organization, root organization, repository or repository container.

Use the GET method above to retrieve the_policyWaiverID_.

Specify the _policyWaiverID_ in the PUT request, for the policy waiver to be updated.

**NOTE:** Updating _matcherStrategy_ is currently unsupported.

**Examples:**

1. Update a policy waiver with id 3458b438595740119043dd49a1a146df that applies to the root org.

```
curl -u admin:admin123 -X PUT http://localhost:8070/api/v2/policyWaivers/organization/ROOT_ORGANIZATION_ID/3458b438595740119043dd49a1a146df
```

2. JSON payload:

```
{
    "comment": "updating expiryTime",
    "expiryTime": "2025-12-26T00:00:00.000+0000",
    "matcherStrategy": "ALL_COMPONENTS",
    "waiverReasonId": "5810538dfd311b6da17557360a10dc64"
}
```

**Response:**

**HTTP status 204**: (No content) to indicate that the waiver has been successfully updated.

## DELETE

```
DELETE /api/v2/policyWaivers/{ownerType: application|organization|repository|repository_container}/{ownerId}/{policyWaiverId}
```

**Examples:**

1. Delete a policy waiver with id 3458b438595740119043dd49a1a146df that applies to the root org

```
curl -u admin:admin123 -X DELETE http://localhost:8070/api/v2/policyWaivers/organization/ROOT_ORGANIZATION_ID/3458b438595740119043dd49a1a146df
```

2. Delete a policy waiver with id d248b438595740119043dd49a1a146da for an application having application id 787c2e3dc8e745c48743926251eef00b:

```
curl -u admin:admin123 -X DELETE http://localhost:8070/api/v2/policyWaivers/application/787c2e3dc8e745c48743926251eef00b/d248b438595740119043dd49a1a146da
```

3. Delete a policy waiver with id 2338b438595740119043dd49a1a146dc in the repository container

```
curl -u admin:admin123 -X DELETE http://localhost:8070/api/v2/policyWaivers/repository_container/REPOSITORY_CONTAINER_ID/2338b438595740119043dd49a1a146dc
```

4. Delete a policy waiver with id e678b438595740119043dd49a1a14645 in the repository having id 6891f877e254428c991d9be640a32969:

```
curl -u admin:admin123 -X DELETE http://localhost:8070/api/v2/policyWaivers/repository/6891f877e254428c991d9be640a32969/e678b438595740119043dd49a1a14645
```

**Response:**

No response/content indicates that the waiver has been successfully deleted.

## Bulk Waivers API

### Overview

The Bulk Waivers API extends the Policy Waiver REST API to enable the creation of multiple policy waivers in a single request. This API is atomic (all-or-nothing), deduplicates duplicate violation IDs, validates all IDs before processing, and skips already-waived violations without error. A maximum of 1000 violation IDs can be processed per request.

**Note**

The Bulk Waivers feature supports bulk creation of waivers only. There is no “bulk waiver request” functionality; users cannot request waivers in bulk for later approval.

**Required permission:** `Waive Policy Violations`

- The `Waive Policy Violations` permission controls who can create and approve waivers directly.

- Users who have only the `Request Waiver` permission can submit individual waiver requests for approval but cannot create or approve waivers.

- The term “Waiver Permissions” refers to the set of permissions that control waiver actions; primarily the `Waive Policy Violations` and `Request Waiver` permissions. It specifically governs approval rights, not the ability to submit a waiver request.

- The Bulk Waivers feature is available only to users with the `Waive Policy Violations` permission. Users who have only the `Request Waiver` permission will not see the Bulk Waiver option in the IQ Server user interface.

- Approving a waiver is treated as a status change (from “requested” to “approved”) and does not require a separate API call.

| Action | Description | Permission Required |
| --- | --- | --- |
| Request a Waiver | Submits a waiver request for review and approval. | `Request Waiver` |
| Create a Waiver | Immediately creates and applies a waiver (if the user has approval rights). | `Waive Policy Violations` |
| Approve a Waiver | Approves a pending waiver request, changing its status to active. | `Waive Policy Violations` |
| Bulk Create Waivers | Creates multiple waivers in a single request. No bulk “request” operation exists. | `Waive Policy Violations` |

### Endpoint

```
POST /api/v2/policyWaivers/{ownerType}/{ownerId}
```

### Path Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `ownerType` | string | Yes | Scope of the waiver. One of: `application`, `organization`, `repository`, `repository_manager`, `repository_container`. |
| `ownerId` | string | Yes | ID that corresponds to `ownerType`(e.g., an application ID when `ownerType=application`). |

### Request Body

The request body must be a JSON object in the following format:

```
{
   "violationIds": ["violation-id-1", "violation-id-2"],
    "apiWaiverOptionsDTO": {
      "comment": "string",
      "matcherStrategy": "EXACT_COMPONENT ALL_VERSIONS",
      "expiryTime": "2023-12-31T23:59:59.000Z",
      "waiverReasonId": "string",
      "expireWhenRemediationAvailable": false
  }
}
```

### Request Body Properties

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `violationIds` | array<string> | Yes | List of policy violation IDs to waive. Maximum 1000 per request |
| `apiWaiverOptionsDTO` | object | Yes | Waiver configuration options (see below). |

#### Waiver Options Properties

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `comment` | string | No | `null` | Optional comment explaining the waiver. |
| `matcherStrategy` | string | Yes | - | `EXACT_COMPONENT`: applies to the exact component version.<br>`ALL_VERSIONS`: applies to all versions of the component. |
| `expiryTime` | string | No | `null` | Optional datetime when the waiver expires. |
| `waiverReasonId` | string | No | `null` | Optional Waiver Reason ID. |
| `expireWhenRemediationAvailable` | boolean | No | `false` | Automatically expire the waiver when a remediation becomes available. Only valid with `EXACT_COMPONENT`. |

### Example:

**Basic Bulk Waiver Creation Request:**

```
curl -X POST \
    "https://your-iq-server/api/v2/policyWaivers/application/myAppId" \
    -H "Content-Type: application/json" \
    -u username:password \
    -d '{
      "violationIds": [\
       "violation-id-1",\
       "violation-id-2",\
       "violation-id-3"\
      ],
      "apiWaiverOptionsDTO": {
       "comment": "Bulk waiver for development dependencies",
       "matcherStrategy": "EXACT_COMPONENT"
      }
    }
'
```

## Change history for Policy Waiver REST API v2

| Name | Type | Release supported from |
| --- | --- | --- |
| PUT | Method | Release 188 |
| waiverReasonId | Input parameter | Release 183 |
| reasonText | Response field | Release 183 |
| policyWaiverId | Input parameter | Release 147 |
| associatedPackageURL | Response field | Release 140 |
| matcherStrategy | Input parameter, Response field | Release 140 |
| creatorID, creatorName | Response fields | Release 131 |
| expirytime | Input parameter | Release 100 |
| DELETE | Method | Release 90 |
| GET | Method | Release 92 |
| applyToAllComponents | Input parameter | Deprecated, use matcherStrategy instead |

## Other Related REST APIs

1. [Applicable Waivers REST API](https://help.sonatype.com/en/applicable-waivers-rest-api.html "Applicable Waivers REST API")

2. [Component Waivers REST API](https://help.sonatype.com/en/component-waivers-rest-api.html "Component Waivers REST API")

3. [Stale Waivers REST API](https://help.sonatype.com/en/stale-waivers-rest-api.html "Stale Waivers REST API")

4. [Transitive Waivers REST API](https://help.sonatype.com/en/transitive-waivers-rest-api.html "Transitive Waivers REST API")
