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.
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.
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 thetag
filter’scurrentOnly
attribute tofalse
. 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’safter
andbefore
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’sid
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
andrepository
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 turnedtag
->currentOnly
set tofalse
instructs the service to include all, current and historic, image tag mappingspolicyEvaluation
->latestOnly
set tofalse
instructs the service to include all, current and historic, policy evaluationspolicyBundle
->active
set tofalse
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