Skip to main content
Open Beta The Advisory API gives you programmatic access to Anaconda’s curated security advisory data for conda packages. Use it to sync vulnerability information into your Security Information and Event Management (SIEM) system, IT Service Management (ITSM) platform, or audit pipeline. Each advisory is a Common Vulnerabilities and Exposures (CVE) record, and the advisory ID is typically the CVE ID. Advisories apply to artifacts, not to packages as a whole. A package has many versions, and each version can have many builds. Each build of each version is a separate artifact. An advisory identifies exactly which artifacts are affected. For example, suppose a vulnerability affects version 1.2.3 of a package. The advisory identifies the affected builds of 1.2.3, such as py39h1234567_0 on linux-64. If Anaconda patches the vulnerability in a later build of 1.2.3, the patched build isn’t identified as affected. Anaconda produces advisories through the same curation process that powers the CVE information shown in Anaconda Platform. For more information about CVEs and the curation process, see Common Vulnerabilities and Exposures (CVEs).

Authentication

Obtaining a token

Exchange your service account credentials for an access token:
The response includes an access_token:
Access tokens expire after 15 minutes (900 seconds). If your sync job runs longer, request a new token when the current one expires.

Making authenticated requests

Include the token in the Authorization header:

Base URL

Endpoints

Syncing the advisory feed

Sync the feed to keep your own up-to-date copy of Anaconda’s advisory data. The first sync downloads every advisory Anaconda has published; later syncs download only what changed. With a local copy of the advisory data, your tooling can check every package you run against the latest CVEs, as often as you want, without an API call for each check. On your first sync, request the feed with no parameters to get every advisory Anaconda has published. Run a full sync only once. The response returns a watermark; save it. On later syncs, pass that watermark as the modified_since parameter to get only the advisories that changed since your last sync. The response contains advisories and pagination metadata:
To view the command output cleanly in your terminal, pipe the response through jq.
Response pagination metadata example
The fields work as follows:
  • watermark: The most recent change included in the results. The watermark is the same on every page of a sync. Save it when you reach the last page; it’s your starting point for the next sync.
  • continuation and next_url: Present while more pages remain. To get the next page, follow the next_url, or pass the continuation value back as the continuation query parameter. When you pass continuation, the API ignores all other query parameters. Continuation tokens stay valid for at least 24 hours, but don’t persist them long term like the watermark.
  • has_more: Displays true while more pages remain.
When you finish a sync, index the advisories locally by package URL (PURL) or by the affected artifacts’ SHA256 hashes (artifact_sha256s) so your tooling can match them against installed packages. Each PURL corresponds to one of the SHA256 hashes in artifact_sha256s; either one works as a lookup key. For a working implementation of this pattern, continue to Monitoring for new advisories with Python.

Monitoring for new advisories with Python

The following script shows the full sync pattern. It gets an access token, downloads the advisories that changed since the last run, saves the new watermark, and prints a summary. On the first run, when no watermark exists, it downloads the full feed. The script requires the requests package, and it reads your service account credentials from environment variables. To use the script:
1

Set the environment variables

2

Save the script

Save the following script as sync.py:
3

Run the script

The first run downloads the full feed, which can take several minutes. Later runs download only the advisories that changed since the previous run.
The first full sync can take long enough that the access token expires. If a request returns a 401 error, get a new token and continue paging from the last next_url.
4

Schedule the script

Optional. To keep monitoring over time, schedule the script to run regularly, for example, with cron or a scheduled CI job.

Matching advisories against your environments

What you do with changed advisories depends on your systems. One common approach is to compare the packages each advisory affects against the packages you have installed. The following example extends the script above. Add it to the same file. The example parses the PURLs of the affected artifacts and compares them with the packages installed in the active conda environment. The match is exact: the name, version, build, and platform must all match. It checks only the advisories from the current sync (changed), so it doesn’t call the API again.
The example requires the packageurl-python package (conda install packageurl-python).
The example checks the environment that’s active when the script runs. To check a different environment, pass its name to conda list, for example conda list --name <ENV_NAME> --json.Keep this in mind when you schedule the script: cron jobs and CI runners don’t activate environments, so the active environment is base unless the job activates another one or targets it by name.
Matching on the exact artifact matters: Anaconda sometimes fixes a vulnerability in a new build of the same package version, and some CVEs affect only certain platforms. Advisories identify only artifacts that Anaconda builds and maintains, so packages installed from other channels, such as conda-forge, don’t match. For the strictest comparison, match on the advisory’s artifact_sha256s instead of the PURL qualifiers.