repo-manager/docs/sbom-nexus-client-contract_v1.md
tegwick e6cc18bf18 feat(sbom): project immutable Forgejo source refs
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-22 23:34:01 +02:00

145 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SBOM Nexus client contract v1
Repo Manager consumes SBOM Nexus; it does not implement a second scanner,
snapshot store, freshness model, licence classifier, or catch-up scheduler.
This contract pins the boundary used by `RMGR-WP-0011`.
## Authority modes
| Mode | Surface | Authoritative | Persisted | Advances Nexus state |
| --- | --- | --- | --- | --- |
| Local preview | `rmgr sbom scan|licence-report``sbom-nexus scan` | no | no | no |
| Service operation | configured SBOM Nexus HTTP client | yes | Nexus decides | yes, according to the route outcome |
Every compatibility-command result carries:
```json
{
"repo_manager_context": {
"mode": "local-preview",
"authoritative": false,
"persisted": false,
"advances_last_attempt_at": false,
"advances_last_success_at": false,
"creates_snapshot_history": false
}
}
```
Writing preview JSON to a file creates optional local evidence only. It does
not turn the result into an authoritative snapshot or ingest receipt.
## Pinned snapshot envelope
Repo Manager accepts `schema: sbom-nexus.snapshot.v1`. Additive fields are
compatible. An unknown schema or omission of any of these fields is a contract
error: `schema`, `ok`, `repo_slug`, `source_revision`, `generated_at`,
`entry_count`, `entries`, `sources`, `licence_report`, and `errors`.
Repo Manager may project the existing licence-report compatibility shape from
that envelope. It must not recalculate licence groups or copyleft signals.
## Authoritative service routes
The production client may consume these Nexus-owned routes without depending
on Nexus tables or migrations:
| Purpose | Route |
| --- | --- |
| Upsert repository projection | `PUT /repositories/{repo_slug}` |
| Read repository projections | `GET /repositories/` |
| Persist scan outcome | `POST /sbom/{repo_slug}/ingest` |
| Persist terminal skip outcome | `POST /sbom/{repo_slug}/skip` |
| Read latest repository SBOM | `GET /sbom/{repo_slug}` |
| Read immutable snapshot detail | `GET /sbom/snapshots/{snapshot_id}` |
| Read licence report | `GET /sbom/report/licences/` |
Calls use a bounded timeout and surface deterministic transport, HTTP, and
contract errors. Credentials enter only through the platform runtime path and
must never appear in files, command output, or logs.
## Authoritative client usage
The Python client requires `SBOM_NEXUS_URL`. `SBOM_NEXUS_TIMEOUT_SECONDS`
defaults to 30 seconds and is bounded to 0.1300 seconds. An optional
`SBOM_NEXUS_TOKEN` may be injected at runtime; its value is excluded from
configuration representations and all structured errors.
```python
from repo_manager.sbom_client import SBOMNexusClient, SBOMNexusConfig
client = SBOMNexusClient(SBOMNexusConfig.from_environment())
client.upsert_repository(
"example",
nexus_checkout_path="/srv/controlled/example/abc123",
active=True,
)
receipt = client.ingest_repository(
"example",
expected_source_revision="abc123",
operation_id="stable-operation-id",
)
latest = client.latest_snapshot("example")
report = client.licence_report()
```
The client URL-escapes repository slugs, accepts only object responses with the
pinned route-specific fields, and adds an `authoritative-service` context. It
does not retry mutations automatically: a timeout or server failure can occur
after Nexus commits. Structured errors therefore expose
`mutation_may_have_committed`; callers must resolve the stable operation id or
read the resulting snapshot before deciding whether to retry.
When an expected source revision is supplied, an `ingested` receipt for any
other revision fails closed as `source_revision_mismatch` and explicitly notes
that the mutation may already have committed. The checkout path sent to Nexus
is Nexus-local controlled-source identity, never authorization to mount a
workstation path into the cluster.
## Forgejo archive source-reference projection
The `CUST-WP-0064` v1 source mechanism is available through a read-only
resolution command:
```bash
rmgr sbom source-ref --path /path/to/checkout --slug example
```
Repo Manager reads the selected Git remote only to normalize identity. It then
uses the anonymous Forgejo API—not local `HEAD`, the working tree, or a cached
remote-tracking ref—to read repository visibility, default branch, and its full
40-character commit SHA. The result contains `kind: forgejo-archive-v1`, exact
`coulomb/<slug>` identity, `revision`, `observed_ref`, and a canonical UTC
`observed_at`.
V1 returns `supported: false` and no `source_ref` for a missing remote,
non-Coulomb identity, slug mismatch, private repository, unavailable Forgejo
record, invalid branch response, or unresolved full SHA. It never falls back
to a workstation path or local revision.
Projection is an explicit mutation and requires both service configuration and
confirmation:
```bash
export SBOM_NEXUS_URL=https://sbom-nexus.example
rmgr sbom source-ref --path /path/to/checkout --slug example \
--project --confirm-authoritative
```
The projection sends `checkout_path: null` plus the structured source reference.
It succeeds only when Nexus returns the exact same `source_ref`; an older server
that silently ignores the additive field fails closed. This makes the command a
direct readiness probe for the SBOM Nexus side of `CUST-WP-0064`.
## Repository source identity and provenance
Repo Manager remains authoritative for repository slug, active state,
checkout/source identity, and Git revision. An authoritative scan request must
refer to a controlled source artifact or checkout pinned to that revision. It
must not infer identity from a path string or repository name, and it must not
mount a workstation filesystem into the cluster.
`CUST-WP-0064` owns the coordinated source-input topology. Until that topology
is live, local checkout scans remain previews even when their Git revision is
known. SBOM Nexus alone records the resulting authoritative snapshot and
attempt/success history.