# Apono Query Language

The Apono Query Language (AQL) provides a simple, intuitive syntax for filtering cloud resources, integrations, and permissions.

<figure><img src="https://1094436629-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6MBfUGvblSdAz31yJXm%2Fuploads%2Fgit-blob-432bc3c470f98365ef40d759b816a8645eb4588d%2Fimage%20(59).png?alt=media" alt=""><figcaption><p>AQL query on the Inventory page</p></figcaption></figure>

This reference documents query construction, available components, and common filtering examples.

{% hint style="success" %}
When you are first starting to build queries, you can quickly learn how to build them by following these steps:

1. On the [**Inventory**](https://app.apono.io/inventory) page, click **Basic**.
2. [Filter the resources](https://docs.apono.io/docs/inventory#filter-resources).
3. Click **AQL**. The AQL syntax will appear in the code box.
   {% endhint %}

***

### **Syntax**

The following is a basic AQL query.

```sql
resource_type = "aws-rds-mysql"
```

AQL uses a simple **field-operator-value** pattern.

```sql
field operator "value"
```

<table><thead><tr><th width="220">Component</th><th>Description</th></tr></thead><tbody><tr><td><a href="#field"><strong>field</strong></a></td><td>Attribute or tag to query</td></tr><tr><td><a href="#operator"><strong>operator</strong></a></td><td>Comparative logic</td></tr><tr><td><strong>value</strong></td><td>Expected value for the field</td></tr></tbody></table>

#### field

The `field` component specifies the attribute of your cloud resources to query.

{% tabs %}
{% tab title="Resource" %}

<table><thead><tr><th width="195">Field</th><th width="188">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>resource_type</strong></td><td>Resource type</td><td><code>resource_type = "aws-rds-mysql"</code></td></tr><tr><td><strong>resource_name</strong></td><td>Resource name</td><td><code>resource_name contains "prod"</code></td></tr><tr><td><strong>resource_path</strong></td><td>Resource Path</td><td><code>resource_path contains "us-east-1"</code></td></tr><tr><td><strong>resource</strong></td><td>Resource identifier</td><td><code>resource = "res_12345"</code></td></tr><tr><td><strong>resource_status</strong></td><td>Current status</td><td><code>resource_status = "active"</code></td></tr><tr><td><strong>resource_risk_level</strong></td><td>Associated risk level</td><td><code>resource_risk_level = "high"</code></td></tr></tbody></table>
{% endtab %}

{% tab title="Permission" %}

<table><thead><tr><th width="211">Field</th><th width="188">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>permission_name</strong></td><td>Permission name</td><td><code>permission_name = "ReadOnly"</code></td></tr><tr><td><strong>permission</strong></td><td>Permission identifier</td><td><code>permission = "perm_12345"</code></td></tr><tr><td><strong>permission_risk_level</strong></td><td>Permission risk level</td><td><code>permission_risk_level = "critical"</code></td></tr></tbody></table>
{% endtab %}

{% tab title="Integration" %}

<table><thead><tr><th width="193">Field</th><th width="188">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>integration_name</strong></td><td>Integration name</td><td><code>integration_name = "AWS-Prod"</code></td></tr><tr><td><strong>integration</strong></td><td>Integration identifier</td><td><code>integration = "int_12345"</code></td></tr></tbody></table>
{% endtab %}

{% tab title="Metadata" %}

<table><thead><tr><th width="245">Field</th><th width="176">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>resource_tag["key"]</strong></td><td>Resource tags</td><td><code>resource_tag["environment"] = "prod"</code></td></tr><tr><td><strong>resource_context["key"]</strong></td><td>Resource context</td><td><code>resource_context["region"] = "us-east-1"</code></td></tr><tr><td><strong>permission_tag["key"]</strong></td><td>Permission tags</td><td><code>permission_tag["type"] = "temporary"</code></td></tr><tr><td><strong>permission_context["key"]</strong></td><td>Permission context</td><td><code>permission_context["access"] = "write"</code></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

#### operator

The `operator` component defines how to evaluate the `field` against the specified `value`.

{% tabs %}
{% tab title="Comparison" %}
Basic operators that test for equality and inequality between values

<table><thead><tr><th width="151">Logic</th><th width="253">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>=</strong></td><td>Checks if values are the same</td><td><code>resource_type = "aws-account-dynamodb-table"</code></td></tr><tr><td><strong>!=</strong></td><td>Checks if values are different</td><td><code>integration != "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"</code></td></tr></tbody></table>
{% endtab %}

{% tab title="String Matching" %}
Operators that perform text-based comparisons ranging from exact matches to pattern matching

<table><thead><tr><th width="151">Logic</th><th width="253">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>contains</strong></td><td>Checks if a value contains another value as a substring or pattern</td><td><code>(resource_tag["aws:cloudformation:stack-name"] contains "apono-cloudtrail")</code></td></tr><tr><td><strong>not_contains</strong></td><td>Checks if a value does NOT contain another value as a substring or pattern</td><td><code>permission_name not_contains "admin"</code></td></tr><tr><td><strong>starts_with</strong></td><td>Checks if a value begins with a specific value or pattern</td><td><code>resource_name starts_with "aws"</code></td></tr><tr><td><strong>ends_with</strong></td><td>Checks if a value ends with a specific value or pattern</td><td><code>(resource_tag["env"] ends_with "dev")</code></td></tr></tbody></table>
{% endtab %}

{% tab title="Lists" %}
Operators that check if values exist within defined sets of options

<table><thead><tr><th width="152">Logic</th><th width="252">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>in</strong></td><td>Checks if the value is one of a list</td><td><code>resource_type in ("aws-account-dynamodb-table", "aws-account-s3", "aws-account-sns-topic")</code></td></tr><tr><td><strong>not_in</strong></td><td>Checks if the value is NOT one of a list</td><td><code>(resource_tag["aws:cloudformation:stack-name"] not_in ("apono-cloudtrail", "apono-doxy-dev"))</code></td></tr></tbody></table>
{% endtab %}

{% tab title="Logic" %}
Operators that combine multiple conditions to create complex queries

<table><thead><tr><th width="151">Logic</th><th width="252">Description</th><th>Example</th></tr></thead><tbody><tr><td><strong>and</strong></td><td>Checks if both conditions are true</td><td><code>resource_type = "aws-account-s3" AND permission_name = "admin"</code></td></tr><tr><td><strong>or</strong></td><td>Checks if either condition is true</td><td><code>resource_type = "aws-account-s3" OR resource_name contains "playground"</code></td></tr><tr><td><strong>not</strong></td><td>Negates a condition</td><td><code>integration = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" and not resource_type = "aws-account-sns-topic"</code></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

***

### Common Queries

The following AQL queries demonstrate how to efficiently locate, audit, and manage cloud resources and permissions. They cover common use cases such as identifying high-risk assets, tracking access levels, and enforcing security policies.

Use these queries as a foundation and customize them to fit your specific environment and compliance requirements.

#### Resource Queries

Queries focused on locating and filtering cloud infrastructure resources

```sql
# Find production databases
resource_type = "aws-rds-mysql" and resource_name contains "prod"

# Find high-risk resources in specific region
resource_risk_level = "high" and resource_context["region"] = "us-east-1"

# Find resources by team ownership
resource_tag["team"] = "platform" and resource_tag["environment"] = "prod"
```

#### Permission Queries

Queries that manage and audit access control settings

{% code overflow="wrap" %}

```sql
# Find critical write permissions
permission_risk_level = "critical" and permission_context["access"] = "write"

# Find temporary access permissions
permission_tag["type"] = "temporary" and permission_status = "active"

# Find elevated permissions
permission_risk_level in ("high","critical") and not permission_name contains "readonly"
```

{% endcode %}

#### Combined Queries

Advanced patterns that merge resource and permission conditions for precise access control

```sql
# Find high-risk prod resources with write permissions
resource_name contains "prod"
and resource_risk_level = "high"
and permission_context["access"] = "write"

# Find temporary access to critical resources
resource_risk_level = "critical"
and permission_tag["type"] = "temporary"
and permission_status = "active"
```

***

### Best Practices

Follow these best practices to write AQL queries that are clear, efficient, and easy to modify. These guidelines improve readability, execution speed, and adaptability.

#### Start with a specific condition

AQL processes conditions from left to right. Starting with a specific filter improves efficiency.

```sql
# Effective
resource_type = "aws-rds-mysql" and resource_name contains "prod"

# Less Efficient
resource_name contains "prod" and resource_type = "aws-rds-mysql"
```

#### Use lists instead of multiple OR conditions

When checking multiple values, `in (...)` is more concise and performs better than chaining multiple `or` conditions.

{% code overflow="wrap" %}

```sql
# Effective
resource_type in ("aws-rds-mysql", "aws-account-s3", "aws-ec2-ssh")

# Less efficient
resource_type = "aws-rds-mysql" or resource_type = "aws-account-s3" or resource_type = "aws-ec2-ssh"
```

{% endcode %}

#### Use parentheses to avoid ambiguity

Without parentheses, complex conditions can be misinterpreted and return unexpected results. Grouping conditions explicitly ensures the query evaluates as intended.

```sql
(resource_type = "aws-rds-mysql" and resource_name contains "prod")
or (resource_type = "aws-account-s3" and resource_name contains "backup")
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.apono.io/docs/inventory/apono-query-language.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
