pfenerty/oxidex

GitHub: pfenerty/oxidex

一个软件供应链元数据目录工具,用于集中管理 CycloneDX SBOM、追踪制品组件变更和许可证合规。

Stars: 0 | Forks: 0

# OCIDex **一个用于软件供应链的元数据目录。** OCIDex 接收 [CycloneDX](https://cyclonedx.org/) SBOM,将它们与其描述的软件制品关联起来,并为您提供一个涵盖整个产品组合的、包含每个组件、版本和许可证的可搜索清单 —— 同时附带准确显示版本之间变更内容的变更日志。

OCIDex dashboard showing artifact list

Changelog of the image over time

Details for a particular package

## 功能特性 - **SBOM 接收** — POST 一个 CycloneDX JSON 文档,OCIDex 会验证、解析并存储它,同时保留完整的组件和依赖图数据。 - **制品追踪** — SBOM 按制品(容器镜像、库、应用程序)分组。浏览任何制品的完整版本历史。 - **变更日志** — 精确查看制品的任意两个 SBOM 之间添加、移除或更改了哪些组件。 - **SBOM 差异比对** — 选取任意制品中的任意两个 SBOM 并排比较。 - **组件搜索** — 在所有已接收的 SBOM 中按名称、组或类型查找任何包。查看哪些制品使用了它以及存在多少版本。 - **许可证清单** — 在一个地方汇总 SBOM 中发现的所有许可证,分类为宽松、弱左版 或左版,并提供按制品的摘要。 - **充实管道** — 接收后,后台 worker 会用额外数据充实 SBOM。内置的 OCI 元数据充实器 直接从容器镜像仓库拉取镜像标签、架构和构建信息。 - **OpenAPI 文档** — API 规范在启动时通过 [huma](https://huma.rocks/) 从代码生成。可在 `/docs` 浏览。 ## 快速开始 ### 使用 Docker Compose 获取带有种子数据的运行实例的最快方法: ``` git clone https://github.com/pfenerty/ocidex.git cd ocidex docker compose up -d ``` 这将启动 PostgreSQL、OCIDex API 服务器(端口 8080)和 Web 前端(端口 3000)。 使用来自公共容器镜像的真实 SBOM 填充数据: ``` # 需要 oras、syft 和 curl — 在 Flox 开发环境中可用 flox activate -- ./scripts/seed.sh ``` 然后打开 [http://localhost:3000](http://localhost:3000)。 ### 从源码构建 OCIDex 使用 [Flox](https://flox.dev/) 管理其开发环境(Go、Node、npm、oras、syft 和其他工具)。 ``` git clone https://github.com/pfenerty/ocidex.git cd ocidex flox activate # 安装 Go 工具 (sqlc, golangci-lint) make init # 启动 PostgreSQL (通过 docker-compose,或提供您自己的) docker compose up -d postgres # 配置 cp .env.example .env # edit DATABASE_URL if needed # 运行迁移并构建 make migrate-up make build make frontend # 启动服务器 ./bin/ocidex ``` API 默认在 `:8080` 服务。用于热重载的前端开发: ``` make frontend-dev # Vite dev server on :3000, proxies /api/* to :8080 ``` ### 接收您的第一个 SBOM 使用 [syft](https://github.com/anchore/syft) 生成 SBOM 并将其发送到 OCIDex: ``` syft registry:docker.io/library/nginx:latest -o cyclonedx-json | \ curl -X POST http://localhost:8080/api/v1/sbom \ -H "Content-Type: application/json" \ -d @- ``` ## 技术栈 | 层级 | 技术 | |-------|-----------| | 语言 | Go | | HTTP | [chi](https://github.com/go-chi/chi) + [huma](https://huma.rocks/) (代码优先 OpenAPI 3.1) | | 数据库 | PostgreSQL ([pgx](https://github.com/jackc/pgx) 驱动, [sqlc](https://sqlc.dev/) 查询生成, [goose](https://pressly.github.io/goose/) 迁移) | | 前端 | [SolidJS](https://www.solidjs.com/) + [TanStack Query](https://tanstack.com/query) + [Tailwind CSS](https://tailwindcss.com/) | | API 客户端 | [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) 及生成的 TypeScript 类型 | | 测试 | [matryer/is](https://github.com/matryer/is) (单元), [testcontainers-go](https://golang.testcontainers.org/) (集成) | | 容器 | Docker 多阶段构建 | | 开发环境 | [Flox](https://flox.dev/) | ## 项目结构 ``` cmd/ocidex/ Entry point, server wiring, graceful shutdown internal/api/ HTTP handlers and routing (chi + huma) internal/service/ Business logic interfaces and implementations internal/repository/ Data access layer (sqlc-generated queries) internal/enrichment/ Post-ingestion enrichment pipeline internal/config/ Environment-based configuration db/migrations/ SQL schema migrations (goose) db/queries/ SQL query definitions (sqlc source of truth) web/ SolidJS frontend (Vite + Tailwind) tests/ Integration tests (testcontainers) docs/ Architecture docs, ADRs, development guide ``` ## API 概览 所有端点均在 `/api/v1` 下。完整的 OpenAPI 规范在 `/openapi.json` 提供,交互式文档 UI 在 `/docs`。 | 方法 | 路径 | 描述 | |--------|------|-------------| | `POST` | `/api/v1/sbom` | 接收 CycloneDX JSON SBOM | | `GET` | `/api/v1/sbom` | 列出 SBOM(分页、可过滤) | | `GET` | `/api/v1/sbom/{id}` | 获取 SBOM 详情 | | `GET` | `/api/v1/sbom/{id}/components` | 列出 SBOM 中的组件 | | `GET` | `/api/v1/sbom/{id}/dependencies` | 获取依赖图 | | `GET` | `/api/v1/artifacts` | 列出追踪的制品 | | `GET` | `/api/v1/artifacts/{id}` | 获取制品详情 | | `GET` | `/api/v1/artifacts/{id}/sboms` | 列出制品的 SBOM | | `GET` | `/api/v1/artifacts/{id}/changelog` | 获取 SBOM 之间的变更日志 | | `GET` | `/api/v1/artifacts/{id}/license-summary` | 最新 SBOM 的许可证细目 | | `GET` | `/api/v1/components` | 搜索组件 | | `GET` | `/api/v1/components/distinct` | 去重组件搜索 | | `GET` | `/api/v1/licenses` | 列出所有许可证 | | `GET` | `/api/v1/diff` | 比较任意两个 SBOM | 错误遵循 [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) 问题详情格式。 ## 配置 OCIDex 通过环境变量进行配置: | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `PORT` | `8080` | HTTP 监听端口 | | `DATABASE_URL` | — | PostgreSQL 连接字符串(必填) | | `LOG_LEVEL` | `info` | 日志级别 (`debug`, `info`, `warn`, `error`) | | `ENVIRONMENT` | `development` | 运行环境 | | `CORS_ALLOWED_ORIGINS` | — | 逗号分隔的允许来源 | | `ENRICHMENT_ENABLED` | `false` | 启用接收后充实管道 | | `ENRICHMENT_WORKERS` | `2` | 充实 worker goroutine 数量 | | `ENRICHMENT_QUEUE_SIZE` | `100` | 充实请求队列容量 | | `NATS_ENABLED` | `false` | 启用 NATS JetStream 事件中继 | | `NATS_URL` | `nats://localhost:4222` | NATS 服务器 URL | | `NATS_STREAM_NAME` | `ocidex` | JetStream 流名称 | | `NATS_EVENT_TTL_HOURS` | `24` | 事件保留期(小时) | | `SCANNER_ENABLED` | `false` | 通过 Zot webhook 启用 OCI 镜像仓库自动扫描 | | `ZOT_REGISTRY_ADDR` | `zot:5000` | Zot 镜像仓库地址 (host:port) | | `ZOT_WEBHOOK_SECRET` | — | Zot 随推送通知发送的 Bearer token | | `SYFT_PATH` | `/usr/local/bin/syft` | syft 二进制文件路径 | | `SCANNER_WORKERS` | `2` | 扫描器 worker goroutine 数量 | | `SCANNER_QUEUE_SIZE` | `50` | 扫描器请求队列容量 | ## 文档 | 文档 | 描述 | |----------|-------------| | [架构](docs/ARCHITECTURE.md) | 系统设计、数据模型和组件概述 | | [开发指南](docs/DEVELOPMENT.md) | 编码模式、测试策略和技术栈示例 | | [架构决策记录](docs/adr/) | 17 份记录了每个主要技术选择的 ADR | | [AI 使用说明](docs/AI.md) | 关于 AI 在开发中作用的透明说明 | ## AI 致谢 本项目是在显著的 AI 辅助下构建的。架构决策、技术选型和代码审查由人工主导;实现、重构和文档编写是协作完成的。请参阅 [AI 使用说明](docs/AI.md) 了解全貌。 ## 许可证 [MIT](LICENSE)
标签:CycloneDX, DevSecOps, EVTX分析, Go 语言, GPT, OCI 镜像, OpenAPI, SBOM 差异分析, SBOM 管理, 上游代理, 依赖关系图, 元数据目录, 制品追踪, 占用监测, 变更日志, 容器镜像扫描, 库存搜索, 日志审计, 测试用例, 漏洞管理, 组件库存, 许可证合规, 请求拦截, 资产管理, 跌倒检测, 软件物料清单