From 212de70dcec5dd77b16e7bb9129fb87e022cb396 Mon Sep 17 00:00:00 2001 From: Xueqin Cui Date: Fri, 7 Aug 2026 11:58:49 +1000 Subject: [PATCH 1/2] docs: update architecture to reflect infrastructure migration --- docs/contributing/architecture.md | 50 ++++++++++++++++++++---------- docs/images/architecture.png | Bin 93466 -> 107012 bytes 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/docs/contributing/architecture.md b/docs/contributing/architecture.md index 49148087c06..73c76512efc 100644 --- a/docs/contributing/architecture.md +++ b/docs/contributing/architecture.md @@ -19,39 +19,55 @@ OSV runs on Google Cloud Platform, with the following main components: ## Cloud Datastore -All vulnerability data is stored in [Cloud Datastore], with the [models] defined -[here]. +All vulnerability data is stored in [Cloud Datastore] and the models are primarily defined in Go ([`go/internal/database/datastore/models.go`](../../go/internal/database/datastore/models.go)). [Cloud Datastore]: https://cloud.google.com/datastore -[models]: https://googleapis.dev/python/python-ndb/latest/index.html#defining-entities-keys-and-properties -[here]: https://github.com/google/osv/blob/master/osv/models.py + + +## Google Cloud Storage (GCS) + +Full vulnerability records (conforming to the OSV schema) are stored as protobufs and JSON files in public [Google Cloud Storage] buckets. GCS acts as the primary source of truth for the vulnerability data, while Cloud Datastore is used as an index for fast querying and API lookups. + +[Google Cloud Storage]: https://cloud.google.com/storage + ## Google Kubernetes Engine (GKE) -[GKE] is used for running [workers] to perform bisects and impact analysis. -These workers consume tasks from a [Cloud Pub/Sub] topic. +[GKE](https://cloud.google.com/kubernetes-engine) is used for running the core vulnerability processing pipeline, auxiliary background services, and legacy/OSS-Fuzz workloads. + +### Core Vulnerability Pipeline (Go-based) + +These services run as native Go workloads inside the GKE cluster: + +- **[importer](../../go/cmd/importer)**: A scheduled CronJob that polls and pulls vulnerability source repositories, detects additions/deletions, and dispatches processing tasks via [Cloud Pub/Sub](https://cloud.google.com/pubsub). It also manages periodic data cleanup (`importer-deleter`) and full database reconciliation (`importer-reconciler`). +- **[worker](../../go/cmd/worker)**: A daemon Deployment that consumes Pub/Sub tasks to ingest and enrich vulnerability records, compute affected commit/version ranges, and write them to GCS and Cloud Datastore. It is scaled dynamically using a HorizontalPodAutoscaler based on the Pub/Sub backlog. +- **[exporter](../../go/cmd/exporter)**: A scheduled CronJob that packages the entire OSV database (as zip files and individual JSON files) and exports them to public GCS buckets. +- **[gitter](../../go/cmd/gitter)**: A caching service Deployment that caches and precomputes heavy Git repository operations (cloning, commit graphs, patch IDs) for the importers and workers. It is backed by a large SSD Persistent Volume. +- **[relations](../../go/cmd/relations)**: A scheduled CronJob that calculates and populates transitive and reflective relationships (aliases, related, and upstream fields) between vulnerability records. +- **[indexer](../../gcp/indexer)**: A Deployment that manages git index mapping and version determination. +- **[vulnfeeds](../../vulnfeeds)**: Scheduled CronJobs that mirror and convert external vulnerability advisory feeds (e.g. NVD, Debian, Alpine) into OSV schema format. + +### Auxiliary Services (Python-based) + +These run as Python workloads inside GKE: + +- **[recoverer](../../gcp/workers/recoverer)**: A daemon Deployment that processes failed tasks (e.g., failed GCS writes, git push failures) sent to a recovery queue, attempting to heal/repair their state. +- **[vanir_signatures](../../gcp/workers/vanir_signatures)**: A scheduled CronJob that generates Vanir signatures for modified vulnerabilities. -Workers are Docker containers, which use [gVisor] for sandboxing untrusted -workloads. +### OSS-Fuzz Integration -[GKE]: https://cloud.google.com/kubernetes-engine -[workers]: https://github.com/google/osv/tree/master/gcp/workers -[gVisor]: https://gvisor.dev/ -[Cloud Pub/Sub]: https://cloud.google.com/pubsub +- **[OSS-Fuzz workers](../../gcp/workers/oss_fuzz_worker)**: Legacy Python-based workers that perform bisection and impact analysis for ClusterFuzz/OSS-Fuzz bugs. Because these compile and run code from arbitrary open source projects, they run in Docker containers sandboxed with [gVisor](https://gvisor.dev/). ## Cloud Run / Cloud Endpoints -The [API server] runs on [Cloud Run], and is served by [Cloud Endpoints]. +The [API server](https://api.osv.dev) (source code in [`go/cmd/api`](../../go/cmd/api)) runs on [Cloud Run], and is served by [Cloud Endpoints] (transcoding HTTP/JSON REST to gRPC using ESPv2). -[API server]: https://github.com/google/osv/tree/master/gcp/api [Cloud Run]: https://cloud.google.com/run [Cloud Endpoints]: https://cloud.google.com/endpoints ## Website -The [main web UI] also runs on [Cloud Run], and is served through -[Cloud Load Balancing]. +The [main web UI](https://osv.dev) (source code in [`gcp/website`](../../gcp/website)) also runs on [Cloud Run], and is served through [Cloud Load Balancing]. -[main web UI]: https://osv.dev [Cloud Run]: https://cloud.google.com/run [Cloud Load Balancing]: https://cloud.google.com/load-balancing diff --git a/docs/images/architecture.png b/docs/images/architecture.png index 47eee4cb7d292252a46e692cceb1638562cfe116..aee08f3f243d56d94574a98e6cd35acc9adb7802 100644 GIT binary patch literal 107012 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