Execute a Query On Demand
This topic describes how to execute a query on demand. On-demand execution differs from execution by ID in that the query you want to execute does not have to already exist in your Lacework instance. On-demand execution is useful for repeatedly refining a query until you get the desired results.
All Lacework endpoints require an API access (bearer) token to be specified when you invoke the endpoint. If you already have a secret key, you can use the POST /api/v2/access/tokens
endpoint to generate an access token. For details, see API Access Keys and Tokens.
Configure the Query
This example query checks for unrestricted ingress to TCP port 445.
{
source {
LW_CFG_AWS_EC2_SECURITY_GROUPS a,
array_to_rows(a.RESOURCE_CONFIG:IpPermissions) as (ip_permissions),
array_to_rows(ip_permissions:IpRanges) as (ip_ranges)
}
filter {
ip_permissions:IpProtocol = 'tcp'
and ip_permissions:FromPort = 445
and ip_permissions:ToPort = 445
and ip_ranges:CidrIp = '0.0.0.0/0'
}
return distinct {
ACCOUNT_ALIAS,
ACCOUNT_ID,
ARN as RESOURCE_KEY,
RESOURCE_REGION,
RESOURCE_TYPE,
SERVICE
}
}
The above is the content of the queryText
, which you use later with the POST endpoint.
Configure the example using the following guidelines:
source
: Specify the datasource(s) where the query looks for data. The example specifiesLW_CFG_AWS_EC2_SECURITY_GROUPS
. To get a list of all available datasources, use theGET /api/v2/Datasources
endpoint.filter
: Specify the query's records of interest. The example filters the records available inLW_CFG_AWS_EC2_SECURITY_GROUPS
.return
: List the fields the query exposes. The example adds thedistinct
modifier, which returns deduped event details because there may be unwanted duplicates among result records.
Format for Use by POST
After you configure the query, you must format it for use by the POST /api/v2/Queries
endpoint. Remove all line breaks from the queryText
. The queryText
shouldn't include a query ID.
"queryText": "{source {LW_CFG_AWS_EC2_SECURITY_GROUPS a, array_to_rows(a.RESOURCE_CONFIG:IpPermissions) as (ip_permissions), array_to_rows(ip_permissions:IpRanges) as (ip_ranges)} filter {ip_permissions:IpProtocol = 'tcp' and ip_permissions:FromPort = 445 and ip_permissions:ToPort = 445 and ip_ranges:CidrIp = '0.0.0.0/0'} return distinct {ACCOUNT_ALIAS, ACCOUNT_ID, ARN as RESOURCE_KEY, RESOURCE_REGION, RESOURCE_TYPE, SERVICE}}"
Notice of Deprecation
Including the query ID in the queryText
is now deprecated. Lacework recommends omitting the query ID from the queryText
.
Execute the Query
Execute this query using the
POST /api/v2/Queries/execute
endpoint. Using thebody
input parameter, pass in the following:queryText
- LQL query arguments (
StartTimeRange
andEndTimeRange
)
Using Postman, the request body would be similar to the following:
Example{
"query": {
"queryText": "{source {LW_CFG_AWS_EC2_SECURITY_GROUPS a, array_to_rows(a.RESOURCE_CONFIG:IpPermissions) as (ip_permissions), array_to_rows(ip_permissions:IpRanges) as (ip_ranges)} filter {ip_permissions:IpProtocol = 'tcp' and ip_permissions:FromPort = 445 and ip_permissions:ToPort = 445 and ip_ranges:CidrIp = '0.0.0.0/0'} return distinct {ACCOUNT_ALIAS, ACCOUNT_ID, ARN as RESOURCE_KEY, RESOURCE_REGION, RESOURCE_TYPE, SERVICE}}"
},
"arguments": [
{"name": "StartTimeRange", "value": "2022-07-10T00:00:00.000Z"},
{"name": "EndTimeRange", "value": "2022-07-11T00:00:00.000Z"}
]
}Here is some sample data that the query could return.
{
"data": [
{
"ACCOUNT_ALIAS": "aaa-bb",
"ACCOUNT_ID": "111",
"RESOURCE_KEY": "arn:aws:ec2:sa-east-1:111:security-group/sg-222",
"RESOURCE_REGION": "sa-east-1",
"RESOURCE_TYPE": "ec2:security-group",
"SERVICE": "ec2"
}
]
}You can use the returned data to refine the query if desired and execute it again.
Next Steps
After you refine and execute the query to get the desired results, create the query in your Lacework instance to allow a policy to use it. Thus far, you have only been executing the query. Use the POST /api/v2/Queries
endpoint to create the query.