P0 App Documentation
Sign up for FreeSandbox
  • What Is P0?
    • πŸŽ›οΈIAM Dashboard
    • πŸ”ŽAccess Inventory
    • πŸͺ‘IAM Posture
    • ⏱️Just-In-Time Access
    • ♻️Service-Account Key Rotation
  • Getting Started
    • ⬇️Quick Start
    • 🎁Share P0 With Your Team
  • INVENTORY
    • πŸ—ΊοΈAccess Inventory
    • πŸ”¬Result Details
    • ❔Query Search
      • πŸ“–Search Reference
  • Posture
    • βš–οΈPosture Overview
  • Monitor Results
  • πŸ€”Finding Details
  • ORCHESTRATION
    • ⏰Just-in-time access
      • πŸ–οΈRequesting Access
        • πŸ‘‰For Another Party
      • 🏁Approving Access
        • Pre-approving Access
      • πŸ”€Request Routing
        • Google Cloud Filtering
        • AWS Filtering
  • Environments
    • ☁️Creating an Environment
    • πŸ““Environment Terminology
    • βš™οΈSettings
  • Integrations
    • πŸ“žNotifier integrations
      • πŸ’¬Slack
      • πŸ‘¬Microsoft Teams
      • πŸ“£Custom Notifier
    • πŸ”‘Resource integrations
      • ☁️Google Cloud
        • Requesting Access
        • Permissions Reference
          • Cloud Storage
          • Compute Engine
      • πŸ“¦AWS
        • Requesting Access
      • ☸️Kubernetes
        • Requesting Access
        • Advanced Requests
      • πŸ”‹PostgreSQL
        • Requesting Access
      • ❄️Snowflake
      • πŸ–₯️SSH
      • GitHub
        • Requesting Access
      • πŸ› οΈCustom Resource
    • πŸ‘₯Directory integrations
      • Microsoft Entra ID
        • Requesting Access
      • Google Workspace
      • Integrate P0 with Okta
    • βœ”οΈApproval integrations
      • πŸ””PagerDuty
    • πŸ”ŒSIEM Integrations
      • Splunk HEC Setup
  • P0 Management
    • 🎩Role-Based Access Control
Powered by GitBook
On this page
  • Query expressions
  • Query examples
  • Query links
  1. INVENTORY

Query Search

PreviousResult DetailsNextSearch Reference

Last updated 8 days ago

This page describes how P0's environment query searches work.

Query searches are controlled using two parts:

  • show - controls which kind of data are displayed

  • where - controls which data to show

Show control

Currently, you can choose to "show" credentials (access keys or short-term authentication), principals (users, groups, machine identities, and so forth), grants (in Google Cloud, a role binding; in AWS, a policy attachment), or resources (projects, accounts, services, and individual resources such as storage buckets).

Where control

The "where" control is a free-form search box. You can enter any term here, and P0 will find the principals or grants that relate to your search term.

Example:

Searching for a permission (in this case compute.instances.create in a Google Cloud assessment) will show you all grants that provide that permission:

To see why a search result matches your query, you can click on that result's "view" link. The details page will show an "Explanation" section at the bottom, describing how that result satisfies your query:

Query expressions

You can be more specific in your queries by writing query expressions. This section explains each type of query expression

Here's a summary of query expressions:

Expression
See

Key terms

keyword

Match data substring

"keyword"

Match data exactly

!keyword

Invert keyword matches

Node terms

type:keyterm

Match data types

type=keyterm

Match first datum only

type:attribute:keyterm or type:{attribute1:keyterm1 attribute2:keyterm2 ...}

Match data attributes

Path terms

keyterm->childpath

Child paths

Match a directed path in child direction

keyterm<-parentpath

Parent paths

Match a directed path in parent direction

keyterm<>eitherpath

Either paths

Match a directed path in either parent or child direction

childpath | parentpath | eitherpath

Place multiple conditions on a data connection

Exclusion term

^pathterm

Remove matches from results

Compound expression

expression term

Require multiple data connections

Cypher equivalents

Each detailed explanation below also describes the equivalent statement in the Cypher query language (replace {show} with the corresponding label of the "show" control).

When displaying data as a table, the displayed data are the nodes matching the "show" type (represented by s in the equivalent queries); when displaying data as a graph visualization, the displayed data are the returned paths (represented by p in the equivalent queries).

"Contains" matches

In it's simplest usage, P0 matches IAM data as long as it includes your search keyword. In the above example, searching for compute will show you grants that allow access to any compute resource, provide any privileges with "compute" in their name, grant a permission set with "compute" in its name, or grant access to compute service principals.

"Contains" matches are case insensitive; use Exact matches to find data with exact casing.

Cypher equivalent:

CALL () {
    MATCH p=(s:{show})-[*]->(r)
    RETURN p, r, s
    UNION
    MATCH p=(r)-[*]->(s:{show})
    RETURN p, r, s
}
WITH p, r, s
WHERE ANY(k IN KEYS(r) WHERE r[k] =~ '(?i).*{keyword}.*')
RETURN p, s

Exact matches

To match data exactly, enclose your keyword in double quotes. E.g., searching for compute.instances.get in GCP will match additional permissions, such as compute.instances.getEffectiveFirewalls. Searching for"compute.instances.get" will limit results to only those grants that have that specific permission.

When using exact matches with type and attribute matches, the quotes surround the keyword only: type:attribute:"keyword".

You can also use quotes to search for data where the data includes a colon without triggering a type or attribute match. E.g., risk:"exfiltration:data" will return all results that yield a data exfiltration risk.

Cypher equivalent:

CALL () {
    // per "contains" CALL statement
}
WITH p, r, s
WHERE ANY(k IN KEYS(r) WHERE r[k] = '{keyword}')
RETURN p, s

Inverted matches

You can search for grants and principals that are connected to data that don't match a keyword by typing a ! in front of your search keyword.

Note that using an inverted match on its own usually won't do much, as grants and principals are connected to many data, and some of these data are likely to not match your keyword. Instead, inverted matches are usually best when combined with type or attribute matches, or with exclusion matches. For example, principal:mfa:!enabled will show you all users that have either disabled or unknown MFA status.

When using inverted matches with type and attribute matches, the ! comes after the type and attribute: type:attribute:!keyword.

Cypher equivalent:

CALL () {
    // per "contains" CALL statement
}
WITH p, r, s
WHERE ANY(k IN KEYS(r) WHERE NOT ({keyterm condition}))
RETURN p, s

Exclusion matches

You can search for items that are not connected to data that match a term by typing a ^ in front of your entire search term.

For example, searching for ^usage:type:"unused" will show all grants that have only used or unknown permission usage. Searching for ^usage:type:!"unused" will show all grants where all permissions are unused.

When using exclusion matches, the ^ comes before the type and attribute: ^type:attribute:keyterm.

Cypher equivalent:

MATCH (s1:{show})
WHERE (COUNT {
    // pathterm query w/out "RETURN"
    AND s=s1
}) = 0
RETURN s1

Type matches

You can use a type match without a keyword to search for the presence of data.

For example, condition: will show you all conditional grants.

Cypher equivalent:

CALL () {
    // per "contains" CALL statement
}
WITH p, r, s
WHERE r:{type} AND ANY(k IN keys(r) WHERE r[k] =~ '(?i).*{keyword}.*')
RETURN p, s

"First" matches

Data may be connected to a chain of items of the same type. For instance, a grant on a resource will give access to all that resource's children, and all those child resources' children, and so forth. Or, grants may be made to directory groups with nested group membership.

To restrict your search to only the first item in such a chain, use a first match. For example, principal=alice@my.co will show only the alice@my.co user, and not the groups to which that user belongs.

Cypher equivalent:

CALL () {
    // per "contains" CALL statement
}
WITH p, r, s
WHERE NOT (p)-[*]->(:{type})-[*]->(r)
  AND NOT (r)-[*]->(:{type})-[*]->(p)
  AND ANY(k IN keys(r) WHERE r[k] =~ '(?i).*{keyword}.*')
RETURN p, s

Attribute matches

First and attribute matches may be combined using the syntax {type}={attribute}:{keyterm}.

Cypher equivalent:

CALL () {
    // per "contains" CALL statement
}
WITH p, r, s
WHERE r:{type} AND r.{attribute} =~ '(?i).*{keyword}.*'
RETURN p, s

Multiple matches

Return items that are connected to multiple data by separating search terms using whitespace.

For instance, resource:one resource:two will show you grants that provide access to both resources "one" and "two".

Cypher equivalent:

CALL () {
    // Result of first query
    RETURN p AS p1, s AS s1
}
WITH p1, s1
CALL () {
    // Result of second query
    RETURN p AS p2, s AS s2
}
WITH p2, s2
WHERE s1 = s2
RETURN s1, p1, p2

Via matches

Your IAM data are modeled as a directed graph. You can require data to be connected to your search results according to multiple search terms using a via match.

To use a via match, connect two or more terms using -> (for child relationships), <- (for parent relationships), or <> (for either child or parent relationships).

For example, to find all entitlements that have unused permissions that create a data exfiltration risk, you can search for usage:type:"unused"->risk:"exfiltration:data".

You can chain multiple terms together using additional ->. For example usage:type:"unused"->privilege:s3->risk:"exfiltration:data".

Paths must consistently use child, parent, or "either" relationship syntax. Mixed paths like a->b<-c are not currently supported.

Exclusion matches combined with via matches will return results where one or more of the via conditions do not match.

Cypher equivalent for s<>r:

CALL () {
    MATCH p=(s:{show})-[*]->(q)-[*]->(r)
    RETURN p, q, r, s
    UNION
    MATCH p=(r)-[*]->(q)-[*]->(s:{show})
    RETURN p, q, r, s
}
WITH p, q, r, s
WHERE
    // constraints on q
    AND
    // constraints on r
RETURN p, s

Query examples

One of the best resources for constructing queries is to view the search queries for P0's built-in assessment monitors.

For instance, here's the query for detecting unused service account keys:

show = credential

credential=enabledKey:"true"
credential=last40:"unused"
principal=type:"service-account"
principal=status:"active"

This returns all service-account keys that have not been used in the last 40 days.

Query links

You can also construct queries using tooltips in the displayed data. To do this, hover over an item you want to either include or exclude from your search:

Select the corresponding "show" or "hide" link to either include or exclude that item in your search results.

Limit your search to a specific type of IAM data using a type prefix. For example, adding risk:CRITICAL in front of your search will limit your search to only showing grants that allow a critical IAM risk (as defined by the ). See for a list of all possible types.

Attribute expressions allow you to make even more specific searches. For example, searching for credential:last90:unused will limit displayed principals to those with at least one credential that has not been used in the previous 90 days. See for a list of all possible attributes.

You can reference how data are connected in this graph using .

❔
"Contains" matches
Exact matches
Inverted matches
Type matches
"First" matches
Attribute matches
Via matches
Exclusion matches
Multiple matches
IAM Privilege Catalog
Search types
Search attributes
IAM graph