Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
145 lines
5.8 KiB
Markdown
145 lines
5.8 KiB
Markdown
# 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.1–300 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.
|