Investigating cloud metadata with JPQL (JSON Path Query Language)
All example queries below use GetCredentialReportStream (IAM) and EC2 streams and have been validated against the live catalog.
Query Template | Stream Filter Function (FILTER) | Boolean Logic | Comparison Operators | Membership Operators | Text / Pattern Operators | Null and Presence Operators | IP and Network Operators | Special Operators | Array Modifiers | Namespace Functions | Join Queries | Literal Values & AWS-Specific Strings
Query Template
Use this base pattern for all TotalCloud queries:
Basic structure:
SELECT <alias> FROM cloud.resource WHERE (<filters>) AS <alias>
Each query must include FROM cloud.resource, a $.streamName filter in the WHERE clause, and an alias defined with AS.
SELECT must contain exactly one alias.
Example:
SELECT r FROM cloud.resource WHERE ($.streamName = "GetCredentialReportStream" AND $.data.user = "admin") AS r
Stream Filter Function (FILTER)
The FILTER function defines the specific subset of data that a control should evaluate before applying its compliance checks. It narrows the scope by selecting only the relevant records from all collected data and then running the actual compliance evaluation on them. Any data that does not match the filter criteria is excluded and is therefore not considered compliant or non-compliant (No pass or fail result for that resource would be returned). This ensures that the control evaluates only the intended resources and produces accurate, relevant results.
For example, if you want to check 'Ensure no root user account access key exists', which is applicable to only root user accounts, you can first use FILTER to restrict the evaluation to root user accounts and then apply the compliance condition:
SELECT r FROM cloud.resource
WHERE (FILTER("GetCredentialReportStream", ($.data.user = "<root_account>"))
AND ($.data.access_key_1_active = "true"
OR $.data.access_key_2_active = "true"))
AS r
In this case, only user accounts with value as "<root_account>" are considered in scope, and among those, the control checks whether the access key exists.
Boolean Logic
Use AND, OR, and NOT to combine predicates. The query engine processes them as follows:
AND - Both sides are classified independently. Predicates that can be pushed to Elasticsearch are evaluated there; any remaining predicates are evaluated in DuckDB.
OR - If any branch of an OR expression is residual (cannot be pushed to Elasticsearch), the entire OR expression is evaluated in DuckDB.
NOT - Can be pushed to Elasticsearch only when the inner expression is fully pushable.
Examples:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.access_key_1_active = true
AND NOT $.data.user = "<root_account>") AS r
<root_account> is a literal string value used by AWS in the IAM Credential Report. The user column contains the exact text <root_account> for the root user — it is not a placeholder or macro that gets substituted at runtime. See Literal Values & AWS-Specific Strings section for details.
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND ($.data.access_key_1_last_used_region = "us-east-1"
OR $.data.access_key_1_last_used_region = "eu-west-1")) AS r
Comparison Operators
Use comparison operators to match field values exactly or by range. Numeric and date fields support range operators (>, >=, <, <=, BETWEEN). The = and != operators are supported on text, numeric, boolean, and date fields.
| Operator | Description | Syntax |
|---|---|---|
|
|
Exact equality. Case-sensitive for text; numeric equality for numbers and dates. |
|
|
|
Not equal. Inverse of EQ. |
|
|
|
Greater than. Numeric and date fields only. |
|
|
|
Greater than or equal. Numeric and date fields only. |
|
|
|
Less than. Numeric and date fields only. |
|
|
|
Less than or equal. Numeric and date fields only. |
|
|
|
Inclusive range check. Numeric and date fields only. |
|
Find an IAM user by exact name:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream" AND $.data.user = "admin") AS r
Find IAM users that are not the root account:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream" AND $.data.user != "<root_account>") AS r
Find security groups with ports in a specific range using > and <=:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2SecurityGroupsStream"
AND $.data.IpPermissions[*].FromPort > 1023
AND $.data.IpPermissions[*].ToPort <= 65535) AS r
Find security groups with ports in a well-known range using BETWEEN:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2SecurityGroupsStream"
AND $.data.IpPermissions[*].FromPort BETWEEN 8000 AND 9000) AS r
Membership Operators
Use membership operators to test whether a field value belongs to a set of values. Array-aware operators such as ANYOF, NONEOF, SUBSETOF, and INTERSECTS are designed for array-typed fields.
|
Operator |
Description |
Syntax |
|---|---|---|
|
|
Value is one of the listed values. Works like SQL IN. |
|
|
|
Field value matches any of the given values. Array-aware. |
|
|
|
Field value matches none of the given values. Inverse of ANYOF. |
|
|
|
Checks if the field value is a member of the given set. |
|
|
|
All elements of the array are in the given set. DuckDB. |
|
|
|
Array has at least one element in common with set. DuckDB. |
|
Find IAM users whose access key was last used in specific regions (IN):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.access_key_1_last_used_region IN ("us-east-1", "us-west-2")) AS r
Find EC2 instances of specific types (ANYOF):
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND $.data.Instances[*].InstanceType ANYOF ("t2.micro", "t3.micro")) AS r
Find EC2 instances that are not specific types (NONEOF):
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND $.data.Instances[*].InstanceType NONEOF ("t2.micro", "t3.micro")) AS r
Find IAM roles whose managed policies are fully within a safe set (SUBSETOF):
SELECT r FROM cloud.resource
WHERE ($.streamName = "AccountAuthDetailRoleStream"
AND $.data.AttachedManagedPolicies[*].PolicyName SUBSETOF ("ReadOnlyAccess", "ViewOnlyAccess")) AS r
Find EC2 instances attached to specific security groups (INTERSECTS):
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND $.data.Instances[*].SecurityGroups[*].GroupId INTERSECTS ("sg-00001", "sg-00002")) AS r
Text / Pattern Operators
Use text operators to search string fields by substring, prefix, suffix, wildcard, or regular expression. These operators are not valid on numeric or date fields. CONTAINS, SUFFIX, and LIKE are always evaluated in DuckDB. PREFIX and MATCHES_GLOB may be pushed to Elasticsearch for structured keyword fields.
|
Operator |
Description |
Syntax |
|---|---|---|
|
|
Substring match. Case-sensitive. |
|
|
|
Value starts with the given prefix. |
|
|
|
Value ends with the given suffix. Always DuckDB. |
|
|
|
Regular expression match. Uses /regex/ literal syntax. |
|
|
|
SQL-style wildcard. |
|
|
|
Glob-style wildcard. |
|
Find IAM users whose ARN contains a specific substring (CONTAINS):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.arn CONTAINS "admin") AS r
Find IAM users whose ARN starts with a specific prefix (PREFIX):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.arn PREFIX "arn:aws:iam") AS r
Find IAM users whose username ends with a specific suffix (SUFFIX):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.user SUFFIX "_admin") AS r
Find IAM users matching a regular expression (MATCHES):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.user MATCHES /admin[0-9]+/) AS r
MATCHES uses Lucene regex syntax (ES). Lucene does NOT support lookaheads (?=...) or (?!...). Avoid patterns ending in */ as they trigger the harmful-input filter; use .+ instead of .* when the regex ends with a wildcard.
Find IAM users using a SQL-style wildcard (LIKE):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.user LIKE "admin%") AS r
Find IAM users using a glob wildcard (MATCHES_GLOB):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.user MATCHES_GLOB "admin*") AS r
Null and Presence Operators
Use these operators to check whether a field exists, is null, or is an empty array or string. EXISTS is pushable to Elasticsearch for most field types. IS NULL and IS EMPTY are always evaluated in DuckDB.
|
Operator |
Description |
Syntax |
|---|---|---|
|
|
Field is present and not null. |
|
|
|
Field is null or missing. |
|
|
|
Field is an empty array or empty string. |
|
Find IAM users whose access key 1 has been used (EXISTS):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.access_key_1_last_used_date EXISTS) AS r
Find IAM users who have never used their password (IS NULL):
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND $.data.password_last_used IS NULL) AS r
Find IAM roles with no managed policies attached (IS EMPTY):
SELECT r FROM cloud.resource
WHERE ($.streamName = "AccountAuthDetailRoleStream"
AND $.data.AttachedManagedPolicies IS EMPTY) AS r
IP and Network Operators
Use IP operators to filter resources by IP address or port. These operators work on both scalar and array IP fields and are always evaluated in DuckDB using auto-registered macros. All arguments must be enclosed in parentheses.
|
Operator |
Description |
Syntax |
|---|---|---|
|
|
IP address falls within the given CIDR block. |
|
|
|
IP address falls within an inclusive range defined by a lower and upper bound. |
|
|
|
Port number falls within a numeric range. |
|
Find EC2 instances with a private IP in the corporate network range (IN_CIDR):
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND $.data.Instances[*].PrivateIpAddress IN_CIDR ("10.0.0.0/8")) AS r
Find EC2 instances with a private IP within a specific host range (IN_IP_RANGE):
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND $.data.Instances[*].PrivateIpAddress IN_IP_RANGE ("10.0.0.1", "10.0.0.255")) AS r
Find security group rules with ports in the non-privileged range (IN_PORT_RANGE):
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2SecurityGroupsStream"
AND $.data.IpPermissions[*].FromPort IN_PORT_RANGE (1024, 65535)) AS r
Special Operators
These operators apply computed values or namespace-qualified functions as predicates. They are always evaluated in DuckDB.
|
Operator |
Description |
Syntax |
|---|---|---|
|
|
Counts whitespace-delimited words in the field value and compares to a number. |
|
|
|
Computes age of a date field in days from today. Use via the |
|
|
Namespace function predicate |
A namespace-qualified function call used as a predicate. See Namespace Functions for all available functions. |
|
Find IAM users created more than 90 days ago:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND _DateTime.ageInDays($.data.user_creation_time) > 90) AS r
Find security groups whose description has more than 3 words:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2SecurityGroupsStream"
AND NUMBER OF WORDS($.data.Description) > 3) AS r
Find SNS topics with a safe access policy:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetTopicAttributeStream"
AND _AWSSNS.isSnsAccessPolicySafe($.data.Policy) = true) AS r
Array Modifiers
Array modifiers prefix an operator to control how it applies across the elements of an array field. Use ANY and NONE for Elasticsearch-pushable checks; use ALL and SIZE for DuckDB-evaluated checks.
|
Modifier |
Engine |
Description |
Example |
|---|---|---|---|
|
|
ES |
True if any array element satisfies the predicate. |
|
|
|
ES |
True if no array element satisfies the predicate. |
|
|
|
DuckDB |
True if all array elements satisfy the predicate. |
|
|
|
DuckDB |
Applies a numeric comparison to the count of array elements. |
|
Namespace Functions
Namespace functions are called using the syntax _Namespace.functionName(args) and are always evaluated in DuckDB. Use them as predicates in your WHERE clause.
_DateTime - Date and Time Functions
Use _DateTime functions to filter resources by the age or relative date of a date field.
|
Function |
Description |
|---|---|
|
|
Returns the number of days elapsed since the date field value. |
|
|
Returns the number of months elapsed since the date field value. |
|
|
Returns the number of years elapsed since the date field value. |
|
|
Returns the number of days between two date fields. |
|
|
Returns the current date as a literal value for use in comparisons. |
Find IAM users created more than 90 days ago:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND _DateTime.ageInDays($.data.user_creation_time) > 90) AS r
Find IAM users created more than 6 months ago:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetCredentialReportStream"
AND _DateTime.ageInMonths($.data.user_creation_time) > 6) AS r
Find EC2 instances launched more than 90 days ago:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND _DateTime.ageInDays($.data.Instances[*].LaunchTime) > 90) AS r
_IPAddress - IP Address Functions
Use _IPAddress functions to filter resources by whether an IP address or array of IP addresses falls within a CIDR block or a defined range.
|
Function |
Description |
|---|---|
|
|
True if the IP address is within the given CIDR block. |
|
|
True if all IP addresses in an array field are within the CIDR block. |
|
|
True if any IP address in an array field falls outside the CIDR block. |
|
|
True if the IP address falls within the inclusive range defined by low and high bounds. |
Find EC2 instances with a private IP in the corporate network:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2InstancesStream"
AND _IPAddress.inCIDRRange($.data.Instances[*].PrivateIpAddress, "10.0.0.0/8") = true) AS r
Find security groups with any IP rule outside the allowed CIDR range:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2SecurityGroupsStream"
AND _IPAddress.areAnyOutsideCIDRRange($.data.IpPermissions[*].IpRanges[*].CidrIp, "10.0.0.0/8") = true) AS r
_Port - Port Functions
Use _Port functions to filter resources by whether a port number falls within a defined range.
Find security group rules with high-number ports open:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeEC2SecurityGroupsStream"
AND _Port.inRange($.data.IpPermissions[*].FromPort, 1024, 65535) = true) AS r
_AWSSNS - AWS SNS Functions
Use _AWSSNS functions to evaluate the safety of SNS topic access policies.
Find SNS topics with a safe access policy:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetTopicAttributeStream"
AND _AWSSNS.isSnsAccessPolicySafe($.data.Policy) = true) AS r
Find SNS topics whose access policy is publicly exposed:
SELECT r FROM cloud.resource
WHERE ($.streamName = "GetTopicAttributeStream"
AND _AWSSNS.isSnsAccessPolicySafe($.data.Policy) = false) AS r
_AWSVPC - AWS VPC Functions
Use _AWSVPC functions to evaluate VPC security group rules, network ACLs, and VPC endpoint policies. These functions are AWS-only — they have no Azure equivalent.
|
Function |
Description |
|---|---|
|
|
Checks if any inbound rule allows traffic from the specified CIDR block (e.g., "0.0.0.0/0") on the given port range and protocol. |
|
|
Checks if any inbound rule references another security group as a traffic source. |
|
|
Checks if any inbound rule references a managed prefix list as a traffic source. |
|
|
Evaluates whether a VPC Gateway Endpoint's policy document is safe (not overly permissive). |
Find VPC Gateway Endpoints with a safe policy:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeVpcEndpointsStream"
AND _AWSVPC.isGatewayEndpointPolicySafe($.data.PolicyDocument) = true) AS r
Placeholders — CID 41, 42
"security-group-id" and "prefix-list-id" are actual placeholders that should be replaced with real values (e.g., "sg-0a1b2c3d4e5f67890", "pl-02dc3456") at query time. If you don't need to check by security group or prefix list, you can remove those branches and keep only the IP check.
|
Value |
Used In |
Meaning |
|---|---|---|
|
|
CID 41, 42 — |
Placeholder for an actual security group ID (e.g., sg-0a1b2c3d4e5f67890). Replace with a real SG ID or remove the branch. |
|
|
CID 41, 42 — |
Placeholder for an actual prefix list ID (e.g., pl-02dc3456). Replace with a real PL ID or remove the branch. |
CID 41 — Unrestricted SSH (port 22) ingress via Security Groups
Stream: DescribeSecurityGroupsStream
Type indicators: "security-group-id" (in evaluateBySG), "prefix-list-id" (in evaluateByPL)
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeSecurityGroupsStream"
AND ((_AWSVPC.evaluateByIP($.data.IpPermissions, 22, 22, "tcp", "0.0.0.0/0") = true)
OR (_AWSVPC.evaluateBySG($.data.IpPermissions, "sg-0a1b2c3d4e5f67890", 22, 22, "tcp") = true)
OR (_AWSVPC.evaluateByPL($.data.IpPermissions, 22, 22, "tcp", "pl-02dc3456") = true)))
AS r
CID 42 — Unrestricted RDP (port 3389) ingress via Security Groups
Stream: DescribeSecurityGroupsStream
Type indicators: "security-group-id" (in evaluateBySG), "prefix-list-id" (in evaluateByPL)
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeSecurityGroupsStream"
AND (_AWSVPC.evaluateByIP($.data.item.ipPermissions, 3389, 3389, "tcp", "0.0.0.0/0") = true
OR _AWSVPC.evaluateBySG($.data.item.ipPermissions, "sg-0a1b2c3d4e5f67890", 3389, 3389, "tcp") = true
OR _AWSVPC.evaluateByPL($.data.item.ipPermissions, 3389, 3389, "tcp", " pl-02dc3456") = true)) AS r
If there is no need of SG or PL in the query it can also be used as below:
SELECT r FROM cloud.resource
WHERE ($.streamName = "DescribeSecurityGroupsStream"
AND ((_AWSVPC.evaluateByIP($.data.IpPermissions, 22, 22, "tcp", "0.0.0.0/0") = true)))
AS r
Join Queries
Use a JOIN to correlate resources across two streams. Specify a join key in the ON clause using EQ. Use a HAVING clause to filter join results by the count of matching related records.
SELECT must contain exactly one alias
Basic join syntax:
SELECT <alias>
FROM cloud.resource WHERE (<filters_a>) AS a
JOIN cloud.resource WHERE (<filters_b>) AS b
ON (a.$.path EQ b.$.path)
Find application load balancers that have at least one HTTP listener:
SELECT alb
FROM cloud.resource WHERE ($.streamName = "GetELBV2ListStream"
AND $.data.type = "application") AS alb
JOIN cloud.resource WHERE ($.streamName = "GetElbV2ListenersStream"
AND $.data.Protocol ANYOF ("HTTP")) AS lsn
ON (alb.$.data.loadBalancerArn EQ lsn.$.data.loadBalancerArn)
Use HAVING COUNT to filter ALBs with two or more HTTP or HTTPS listeners:
SELECT alb
FROM cloud.resource WHERE ($.streamName = "GetELBV2ListStream"
AND $.data.type = "application") AS alb
JOIN cloud.resource WHERE ($.streamName = "GetElbV2ListenersStream"
AND $.data.Protocol ANYOF ("HTTP", "HTTPS")) AS lsn
ON (alb.$.data.loadBalancerArn EQ lsn.$.data.loadBalancerArn)
HAVING COUNT(lsn) >= 2
Find RDS SQL Server instances where rds.force_ssl is not enabled (JOIN with multiple ON conditions using CONTAINS):
SELECT x
FROM cloud.resource
WHERE (
$.streamName = "DescribeDBInstancesStream"
AND (
$.data.Engine PREFIX "sqlserver"
OR $.data.Engine PREFIX "SQLSERVER"
)
) AS x
JOIN cloud.resource
WHERE (
$.streamName = "DescribeDBParametersStream"
AND $.data.Parameters[*].ParameterName = "rds.force_ssl"
AND $.data.Parameters[*].ParameterValue != "1"
) AS y
ON (
x.$.data.DBParameterGroups[*].DBParameterGroupName CONTAINS y.$.cloudResourceId
AND x.$.region CONTAINS y.$.region
)
When a JOIN has two or more matching conditions in the ON clause, use the CONTAINS operator instead of EQ (=). This is because the left-hand side often references a nested array field ([*]), and CONTAINS correctly checks if the array-derived value set includes the scalar value from the other side of the join.
Literal Values & AWS-Specific Strings
AWS Literal Value — CID 14
<root_account> looks like a placeholder but is not. It is the actual literal value that AWS returns in the IAM Credential Report CSV under the user column for the root user. No substitution happens at runtime — this must be used exactly as shown.
|
Value |
Used In |
Meaning |
|---|---|---|
|
|
CID 14 — GetCredentialReportStream |
AWS uses the literal text |
CID 14 — Ensure no root user account access key exists
Stream: GetCredentialReportStream
Literal value: <root_account> — the exact string AWS puts in the credential report user column for the root user
SELECT r FROM cloud.resource
WHERE (FILTER("GetCredentialReportStream", ($.data.user = "<root_account>"))
AND ($.data.access_key_1_active = "true"
OR $.data.access_key_2_active = "true"))
AS r