GraphQL Reports API Access

Anchore Enterprise Reports provides a GraphQL API for direct interaction with the service. GraphQL is a query language for APIs and a runtime for fulfilling those queries.

The main Anchore REST API includes operations for retrieving scheduled report results as static sets to make retrieval of saved results simpler. It is available in the V2 API. The GraphQL schema and types are documented at https://graphql.org/learn/schema/.

Get started

There are different ways of interacting with the Anchore Enterprise Reports GraphQL API. The following sections highlight two different options for exploring the Anchore Enterprise Reports GraphQL schema with a few examples.

The endpoint you use for interacting with the GraphQL API is the same host and port as the main V2 API. The path is: /v2/reports/.

Graphical User Interface

One of the ways of exploring and testing a GraphQL schema is by using a web based interface - GraphiQL. GraphiQL is built-in to the API service and enabled by default in Anchore Enterprise.

To access it in a running Anchore Enterprise deployment, open one of the following urls in a browser:

  • http://\<main_api_servername:port\>/v2/reports/graphql
  • http://\<main_api_servername:port\>/v2/reports/global/graphql (Administrator Access Only)

You will be prompted to enter your Anchore Enterprise credentials.

Working with queries in GraphiQL

Click the show Documentation Explorer button (book icon) in the top left of the GraphiQL window to view the self-describing schema. There are only two root types exposed currently, Query and Mutation.

  • Query type can be used to obtain image vulnerability data on request.
  • Mutation type can be used to create new as well as execute and manage existing scheduled queries.

Reports GraphiQL Docs

Expand the Query type by clicking on the hyperlink to expose all sub-types. Notice the schema example for runtimeInventoryImagesByVulnerability in the schema docs:

runtimeInventoryImagesByVulnerability(
  limit: 1000
  nextToken: "token"
  filter: RuntimeInventoryImagesByVulnerabilityFilter
)
{
  results {
    vulnerabilityId
  }
}

The documentation snippet above comprises of (1) a query type name then (2) arguments for the maximum number of responses to be returned within each page, and/or (3) the nextToken supplied from a previous response if this number is exceeded. See the pagination section below for more information. Additionally (4) the filter which must be correctly defined for the query to be successful. Some basic arguments may be omitted for simple test queries, however the root query type structure shown in the documentation itself must always be surrounded by curly braces {..} when used in the editor.

When a query structure is formatted correctly it will be colourised to indicate that it matches the schema. Ensure that limit example is defined as an integer number if used, omit nextToken string if not required. Check the right hand panel for any syntax errors.

Now click on the hyperlink in the schema docs for the filter RuntimeInventoryImagesByVulnerabilityFilter. This filter schema defines three additional filters which can each be used individually within the previous structure.

[..]
    filter: {
      artifact: {name: "gzip"}
      image:{}
      vulnerability: {}
    }

The above example shows one RuntimeInventoryImagesByVulnerabilityFilter artifact filter field called ’name’ which searches for any artifacts with ‘gzip’. More than one field can be used in each filter, and more than one filter field can be defined in multiple filters.

After closing the parentheses (which hold the query type arguments) a response section is added within curly braces to define the results which will be returned. This approach allows different response results to be freely defined according to the query response schema linked to from the top level schema doc RuntimeInventoryImagesByVulnerabilityResponse:

[..]
{
  results {
    vulnerabilityId
    cve
    imagesCount
    account
    images {
      context
      artifacts {
        artifactName
      }
    }
  }
}

Notice that the query response structure also allows both ‘images’ and ‘artifacts’ fields to be defined using their own individual arguments, click on the named hyperlinks to traverse the structure for examples. When combined together the type definition for both the query and response types create a full query.

In summary the GraphiQL GUI interface is handy for exploring and constructing queries supported by the backing API. On the left you can explore the API query docs specific to Anchore, in the middle you can construct and execute your query and on the right side you can see your query results.

Reports GraphQL Example

Happy querying!

Command-Line Interface

You can also use curl to send HTTP requests to Anchore Enterprise Reports API. To view the schema

$ curl -u <username:password> -X POST "http://<servername:port>/v2/reports/graphql?query=%7B__schema%7BqueryType%7Bname%20description%20fields%7Bname%20description%20args%7Bname%20description%20type%7Bname%20kind%7D%7D%7D%7D%7D%7D%0A"

You can use the API programmatically within the command line and other custom scripts/programs.

Query Options

API Key

If you are interacting directly with the API, either via a command line tool, custom scripts/programs or the GraphiQL GUI interface; You can generate and utilize API keys to avoid using private credentials. See Generating API keys for details.

API keys, work the same way as your regular credentials for both command line and GUI queries. The username for API keys is static as _api_key and the password is the value of the generated key string.

Command line access using an API key

  • $ curl -u <_api_key:<generated key value> -XGET "http://<servername:port>/v2/reports

GraphiQL GUI access using an API key

  • Visit your GraphiQL endpoint in your web browser. Use ‘_api_key’ and ‘’ when prompted for a username and password.

Pagination

Depending on the size of the data set (i.e. number of tags, images etc in the system) the results of a query could be very large. The reports service implements pagination for all queries to better handle the volume of the results.

All response types contain a metadata object called pageInfo. It is optional, but recommended to add to all queries:

{
  imagesByVulnerability {
    pageInfo {
      nextToken
      count
    }
    results {
      ...
    }
  }
}

The response may return an opaque token or a null value for nextToken:

{
  "data": {
    "imagesByVulnerability": {
      "pageInfo": {
        "nextToken": "Q1ZFLTIwMTYtMTAyNjY=",
        "count": 1000
      },
      "results": [
        ...
      ]
    }
  }
}      

A non-null nextToken indicates that results are paginated. To get the next page of results, fire the same query along with the nextToken from the last response as a query parameter:

{
  imagesByVulnerability(nextToken: "Q1ZFLTIwMTYtMTAyNjY=") {
    pageInfo {
      nextToken
      count
    }
    results {
      ...
    }
  }
}

Useful queries

Vulnerability centric queries

  • List vulnerabilities of a specific severity. And include all the images, currently or historically mapped to a tag, affected by each vulnerability

    Use the query’s filter argument for specifying the conditionality. Reports service defaults to the “current” image-tag mapping for computing results. To compute results across all image-tag mappings - current and historic,
    set the tag filter’s currentOnly attribute to false. Query for vulnerabilities of Critical severity:

    {
      imagesByVulnerability(filter: {vulnerability: {severity: Critical}, tag: {currentOnly: false}}) {
        pageInfo {
          nextToken
        }
        results {
          vulnerabilityId
          links
          imagesCount
          images {
            digest
          }
        }
      }
    }
    

    To get more details such as tag mappings for the image, add the relevant attributes from the schema to the body of the query.

  • List vulnerabilities detected in the last x hours. And include all the images, currently or historically mapped to a tag, affected by each vulnerability

    Use vulnerability filter’s after and before attributes for specifying a time window using UTC timestamps. Query for vulnerabilities detected after/since August 1st 2019:

    {
      imagesByVulnerability(filter: {vulnerability: {after: "2019-08-01T00:00:00"}, tag: {currentOnly: false}}) {
        pageInfo {
          nextToken
        }
        results {
          vulnerabilityId
          images {
            digest
          }
        }
      }
    }
    
  • Given a vulnerability ID, list all the artifacts affected by that vulnerability. And include all the images, currently or historically mapped to a tag, containing the said artifact

    Use vulnerability filter’s id attribute for specifying a vulnerability identifier. Query for vulnerability ID CVE-2019-15213:

    {
      artifactsByVulnerability(filter: {vulnerability: {id: "CVE-2019-15213"}, tag: {currentOnly: false}}) {
        pageInfo {
          nextToken
        }
        results {
          vulnerabilityId
          links
          artifactsCount
          artifacts {
            artifactName
            artifactVersion
            artifactType
            severity
            images {
              digest
            }
          }
        }
      }
    }
    

For large queries across many images/sboms we recommend that you utilize the scheduled report functionality as this offers improved performance.

Policy evaluation centric queries

  • Given a repository, get the policy evaluation results for all the tags currently mapped to an image using the active policy

    Use registry and repository filters for narrowing the results down. Query for docker.io registry and library/node repository:

    {
      policyEvaluationsByTag(filter: {registry: {name: "docker.io"}, repository: {name: "library/node"}}) {
        pageInfo {
          nextToken
        }
        results {
          repositories {
            tagsCount
            tags {
              tagName
              imageDigest
              evaluations {
                result
                reason
              }
            }
          }
        }
      }
    }
    
  • Given a tag, get the policy evaluation history. Include policy evaluations encompassing updates to the tag and the active policy

    Reports service defaults to the “current” state for computing results. To compute results across historic state, a few filter knobs have to be turned

    • tag -> currentOnly set to false instructs the service to include all, current and historic, image tag mappings

    • policyEvaluation -> latestOnly set to false instructs the service to include all, current and historic, policy evaluations

    • policyBundle -> active set to false instructs service to include all, current and historic, active policies

      {
        policyEvaluationsByTag(filter: {registry: {name: "docker.io"}, repository: {name: "library/node"}, tag: {name: "latest", currentOnly: false}, policyEvaluation: {latestOnly: false}, policyBundle: {active: false}}) {
          pageInfo {
            nextToken
          }
          results {
            repositories {
              tags {
                imageDigest
                detectedAt
                current
                evaluations {
                  result
                  reason
                  lastEvaluatedAt
                  policyBundle {
                    bundleId
                    bundleDigest
                  }
                  latest
                }
              }
            }
          }
        }
      }
      

Metric centric queries

  • List all the available metrics

    {
      metrics {
        pageInfo {
          nextToken
        }
        results {
          id
          name
          description
          metricType
        }
      }
    }
    
  • Given a metric ID, list values for that metric within a period of time. Useful for plotting changes over a timescale

    Query for vulnerabilities.tags.all.critical metric between 1st August and 1st September 2019:

    {
      metricData(filter: {metricId: "vulnerabilities.tags.all.critical", start: "2019-08-01T00:00:00", end: "2019-09-01T00:00:00"}) {
        pageInfo {
          nextToken
        }
        results {
          collectedAt
          value
        }
      }
    }
    

Scheduled report queries

Scheduled reports can be created via the Anchore Enterprise reporting Web UI or using the GraphQL API and mutation type. Once you have created a scheduled report, the following example below will run you through how you can retrieve and use this report data.

Please note:

  • Large queries will run MUCH faster when created as a scheduled report and run. vs manually paginating through the API.
  • When creating a scheduled report directly via the GraphQL API it will NOT show up in the UI.

Retrieve a list of UUIDs for all scheduled report executions. Use the selected UUIDs to retrieve the report content from the API:

{ 
scheduledQueries { 
    pageInfo { 
        nextToken 
        count 
    } 
    results { 
        uuid 
        name 
        description 
        createdAt 
        updatedAt 
        cronSchedule 
        executions { 
            uuid 
            createdAt 
            resultCount 
            }
        } 
    } 
}

When the response is received extract the execution instance uuid nested within the named report.

[{"uuid":"d0e8ba1c55434647bd7244452c9917c6","name":"TestReport","description":"","createdAt":"2024-05-30T08:38:41.179056","updatedAt":"2024-05-30T08:38:41.179074","cronSchedule":"0 8 * * 0,1,2,3,4,5,6","executions":[{"uuid":"c14dd3ee18e2490aa5d0679e1fb514af","createdAt":"2024-05-30T09:41:56.518770","resultCount":1061},{"uuid":"b7990ee4069b466286058745c887f0fa","createdAt":"2024-05-30T08:40:37.348798","resultCount":0},{"uuid":"97b469897b3440a3bad00edb8ec4ad2f","createdAt":"2024-05-30T08:38:41.227474","resultCount":0}]}]}}}

Now insert the uuid of the report execution in a REST query to the API using:

curl -s -u "<username:password>" -X GET http://<servername:port>/v2/reporting/scheduled-query-results/c14dd3ee18e2490aa5d0679e1fb514af

Which will return a response similiar to the following:

{"tagsByVulnerability":{"results":[{"vulnerabilityId":"CVE-2024-34459","cve":"CVE-2024-34459","registries":[{"registryName":"docker.io","repositories":[{"repositoryName":"centos","tags":[{"tagName":"7","detectedAt":"2024-05-30T09:40:04","current":true,"image":{"digest":"sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f","link":"https://access.redhat.com/security/cve/CVE-2024-34459","artifacts":[{"artifactName":"libxml2-python","artifactVersion":"2.9.1-6.el7.5","artifactType":"rpm","artifactLocation":"pkgdb","namespace":"rhel:7","severity":"Low","fixedIn":null,"fixObservedAt":null},{"artifactN...
Last modified February 12, 2025