Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
106 changes: 98 additions & 8 deletions src/pages/reference/vulnerability-database/update-schedule.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,102 @@
import Image from 'next/image'
---
title: Update Schedule
description: How DevGuard's vulnerability database is built, signed, distributed, and kept up to date
---

import { Callout } from 'nextra/components'
import {
Tooltip,
TooltipTrigger,
TooltipContent,
} from '@/components/ui/tooltip'
import PageContentComingSoon from '@/components/PageContentComingSoon'

# Update Schedule

<PageContentComingSoon />
DevGuard maintains its own aggregated vulnerability database that is rebuilt every **6 hours** from upstream sources, cryptographically signed, and distributed as an OCI artifact. DevGuard instances pull these incremental updates automatically.

## Build Schedule

The vulnerability database is built by a [GitHub Actions workflow](https://github.com/l3montree-dev/devguard/actions/workflows/vulndb.yaml) that runs on a fixed schedule:

| Property | Value |
|---|---|
| **Schedule** | Every 6 hours (`0 */6 * * *`) |
| **Trigger** | Cron schedule + manual dispatch |
| **Pipeline** | [`vulndb.yaml`](https://github.com/l3montree-dev/devguard/blob/main/.github/workflows/vulndb.yaml) |
| **Artifact registry** | [`ghcr.io/l3montree-dev/devguard/vulndb/v1`](https://github.com/l3montree-dev/devguard/pkgs/container/devguard%2Fvulndb%2Fv1) |

## Data Sources Synced

Each build synchronizes the following upstream sources into a single PostgreSQL database:

| Source | Description |
|---|---|
| **OSV** | Open Source Vulnerabilities — covers npm, PyPI, Go, Maven, Cargo, NuGet, RubyGems, and [many more ecosystems](https://osv.dev/list) |
| **EPSS** | Exploit Prediction Scoring System — probability that a CVE will be exploited in the wild |
| **CISA KEV** | Known Exploited Vulnerabilities catalog |
| **CWE** | Common Weakness Enumeration taxonomy |
| **ExploitDB** | Public exploit database |
| **GitHub PoC** | Proof-of-concept exploits published on GitHub |
| **Debian Security Tracker (DSA)** | Debian-specific security advisories and affected package mappings |
| **Malicious Packages** | Known malicious packages across ecosystems |

<Callout type="info">
For details on each data source and how they are used, see [Data Sources](/reference/vulnerability-database/data-sources).
</Callout>

## Build Pipeline

The workflow executes the following steps in sequence:

1. **Import** — Pull the latest published database state from the OCI registry using `devguard-cli vulndb import`, restoring the previous build as a baseline.
2. **Sync** — Fetch fresh data from all upstream sources using `devguard-cli vulndb sync`. This updates CVEs, affected components, exploit data, EPSS scores, CISA KEV status, CWE mappings, and malicious package entries.
3. **Export** — Compute the differential between the previous and current database states using `devguard-cli vulndb export`. The result is a set of CSV files containing only inserts, updates, and deletes.
4. **Package** — Bundle the differential CSV files into a `vulndb.zip` archive.
5. **Sign** — Sign the archive using [Cosign](https://docs.sigstore.dev/cosign/overview/) with a private key. The signature is stored as `vulndb.zip.sig`.
6. **Publish** — Push both the archive and its signature to the GitHub Container Registry as OCI artifacts using [ORAS](https://oras.land/). Each artifact is tagged with a Unix timestamp (e.g., `1708185600`).

<Callout type="info">
Full database snapshots can also be generated via manual workflow dispatch by setting `run_generate_snapshot` to `true`. Snapshots contain the complete database state rather than just a differential and are used as a baseline for new instances.
</Callout>

## Distribution Format

The database is distributed as OCI artifacts via the GitHub Container Registry:

```
ghcr.io/l3montree-dev/devguard/vulndb/v1:<timestamp> # differential update
ghcr.io/l3montree-dev/devguard/vulndb/v1:<timestamp>.sig # cosign signature
ghcr.io/l3montree-dev/devguard/vulndb/v1:<timestamp>-snapshot # full snapshot (periodic)
ghcr.io/l3montree-dev/devguard/vulndb/v1:<timestamp>-snapshot.sig
```

Each archive contains CSV files with the changes since the last build:

| File | Contents |
|---|---|
| `cves_insert.csv` / `cves_update.csv` / `cves_delete.csv` | New, modified, or removed CVE entries |
| `affected_components_*.csv` | Affected component mappings |
| `cve_affected_component_*.csv` | CVE-to-component join records |
| `cwes_*.csv` | CWE taxonomy updates |
| `exploits_*.csv` | Exploit data changes |
| `malicious_packages_*.csv` | Malicious package entries |
| `malicious_affected_components_*.csv` | Malicious package component mappings |
| `cve_relationships_*.csv` | CVE relationship updates |

## How DevGuard Instances Consume Updates

DevGuard server instances automatically pull and apply database updates:

1. On startup (and periodically thereafter), the server's **VulnDB daemon** calls `ImportFromDiff`.
2. The daemon connects to `ghcr.io/l3montree-dev/devguard/vulndb/v1` and lists all available tags.
3. It identifies tags newer than the last imported version (tracked in the `vulndb.lastIncrementalImport` config key).
4. For each new tag, it downloads the OCI artifact, **verifies the Cosign signature** against the bundled `cosign.pub` public key, unzips the archive, and applies the differential CSV files to the local database.
5. Snapshot tags are handled separately — if a snapshot is encountered, the full database state is loaded before applying subsequent differentials.

<Callout type="warning">
To disable automatic updates (e.g., in air-gapped environments), set the environment variable `DISABLE_VULNDB_UPDATE=true`. See [Database Maintenance](/how-to-guides/administration/database-maintenance) for more details.
</Callout>

## Signature Verification

Every database artifact is signed and verified before being applied:

- **Signing**: The build pipeline signs `vulndb.zip` using Cosign with an ECDSA private key. The signature is base64-encoded and published alongside the archive.
- **Verification**: On import, the DevGuard instance loads the `cosign.pub` public key, downloads the `.sig` artifact for the corresponding tag, and verifies the signature using `sigstore/sigstore`. If verification fails, the update is rejected.

This ensures that only database artifacts built by the official pipeline are applied, protecting against supply chain attacks on the vulnerability data itself.
Loading