sbomify/sbomify
GitHub: sbomify/sbomify
软件物料清单(SBOM)和安全文档的集中管理平台,支持多格式聚合、合规检测和供应链透明化共享。
Stars: 46 | Forks: 8

[](https://app.sbomify.com/public/product/eP_4dk8ixV/)
[](https://securityscorecards.dev/viewer/?uri=github.com/sbomify/sbomify&sort_by=check-score&sort_direction=desc)
[](https://www.bestpractices.dev/projects/10952)
[](https://join.slack.com/t/sbomify/shared_invite/zt-3na54pa1f-MXrFWhotmZr0YxXc8sABTw)
[](https://github.com/sbomify/sbomify/actions/workflows/ci-cd.yml)
sbomify 是一个软件物料清单 (SBOM) 和文档管理平台,支持自托管或通过 [app.sbomify.com](https://app.sbomify.com) 访问。该平台提供了一个集中位置来上传和管理您的 SBOM 及相关文档,允许您与利益相关者共享或将其公开。
sbomify 后端与我们的 [github actions module](https://github.com/sbomify/sbomify-action) 集成,可从 lock 文件和 docker 文件自动生成 SBOM。
欲了解更多信息,请参阅 [sbomify.com](https://sbomify.com)。
## 功能特性
### SBOM 管理
- 支持 CycloneDX 和 SPDX SBOM 格式(包括 SPDX 3.0)
- 通过 Web 界面或 API 上传 SBOM
- 以多种格式为产品和发布版本生成聚合 SBOM:
- CycloneDX 1.6, 1.7
- SPDX 2.3, 3.0
- 漏洞扫描集成
- 公共和私有访问控制
- 基于工作区的组织结构
### 合规性插件
| Plugin | Type | Standard |
| --------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| NTIA Minimum Elements (2021) | Compliance | [NTIA Minimum Elements for SBOM](https://www.ntia.gov/report/2021/minimum-elements-software-bill-materials-sbom) |
| CISA Minimum Elements (2025 Draft) | Compliance | [CISA 2025 SBOM Minimum Elements](https://www.cisa.gov/sites/default/files/2025-08/2025_CISA_SBOM_Minimum_Elements.pdf) _(Public Comment Draft)_ |
| BSI TR-03183-2 v2.1 (EU CRA) | Compliance | [BSI TR-03183-2: Cyber Resilience Requirements](https://bsi.bund.de/dok/TR-03183-en) |
| FDA Medical Device Cybersecurity (2025) | Compliance | [FDA Cybersecurity in Medical Devices](https://www.fda.gov/media/119933/download) |
| GitHub Artifact Attestation | Attestation | [GitHub Artifact Attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations) |
### 文档管理
- 上传和管理文档工件(规范、手册、报告、合规文档等)
- 将文档与软件组件关联
- 文档版本控制
- 使用可配置 S3 buckets 进行安全存储
- 公共和私有文档共享
### 组织结构
- **Components (组件)**:核心实体,可包含 SBOM 或文档
- **Projects (项目)**:将相关组件组合在一起
- **Products (产品)**:组织多个项目
- **Workspaces (工作区)**:控制访问和权限
### Transparency Exchange API (TEA)
- 实现 [Transparency Exchange API](https://github.com/CycloneDX/transparency-exchange-api/) v0.3.0-beta.2
- 通过 `.well-known/tea` endpoints 进行标准化 SBOM 发现
- 支持跨供应链自动发现和检索 SBOM
## 发布
有关创建新发布版本的信息,请参阅 [RELEASE.md](docs/RELEASE.md)。
## 架构决策记录 (ADRs)
我们使用架构决策记录 来记录本项目中做出的重大架构决策。ADR 为决策提供了背景和理由,帮助当前和未来的贡献者理解为何选择某些方法。
有关所有 ADR,请参阅 [docs/ADR](docs/ADR) 文件夹。
## 部署
有关部署过程的详细信息,包括:
- CI/CD workflow
- 环境设置
- 存储配置
请参阅 [docs/deployment.md](docs/deployment.md)。
有关完整的生产部署说明,请参阅 [the deployment guide](docs/deployment.md)。
## 本地开发
### 开发期间的认证
对于本地开发,认证通过 Django 的 admin 界面处理:
```
# 为本地开发创建 superuser
docker compose \
-f docker-compose.yml \
-f docker-compose.dev.yml exec \
sbomify-backend \
uv run python manage.py createsuperuser
```
然后访问 `http://localhost:8000/admin` 处的 admin 界面登录。
### 开发先决条件
- Python 3.13+
- uv (Python 包管理器)
- Docker (用于运行 PostgreSQL 和 Minio)
- Bun (用于 JavaScript 开发)
#### 安装 uv
- 使用官方安装程序安装 uv:
```
curl -LsSf https://astral.sh/uv/install.sh | sh
```
- 验证安装:
```
uv --version
```
#### 安装依赖项
- 使用 uv 安装 Python 依赖项:
```
# 安装所有依赖,包括开发依赖
uv sync
# 使用 uv 运行命令
uv run python manage.py --help
```
- 使用 Bun 安装 JavaScript 依赖项:
```
bun install
```
### API 文档
API 文档可在以下位置获取:
- 交互式 API 文档 (Swagger UI): `http://localhost:8000/api/v1/docs`
- OpenAPI 规范: `http://localhost:8000/api/v1/openapi.json`
该 API 提供用于管理的 endpoints:
- **SBOMs**: 上传、检索和管理软件物料清单
- **Documents**: 上传、检索和管理文档工件
- **Components**: 管理包含 SBOM 或文档的组件
- **Projects & Products**: 组织和分组组件
- **Workspaces**: 用户管理和访问控制
#### 聚合 SBOM 下载
下载产品和发布版本的聚合 SBOM,并支持格式选择:
```
# 下载 CycloneDX 1.6 (默认) 格式的 release SBOM
curl "https://app.sbomify.com/api/v1/releases/{release_id}/download"
# 下载 SPDX 2.3 格式的 release SBOM
curl "https://app.sbomify.com/api/v1/releases/{release_id}/download?format=spdx"
# 下载 SPDX 3.0 格式的 release SBOM
curl "https://app.sbomify.com/api/v1/releases/{release_id}/download?format=spdx&version=3.0"
# 下载 CycloneDX 1.7 格式的 release SBOM
curl "https://app.sbomify.com/api/v1/releases/{release_id}/download?format=cyclonedx&version=1.7"
# 下载 SPDX 2.3 格式的 product SBOM
curl "https://app.sbomify.com/api/v1/products/{product_id}/download?format=spdx&version=2.3"
```
**支持的格式和版本:**
| Format | Versions | Default |
| --------- | -------- | ------- |
| CycloneDX | 1.6, 1.7 | 1.6 |
| SPDX | 2.3, 3.0 | 2.3 |
这些 endpoints 在运行开发服务器时可用。
### 设置
通过在 shell 中设置或使用 Docker Compose 覆盖文件来配置环境变量。
**重要:添加到 `/etc/hosts`**
为了使开发环境能够与 Keycloak 认证正常配合工作,您必须将以下条目添加到您的 `/etc/hosts` 文件中:
```
127.0.0.1 keycloak
```
启动开发环境(推荐方法):
```
./bin/developer_mode.sh build
./bin/developer_mode.sh up
```
创建本地管理员账户:
```
docker compose \
-f docker-compose.yml \
-f docker-compose.dev.yml exec \
-e DJANGO_SUPERUSER_USERNAME=sbomifyadmin \
-e DJANGO_SUPERUSER_PASSWORD=sbomifyadmin \
-e DJANGO_SUPERUSER_EMAIL=admin@sbomify.com \
sbomify-backend \
uv run python manage.py createsuperuser --noinput
```
访问应用程序:
- Admin 界面: `http://localhost:8000/admin`
- 主应用程序: `http://localhost:8000`
#### 替代方案:本地运行(Django 不在 Docker 中)
- 在 Docker 中启动所需服务:
```
# 同时启动 PostgreSQL 和 MinIO
docker compose up sbomify-db sbomify-minio sbomify-createbuckets -d
```
- 安装依赖项:
```
uv sync
bun install # for JavaScript dependencies
```
- 运行迁移:
```
uv run python manage.py migrate
```
- 启动开发服务器:
```
# 在一个终端中,启动 Django
uv run python manage.py runserver
# 在另一个终端中,启动 Vite
bun run dev
```
### 配置
#### 开发服务器设置
应用程序使用 Vite 进行 JavaScript 开发。以下环境变量控制开发服务器:
```
# Vite 开发设置
DJANGO_VITE_DEV_MODE=True
DJANGO_VITE_DEV_SERVER_PORT=5170
DJANGO_VITE_DEV_SERVER_HOST=http://localhost
# 静态文件和开发服务器设置
STATIC_URL=/static/
DEV_JS_SERVER=http://127.0.0.1:5170
WEBSITE_BASE_URL=http://127.0.0.1:8000
VITE_API_BASE_URL=http://127.0.0.1:8000/api/v1
VITE_WEBSITE_BASE_URL=http://127.0.0.1:8000
```
这些设置可以使用环境变量进行配置。
#### Keycloak 认证设置
Keycloak 现作为 Docker Compose 环境的一部分进行管理。您无需手动运行 Keycloak。
Keycloak 的持久化存储由 Docker 使用命名卷 (`keycloak_data`) 管理。
##### Keycloak 引导
当您使用 Docker Compose 启动开发环境时,Keycloak 会使用位于 `bin/keycloak-bootstrap.sh` 的脚本自动进行引导。此脚本使用环境变量(例如 `KEYCLOAK_REALM`、`KEYCLOAK_CLIENT_ID`、`KEYCLOAK_ADMIN_USERNAME`、`KEYCLOAK_ADMIN_PASSWORD`、`KEYCLOAK_CLIENT_SECRET` 等)来配置 realm、client 和凭据。**您无需编辑脚本本身**——只需在 Docker Compose 配置中设置适当的环境变量即可控制引导过程。
在开发模式下运行时(使用 `docker-compose.dev.yml`),引导脚本会自动:
- **禁用 SSL 要求**,以便于本地开发
- **创建测试用户**用于认证测试:
- **John Doe** - 用户名: `jdoe`, 密码: `foobar123`, 邮箱: `jdoe@example.com`
- **Steve Smith** - 用户名: `ssmith`, 密码: `foobar123`, 邮箱: `ssmith@example.com`
这些特定于开发的配置由 `KEYCLOAK_DEV_MODE` 环境变量控制,仅在运行开发 Docker Compose 堆栈时应用。
要在开发环境中启动 Keycloak(及所有其他服务),只需运行:
```
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
```
Keycloak 将在 处可用。
#### S3/Minio 存储
应用程序使用兼容 S3 的存储来存储文件和资产。在开发中,我们使用 Minio 作为本地 S3 替代品。
- 使用 Docker Compose 运行时,一切都会自动配置
- 本地运行时(Django 在 Docker 外部):
- 确保通过 Docker 运行 Minio:
`docker compose up sbomify-minio sbomify-createbuckets -d`
- 在您的环境变量中设置 `AWS_ENDPOINT_URL_S3=http://localhost:9000`
- 所需的 buckets (`sbomify-media`, `sbomify-sboms`, 以及可选的 `sbomify-documents`) 将自动创建
##### 存储 Buckets
应用程序针对不同类型的内容使用独立的 S3 buckets:
- **Media Bucket**: 用户头像、工作区 logo 和其他媒体资产
- **SBOMs Bucket**: 软件物料清单文件
- **Documents Bucket**: 文档工件(规范、手册、报告、合规文档等)
- 如果未单独配置,文档将自动使用 SBOMs bucket
- 对于生产环境,建议使用单独的 bucket 以便更好地组织和访问控制
您可以访问 Minio 控制台:
- `http://localhost:9001`
- 默认凭据: minioadmin/minioadmin
##### 生产存储配置
对于生产部署,您可以为文档配置独立的 S3 buckets:
```
# 可选:配置专用 documents bucket(推荐用于生产环境)
export AWS_DOCUMENTS_ACCESS_KEY_ID="your-documents-access-key"
export AWS_DOCUMENTS_SECRET_ACCESS_KEY="your-documents-secret-key"
export AWS_DOCUMENTS_STORAGE_BUCKET_NAME="your-documents-bucket"
export AWS_DOCUMENTS_STORAGE_BUCKET_URL="https://your-documents-bucket.s3.region.amazonaws.com"
# 如果未配置,documents 将自动使用 SBOMs bucket
export AWS_SBOMS_ACCESS_KEY_ID="your-sboms-access-key"
export AWS_SBOMS_SECRET_ACCESS_KEY="your-sboms-secret-key"
export AWS_SBOMS_STORAGE_BUCKET_NAME="your-sboms-bucket"
export AWS_SBOMS_STORAGE_BUCKET_URL="https://your-sboms-bucket.s3.region.amazonaws.com"
```
独立 buckets 的优势:
- **安全性**: 针对 SBOM 与文档采用不同的访问策略
- **组织性**: 清晰区分内容类型
- **备份**: 针对不同数据类型的独立备份策略
#### Dependency Track 集成
sbomify 支持与 [Dependency Track](https://dependencytrack.org/) 集成,以进行高级漏洞管理和分析。Dependency Track 集成适用于商业版和企业版计划。
**注意:** Dependency Track 仅支持 CycloneDX 格式的 SBOM。无论工作区配置如何,SPDX SBOM 将自动使用 OSV 扫描。
##### 基于环境的项目命名
当跨多个环境(开发、预发布、生产)使用共享的 Dependency Track 实例时,sbomify 会自动为项目名称添加环境前缀以帮助区分它们:
**示例:**
- **生产环境** (`https://app.sbomify.com`): `prod-sbomify-{component-id}`
- **预发布环境** (`https://staging.sbomify.com`): `staging-sbomify-{component-id}`
- **开发环境** (`https://dev.sbomify.com`): `dev-sbomify-{component-id}`
- **本地环境** (`http://localhost:8000`): `local-sbomify-{component-id}`
**自定义环境前缀:**
您可以通过设置 `DT_ENVIRONMENT_PREFIX` 环境变量来覆盖自动检测:
```
export DT_ENVIRONMENT_PREFIX="my-custom-env"
# 结果为:my-custom-env-sbomify-{component-id}
```
这使得在查看 Dependency Track 仪表板时可以轻松识别项目所属的环境。
##### 所需权限
要与 Dependency Track 集成,您需要创建一个具有以下权限的 API token:
- `BOM_UPLOAD`
- `PROJECT_CREATION_UPLOAD`
- `VIEW_PORTFOLIO`
- `VIEW_VULNERABILITY`
您可以在 Dependency Track 实例的 **Administration → Access Management** 下创建 token(使用那里的工作区管理界面)。
##### DT 配置
1. **通过 Django admin 添加 Dependency Track Server**:
- 导航至 `/admin/vulnerability_scanning/dependencytrackserver/`
- 点击 "Add Dependency Track Server"
- 填写服务器详细信息:
- **Name**: 服务器的友好名称
- **URL**: 您的 Dependency Track 实例的基础 URL
- **API Key**: 具有所需权限的 Token
- **Priority**: 数字越小 = 负载均衡优先级越高
- **Max Concurrent Scans**: 同时上传 SBOM 的最大数量
2. **配置工作区设置**:
- 商业版/企业版工作区可以在 **Settings → Integrations** 中选择 Dependency Track
- 企业版工作区可以选择配置自定义 Dependency Track 实例
- 商业版工作区使用共享服务器池
##### DT 功能特性
- **自动漏洞扫描**:
- 社区版工作区:使用 OSV 进行每周漏洞扫描
- 商业版/企业版工作区:使用 Dependency Track 每 12 小时更新一次漏洞信息
- **负载均衡**: 在多个 Dependency Track 服务器之间分配扫描任务
- **健康监控**: 自动服务器健康检查和容量管理
- **历史跟踪**: 完整的扫描结果历史记录,用于趋势分析
- **统一结果**: 跨 OSV 和 Dependency Track 的一致漏洞数据格式
### 行测试用例
在运行测试之前,您需要启动 docker-compose.tests.yml:
```
docker compose -f docker-compose.tests.yml up -d
```
使用 Django 的 test profile 运行测试:
```
# 运行所有测试并生成覆盖率
uv run coverage run -m pytest
# 运行特定测试组
uv run coverage run -m pytest core/tests/
uv run coverage run -m pytest sboms/tests/
uv run coverage run -m pytest teams/tests/
# 在失败时运行 debugger
uv run coverage run -m pytest --pdb -x -s
# 生成覆盖率报告
uv run coverage report
```
测试覆盖率必须至少达到 80% 才能通过 CI 检查。
### E2E 快照 (截图) 测试
该项目包含端到端快照测试,用于捕获 UI 的截图并将其与基准图像进行比较。这有助于确保不同屏幕尺寸下以及代码更改后的视觉一致性。
#### E2E 测试先决条件
在运行 e2e 快照测试之前,您需要:
**构建 JavaScript 资产:**
```
bun run build
```
这确保在截图之前所有静态资产(JavaScript, CSS)都是最新的。
#### 编写快照测试
以下是编写快照测试的抽象示例:
```
@pytest.mark.django_db
@pytest.mark.parametrize("width", [1920, 992, 576, 375])
class TestYourPageSnapshot:
def test_your_page_snapshot(
self,
authenticated_page,
your_test_fixtures, # noqa: F811
snapshot,
width: int,
) -> None:
# Navigate to the page you want to test
authenticated_page.goto("/your-page")
authenticated_page.wait_for_load_state("networkidle")
# Get or create baseline screenshot (stored in __snapshots__)
baseline = snapshot.get_or_create_baseline_screenshot(authenticated_page, width=width)
# Take current screenshot
current = snapshot.take_screenshot(authenticated_page, width=width)
# Compare screenshots
snapshot.assert_screenshot(baseline.as_posix(), current.as_posix())
```
**关键组件:**
- 使用 `@pytest.mark.django_db` 启用数据库访问
- 使用 `@pytest.mark.parametrize("width", [...])` 测试多种屏幕尺寸
- 注入 `authenticated_page` fixture 用于浏览器自动化
- 注入 `snapshot` fixture 用于截图管理
- 使用 `get_or_create_baseline_screenshot()` 获取基准(如果缺失则创建)
- 使用 `take_screenshot()` 捕获当前状态
- 使用 `assert_screenshot()` 进行比较
#### 运行 E2E 快照测试
构建资产后,您可以使用专用的 E2E docker-compose 堆栈来运行快照测试:
```
# 启动测试 stack(数据库、chromium 和 tests container)
docker compose -f docker-compose.tests.yml up -d
# 在 tests container 内运行所有 E2E snapshot 测试
docker compose -f docker-compose.tests.yml exec tests uv run pytest sbomify/apps//tests/e2e/
# 运行单个 E2E snapshot 测试(示例)
docker compose -f docker-compose.tests.yml exec tests uv run pytest \
sbomify/apps//tests/e2e/test_your_page.py::TestYourPageSnapshot::test_your_page_snapshot[1920]
```
#### 处理快照测试
**新测试**
当您编写新的快照测试时,它会自动在 `__snapshots__` 目录(位于 `sbomify/apps//tests/e2e/__snapshots__/`)中创建基准截图。只需运行测试并验证生成的截图看起来是否正确。
**现有测试 - 通过**
如果测试已存在并通过,则一切按预期工作。无需操作。
**现有测试 - 失败**
如果测试失败,请检查 `__diffs__` 目录(位于 `sbomify/apps//tests/e2e/__diffs__/`)以查看更改内容。差异图像显示基准截图与当前截图之间的差异。
**更新过时的快照**
如果 `__diffs__` 中的差异截图显示新的视觉状态是正确的(即基准快照已过时),您需要更新基准:
1. 从 `__snapshots__` 中删除过时的快照文件
2. 重新运行测试 - 它将使用当前状态自动重新创建基准截图
**示例:**
```
# 删除过期的 snapshot
rm sbomify/apps//tests/e2e/__snapshots__/test_your_page_snapshot[1920].jpg
# 重新运行测试以创建新基线
uv run pytest sbomify/apps//tests/e2e/test_your_page.py::TestYourPageSnapshot::test_your_page_snapshot
```
有关实际示例,请参阅 `sbomify/apps/core/tests/e2e/test_dashboard.py`。
### 测试数据管理
应用程序包含管理命令,以帮助您在开发环境中设置和管理测试数据:
```
# 使用示例 SBOM 数据创建测试环境
# 如果未指定 workspace,则使用数据库中的第一个 workspace
# (management command 保留了旧的 --team-id flag 名称以保持兼容性)
python manage.py create_test_sbom_environment
# 为特定 workspace 创建测试环境(仍使用旧的 --team-id flag)
python manage.py create_test_sbom_environment --team-id=your_team_id
# 清理现有测试数据并创建新环境
python manage.py create_test_sbom_environment --clean
# 清理所有 workspace 的所有测试数据
python manage.py cleanup_test_sbom_environment
# 清理特定 workspace 的测试数据(仍使用旧的 --team-id flag)
python manage.py cleanup_test_sbom_environment --team-id=your_team_id
# 预览将被删除的内容(dry run)
python manage.py cleanup_test_sbom_environment --dry-run
```
这些命令将:
1. 创建测试产品、项目和组件
2. 从测试文件加载真实的 SBOM 数据(SPDX 和 CycloneDX 格式)
3. 设置所有实体之间的正确关系
4. 允许您在需要时清理测试数据
测试数据按来源(例如 hello-world 和 sbomify)而不是按格式分组,因此每个组件都将附加 SPDX 和 CycloneDX SBOM。
注意:您必须在数据库中至少拥有一个工作区,才能在不指定旧版 `--team-id` 标志的情况下使用这些命令。
### JS 构建工具
对于前端 JS 工作,需要设置 JS 工具。
#### Bun
```
curl -fsSL https://bun.sh/install | bash
```
在 `package.json` 同级的文件夹中:
```
bun install
```
#### Linting
对于 JavaScript/TypeScript linting:
```
# 检查 linting 问题(用于 CI,也可在本地运行)
bun lint
# 自动修复 linting 问题(仅限本地开发)
bun lint-fix
```
#### 运行 vite dev server
```
bun run dev
```
### Pre-commit 检查
该项目使用 pre-commit hooks 来确保代码质量和一致性。hooks 会检查:
- 代码格式化 (ruff-format)
- Python linting (ruff)
- 安全问题 (bandit)
- Markdown 格式化
- TypeScript 类型检查
- JavaScript/TypeScript linting
- 合并冲突
- Debug 语句
设置 pre-commit:
- 安装 pre-commit hooks:
```
uv run pre-commit install
```
- 手动运行 pre-commit 检查:
```
# 检查所有文件
uv run pre-commit run --all-files
# 仅检查暂存文件
uv run pre-commit run
```
## 生产部署
### 生产环境先决条件
- Docker 和 Docker Compose
- 兼容 S3 的存储(如 Amazon S3 或 Google Cloud Storage)
- PostgreSQL 数据库
- 用于生产部署的反向代理(例如 Nginx)
### Docker Compose 配置
提供了 `docker-compose.prod.yml` 文件用于类生产设置。**注意:** 此配置未经过充分测试,不建议按原样用于实际生产环境。提供的设置仅用于演示和预发布目的,未来将会更新和改进。
对于生产部署,为签名 URL 生成一个安全的签名 salt:
```
# 为 signed URLs 生成安全 signing salt
export SIGNED_URL_SALT="$(openssl rand -hex 32)"
```
`SIGNED_URL_SALT` 用于为产品/项目 SBOM 中的私有组件的下载 URL 进行签名。
要尝试类生产堆栈:
```
docker compose -f docker-compose.yml -f docker-compose.prod.yml build
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
您需要设置适当的环境变量,并确保您的反向代理、存储和数据库已安全配置。
标签:API集成, CycloneDX, DevSecOps, Docker, GitHub Actions, IP 地址批量处理, SaaS, SBOM, SPDX, 上游代理, 产品安全, 人工智能安全, 信任中心, 制品仓库, 可观测性, 合规性, 安全管理, 安全防御评估, 开源治理, 文档安全, 文档管理, 测试用例, 漏洞探索, 硬件无关, 私有化部署, 自动笔记, 请求拦截, 跌倒检测, 软件开发工具包, 软件物料清单, 逆向工具, 防御规避