Add or Edit Compliance Policy Exceptions through the Lacework API
This method requires that you obtain the policy exception configuration before creating an exception. The exception configuration varies from policy to policy, so this must be known before creating an exception for a given policy.
Generate your API Access Key and Token before attempting to create exceptions.
The access token is represented as $AccountAdminToken
within the curl command examples shown in this article.
- Manual Policies cannot have exceptions applied to them.
- Once an exception is added or edited, it will not take effect until the next compliance assessment run is complete.
Add Compliance Policy Exceptions
1. Get the Policy Exception Configuration
Use the Policies Details endpoint to get all the information on a given policy:
GET https://YourLacework.lacework.net/api/v2/Policies/{policyId}
curl -X GET -H "Authorization: Bearer $AccountAdminToken" -H "Content-Type: application/json" "https://myAccount.lacework.net/api/v2/Policies/lacework-global-87"
From the output, you need the exceptionConfiguration
section as that contains the required fieldKey
values for creating the exception.
If you have jq installed, you can adjust the example above to only print the exceptionConfiguration
section:
curl -X GET -H "Authorization: Bearer $AccountAdminToken" -H "Content-Type: application/json" "https://myAccount.lacework.net/api/v2/Policies/lacework-global-87" | jq '.data.exceptionConfiguration'
Alternatively, if you have the Lacework CLI installed, you can use the Raw Lacework API to get the exceptionConfig
for a given policy:
lacework api get /api/v2/Policies/<policy-id> | jq '.data.exceptionConfiguration'
Exception Configuration Examples
- AWS
- Google Cloud
- Azure
- OCI
- Kubernetes
"exceptionConfiguration": {
"constraintFields": [
{
"dataType": "String",
"fieldKey": "accountIds",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "regionNames",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "resourceNames",
"multiValue": false
},
{
"dataType": "KVTagPair",
"fieldKey": "resourceTags",
"multiValue": true
}
]
},
"exceptionConfiguration": {
"constraintFields": [
{
"dataType": "Number",
"fieldKey": "organizations",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "projects",
"multiValue": true
},
{
"dataType": "KVTagPair",
"fieldKey": "resourceLabel",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "resourceName",
"multiValue": false
}
]
},
"exceptionConfiguration": {
"constraintFields": [
{
"dataType": "String",
"fieldKey": "azureResourceGroup",
"multiValue": false
},
{
"dataType": "String",
"fieldKey": "regionNames",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "resourceName",
"multiValue": false
},
{
"dataType": "KVTagPair",
"fieldKey": "resourceTags",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "subscriptions",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "tenants",
"multiValue": true
}
]
},
"exceptionConfiguration": {
"constraintFields": [
{
"dataType": "String",
"fieldKey": "compartmentIds",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "nestedCompartmentIds",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "regionNames",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "resourceName",
"multiValue": false
}
]
},
- EKS
"exceptionConfiguration": {
"constraintFields": [
{
"dataType": "String",
"fieldKey": "k8sAccountIds",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "k8sClusterNames",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "k8sNamespaces",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "k8sRegionNames",
"multiValue": true
},
{
"dataType": "KVTagPair",
"fieldKey": "k8sResourceLabels",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "k8sResourceTypes",
"multiValue": true
},
{
"dataType": "String",
"fieldKey": "k8sClusterResourceNames",
"multiValue": false
}
]
},
2. Create the JSON Payload for the Exception
Once you have the exception configuration for the policy, create the JSON payload for the policy exception based on the fieldKey
values.
AND vs OR
The following operator logic applies in these circumstances:
Multiple exception criteria in a single exception = AND
For example:
- A policy exception is created for an Amazon S3 bucket resource with criteria that includes a
resourceNames
andresourceTags
field. - The exception applies to a bucket that has a matching resource name and resource tag.
- A policy exception is created for an Amazon S3 bucket resource with criteria that includes a
Multiple policy exceptions for a single policy = OR
For example:
- A policy exception is created for an Amazon S3 bucket resource with criteria of a
resourceNames
. - A second policy exception is created with criteria of
resourceTags
. - The exception applies to any bucket found that has a matching resource name defined in the first exception or resource tags defined in the second exception.
- A policy exception is created for an Amazon S3 bucket resource with criteria of a
Data Types and Wildcards
Use the following sections to understand the expected format for each fieldKey
value.
- AWS
- Google Cloud
- Azure
- OCI
- Kubernetes
JSON fieldKey | UI Equivalent | Data Type | Wildcards accepted? |
---|---|---|---|
accountIds | Account Ids | String | Yes |
regionNames | Region Names | String | Yes |
resourceNames | User Name, Policy Name, Bucket Name, Volume Id, RDS Database, Trail Name, Key Id/Alias, VPC Id, Network ACL ARN, Group Id/Name | String | Yes |
resourceTags | Resource Tags | Key Value | No |
JSON fieldKey | UI Equivalent | Data Type | Wildcards accepted? |
---|---|---|---|
organizations | Organizations (IDs) | Number | Yes |
projects | Projects (IDs) | String | Yes |
resourceName | Resource Name | String | Yes |
resourceLabel | Resource Label | Key Value | No |
JSON fieldKey | UI Equivalent | Data Type | Wildcards accepted? |
---|---|---|---|
tenants | Tenants | String | Yes |
subscriptions | Subscriptions | String | Yes |
regionNames | Regions | String | Yes |
azureResourceGroup | Resource Group | String | Yes |
resourceName | Resource Name | String | Yes |
resourceTags | Resource Tags | Key Value | No |
JSON fieldKey | UI Equivalent | Data Type | Wildcards accepted? |
---|---|---|---|
compartmentIds | Compartment IDs without descendants | String | Yes |
nestedCompartmentIds | Compartment IDs with descendants | String | Yes |
regionNames | Regions | String | Yes |
resourceName | Resource Name | String | Yes |
- EKS
JSON fieldKey | UI Equivalent | Data Type | Wildcards accepted? |
---|---|---|---|
k8sAccountIds or accountIds | Account Ids | String | Yes |
k8sClusterNames | Cluster Names | String | Yes |
k8sRegionNames or regionNames | Region Names | String | Yes |
k8sResourceTypes | Resource Types | String | Yes |
k8sNamespaces | Namespaces | String | Yes |
k8sResourceLabels | Resource Labels | Key Value | No |
k8sClusterResourceNames or resourceNames | Various (for example: Cluster Role Binding Name) | String | Yes |
k8sClusterPodContainerImageNames | Image Names | String | Yes |
resourceTags | Resource Tags or Tags | Key Value | No |
You can simply enter a registry when creating an exception for k8sClusterPodContainerImageNames
.
{
"fieldKey": "k8sClusterPodContainerImageNames",
"fieldValues": [
"*public.ecr.aws*",
"*.ecr.*.amazonaws.com/*"
]
},
Wildcard Usage
You can use wildcards to match and exclude singular or multiple resources for field values that accept wildcards.
For example, if you wanted to exclude the AWS resource mySecurityGroup_sg
, you can exclude it using wildcards with one of the following examples:
AWS Example 1
{
"fieldKey": "resourceNames",
"fieldValues": [
"*_sg"
]
},
AWS Example 2
{
"fieldKey": "resourceNames",
"fieldValues": [
"*SecurityGroup*"
]
},
AWS Example 3
{
"fieldKey": "resourceNames",
"fieldValues": [
"mySecurityGroup*"
]
},
For Google Cloud, if you wanted to exclude the resource //storage.googleapis.com/myBucketName
, the following example will work:
Google Cloud Example
{
"fieldKey": "resourceName",
"fieldValues": [
"*myBucketName"
]
},
JSON Payload Examples
- AWS
- Google Cloud
- Azure
- OCI
- Kubernetes
Do not use the ARN format when providing the resourceNames
value for policy exceptions.
For example, using arn:aws:s3:::mys3bucket
is not accepted, as only mys3bucket
should be provided.
Based on the policy type, the correct type of resource should be provided when entering the fieldValues
for resourceNames
(if you are not using a "*" wildcard).
For example, the lacework-global-87 policy requires one or more security groups in the fieldValues
entry for resourceNames
:
{
"description": "All traffic is allowed through this security group",
"constraints": [
{
"fieldKey": "accountIds",
"fieldValues": [
"*"
]
},
{
"fieldKey": "regionNames",
"fieldValues": [
"us-west-2"
]
},
{
"fieldKey": "resourceNames",
"fieldValues": [
"mySecurityGroup_sg"
]
},
{
"fieldKey": "resourceTags",
"fieldValues": [
{
"key": "mykey",
"value": "myvalue"
}
]
},
]
}
If accountIds
or regionNames
are not included in the JSON payload and are part of the exception criteria for a policy, the default fieldValues
would be *
.
This would mean all integrated accounts and/or regions would be included in the exception.
The resourceName
field value must be in the full resource name format unless you are using wildcards.
Additionally, the organizations and projects fields should be in ID format.
Based on the policy type, the correct type of resource should be provided when entering the fieldValues
for resourceName
(if you are not using a "*" wildcard).
For example, the lacework-global-270 policy requires one or more Cloud Storage buckets in the fieldValues
entry for resourceName
:
{
"description": "Allow public access to this cloud storage bucket",
"constraints": [
{
"fieldKey": "organizations",
"fieldValues": [
"*"
]
},
{
"fieldKey": "projects",
"fieldValues": [
"*"
]
},
{
"fieldKey": "resourceName",
"fieldValues": [
"//storage.googleapis.com/myBucketName"
]
},
{
"fieldKey": "resourceLabel",
"fieldValues": [
{
"key": "mykey",
"value": "myvalue"
}
]
},
]
}
Based on the policy type, the correct type of resource should be provided when entering the fieldValues
for resourceName
(if you are not using a "*" wildcard).
For example, the lacework-global-617 policy requires one or more storage accounts in the fieldValues
entry for resourceName
:
{
"description": "Exclude this storage account from trusting Azure services access",
"constraints": [
{
"fieldKey": "tenants",
"fieldValues": [
"*"
]
},
{
"fieldKey": "subscriptions",
"fieldValues": [
"*"
]
},
{
"fieldKey": "azureResourceGroup",
"fieldValues": [
"*"
]
},
{
"fieldKey": "regionNames",
"fieldValues": [
"centralus"
]
},
{
"fieldKey": "resourceName",
"fieldValues": [
"mystorageaccount"
]
},
{
"fieldKey": "resourceTags",
"fieldValues": [
{
"key": "mykey",
"value": "myvalue"
}
]
},
]
}
- For
compartmentIds
, this entry should only contain Compartment IDs that have no nested subcompartments. The exception will only apply to this compartment. - For
nestedCompartmentIds
, this entry should only contain Compartment IDs that have nested subcompartments (for example, the tenancy / root compartment). The exception will apply to this compartment and any subcompartments therein.
Based on the policy type, the correct type of resource should be provided when entering the fieldValues
for resourceName
(if you are not using a "*" wildcard).
For example, the lacework-global-209 policy requires one or more block volumes in the fieldValues
entry for resourceName
:
{
"description": "Block volume does not require attaching to instance",
"constraints": [
{
"fieldKey": "compartmentIds",
"fieldValues": [
"*"
]
},
{
"fieldKey": "nestedCompartmentIds",
"fieldValues": [
"*"
]
},
{
"fieldKey": "regionNames",
"fieldValues": [
"oci-global"
]
},
{
"fieldKey": "resourceName",
"fieldValues": [
"myblockvolume01"
]
},
]
}
- EKS
- Example 1
- Example 2
Based on the policy type, the correct type of resource should be provided when entering the fieldValues
for k8sClusterResourceNames
(if you are not using a "*" wildcard).
For example, the lacework-global-335 policy requires one or more Cluster Role Binding Names in the fieldValues
entry for k8sClusterResourceNames
:
{
"description": "Exclude this cluster role binding from using default service accounts",
"constraints": [
{
"fieldKey": "k8sAccountIds",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sClusterNames",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sNamespaces",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sRegionNames",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sResourceTypes",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sResourceLabels",
"fieldValues": [
{
"key": "mykey",
"value": "myvalue"
}
]
},
{
"fieldKey": "k8sClusterResourceNames",
"fieldValues": [
"my-cluster-role-binding"
]
},
]
}
Some policies do not require a specific resource name and apply generally to Kubernetes configuration.
For example, the lacework-global-320 policy can have an exception that applies to all Kubernetes clusters in a specific region:
{
"description": "Allow Kubernetes clusters in the us-west-2 region to accept anonymous authentication requests",
"constraints": [
{
"fieldKey": "k8sAccountIds",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sClusterNames",
"fieldValues": [
"*"
]
},
{
"fieldKey": "k8sRegionNames",
"fieldValues": [
"us-west-2"
]
},
{
"fieldKey": "k8sResourceTypes",
"fieldValues": [
"*"
]
},
]
}
3. Add the Policy Exception
Use the Create Policy Exceptions endpoint when adding new policy exceptions:
POST /api/v2/Exceptions?policyId={policyId}
In the example below, the JSON payload exists as a file named myexceptionpayload.json
in the local directory:
curl -X POST -H "Authorization: Bearer $AccountAdminToken" -H "Content-Type: application/json" --data @myexceptionpayload.json "https://myAccount.lacework.net/api/v2/Exceptions?policyId=lacework-global-87"
The command is successful if a 201
response is received.
Edit Compliance Policy Exceptions
Editing an existing Compliance policy exception through the API is similar to adding a new policy exception. A different endpoint will be used, and the existing policy exception ID must also be obtained.
Edit your existing JSON Payload file or create a new one with the updated details.
Use the List All Policy Exceptions endpoint to find all exceptions applied to a policy:
GET /api/v2/Exceptions?policyId={policyId}
Example for lacework-global-87curl -X GET -H "Authorization: Bearer $AccountAdminToken" -H "Content-Type: application/json" "https://myAccount.lacework.net/api/v2/Exceptions?policyId=lacework-global-87"
Find the
exceptionId
that you want to update as this will be used in the next step.Update policy exceptions by using the Update Policy Exceptions endpoint:
PATCH /api/v2/Exceptions/{exceptionId}?policyId={policyId}
In the example below, the JSON payload exists as a file named
myupdatedexceptionpayload.json
in the local directory and the existing policy exception ID ismyExceptionId
:Example for lacework-global-87curl -X PATCH -H "Authorization: Bearer $AccountAdminToken" -H "Content-Type: application/json" --data @myupdatedexceptionpayload.json "https://myAccount.lacework.net/api/v2/Exceptions/myExceptionId?policyId=lacework-global-87"
The command is successful if a
200
response is received.