fix(assessment): harden capability evidence trust
This commit is contained in:
@@ -360,7 +360,11 @@ windows. Only `active` and `next` entries are trusted; unknown statuses,
|
||||
duplicate key IDs and malformed structured keyrings fail closed, while revoked,
|
||||
disabled and retired entries are ignored. Do not establish this trust file by
|
||||
downloading it in the same rerun. Public JSON responses are bounded to 16 MiB.
|
||||
Use `--json` or `--output PATH` for automation.
|
||||
Use `--json` or `--output PATH` for automation. Evidence and report files are
|
||||
written through a bounded same-directory atomic replacement, with mode `0600`
|
||||
and file and directory `fsync`. All parent directories must already exist, no
|
||||
parent component may be a symlink, and an existing symlink or non-regular output
|
||||
target is rejected.
|
||||
|
||||
Exit status `0` means the assessed release metadata is current, `2` means
|
||||
explicit review is required, and `1` means the schema or trust checks are
|
||||
@@ -385,7 +389,7 @@ that observation to the assessment and signed catalog:
|
||||
--output /var/tmp/govoplan-fit-review.json
|
||||
```
|
||||
|
||||
The collector follows the strict
|
||||
The collector follows the strict version `0.2.0`
|
||||
[`installed-composition-evidence.schema.json`](installed-composition-evidence.schema.json)
|
||||
contract. It enumerates all installed distributions whose normalized name starts
|
||||
with `govoplan-`, compares the enabled assessed package and module-manifest
|
||||
@@ -395,11 +399,18 @@ entries and evidence-backed conclusions.
|
||||
|
||||
For each distribution, the collector also:
|
||||
|
||||
- verifies every supported SHA-256 entry in installed wheel `RECORD` metadata,
|
||||
- verifies every supported SHA-256 immutable wheel-payload entry in installed
|
||||
`RECORD` metadata,
|
||||
within fixed limits of 256 GovOPlaN distributions, 10,000 files and 512 MiB
|
||||
hashed per distribution, 50,000 files and 2 GiB hashed for one collection,
|
||||
and 64 MiB for any single file;
|
||||
- distinguishes immutable VCS commits and archive hashes from editable installs,
|
||||
- accepts package-owned data-file targets below the installation prefix and
|
||||
declared `console_scripts`, while rejecting other traversal, undeclared
|
||||
scripts, paths outside the prefix and leaf symlinks before opening a file;
|
||||
- reports pip-generated, unhashed `__pycache__/*.pyc` entries separately only
|
||||
when their derived source is a hashed payload entry, including generated
|
||||
files below a confined package-owned runtime-data prefix;
|
||||
- distinguishes coherent PEP 610 Git commits and archive hashes from editable installs,
|
||||
local directories, package-index/unknown origins and malformed metadata;
|
||||
- compares a non-editable VCS commit with the assessment commit and, when one is
|
||||
present, the signed catalog `selected_units` commit;
|
||||
@@ -407,16 +418,29 @@ For each distribution, the collector also:
|
||||
and stable error codes. It never writes direct URLs, paths, hostnames,
|
||||
usernames, exception text or file contents.
|
||||
|
||||
`RECORD` agreement proves that the files agree with their installed metadata; it
|
||||
does not make self-consistent metadata a trusted release origin. Similarly, a
|
||||
version string is not artifact integrity. Editable and directory-backed installs
|
||||
`RECORD` `verified` means complete matching coverage of the immutable wheel
|
||||
payload, not every runtime byte. The proof scope exposes the aggregate count of
|
||||
generated unhashed bytecode; runtime activation remains unchecked. `RECORD`
|
||||
agreement proves that payload files agree with installed metadata, but does not
|
||||
make self-consistent metadata a trusted release origin. Similarly, a version
|
||||
string is not artifact integrity. PEP 610 VCS evidence is accepted only for
|
||||
`vcs: git`, a full 40–64 hexadecimal commit, one mutually exclusive provenance
|
||||
form and a coherent bounded URL shape. Editable and directory-backed installs
|
||||
remain mutable even when their small editable-install `RECORD` is valid. Archive
|
||||
or index artifacts without a hash anchored by the assessed release remain
|
||||
unanchored. These conditions cause review rather than being promoted to
|
||||
immutable installed-release proof.
|
||||
|
||||
Use `--installed-evidence PATH` to review evidence collected in a separate
|
||||
environment. Evidence input and output are bounded to 4 MiB. Collection loads
|
||||
Only evidence produced in-process by `--collect-installed-evidence` is a local
|
||||
observation, and it must be no more than five minutes old (with at most 30
|
||||
seconds of future clock skew) at the selected verification time. Use
|
||||
`--installed-evidence PATH` to compare evidence collected in a separate
|
||||
environment. Imported JSON is unsigned and therefore always carries a blocker:
|
||||
it can identify differences but cannot establish checked or valid installed
|
||||
proof. A future signed collector-attestation format is required to cross that
|
||||
boundary. The proof scope records observation mode, collection/evaluation time,
|
||||
freshness, and whether evaluation used current time or an explicit historical
|
||||
override. Evidence input and output are bounded to 4 MiB. Collection loads
|
||||
the `govoplan.modules` entry-point factories in order to read module IDs and
|
||||
manifest versions; that executes installed GovOPlaN manifest code. Run it only
|
||||
inside the installation being assessed and with the same isolation expected for
|
||||
@@ -453,16 +477,35 @@ the tool's deterministic canonicalization.
|
||||
--trusted-keyring /srv/govoplan/trust/catalog-keyring.json \
|
||||
--installed-evidence /srv/govoplan/evidence/installed.json \
|
||||
--boundary-evidence /srv/govoplan/evidence/target-proof.json \
|
||||
--boundary-authority-keyring /srv/govoplan/trust/proof-authorities.json
|
||||
--boundary-authority-keyring /srv/govoplan/trust/proof-authorities.json \
|
||||
--expected-external-provider-subject provider-production
|
||||
```
|
||||
|
||||
With `--installed-evidence`, this command performs comparison and proof-binding
|
||||
diagnostics only: the imported installed document is unsigned, so neither it nor
|
||||
the boundary claim becomes accepted proof. An accepted boundary review requires
|
||||
a trusted orchestrator to retain the direct in-process observation, obtain the
|
||||
external signature over its digest, and call the review library within the
|
||||
five-minute observation window. A future signed collector-attestation format
|
||||
should make that exchange durable across processes.
|
||||
|
||||
Target-environment and production-approval claims must use the assessment's
|
||||
`deployment_profile.id` as `subject_id`. External-provider claims require the
|
||||
operator to supply a bounded opaque expected subject with
|
||||
`--expected-external-provider-subject`; without it, such a claim remains
|
||||
unchecked and blocks. Expected and observed IDs are retained in proof scope.
|
||||
|
||||
The authority keyring is a governance trust root. Do not download or generate it
|
||||
from the proof bundle being checked, and do not reuse catalog signing authority
|
||||
as implicit production authority. A target operator or approver must validate
|
||||
from the proof bundle being checked. The checker rejects proof-authority public
|
||||
keys reused by either the published or independently trusted catalog keyring,
|
||||
and rejects the same proof public-key material assigned to multiple authority
|
||||
IDs. Authority `not_after` is exclusive. A target operator or approver must validate
|
||||
the referenced drill/result artifacts before signing. The rerun verifies the
|
||||
attestation and its bindings; it does not fetch or reinterpret those artifacts.
|
||||
`--verification-time` exists for reproducible historical review. Live admission
|
||||
must use the actual current time.
|
||||
`--verification-time` exists only for reproducible historical review. Supplying
|
||||
it always marks the machine and human report as a **HISTORICAL override**; callers
|
||||
cannot relabel it as current. Live admission must omit it and use the actual
|
||||
current time.
|
||||
|
||||
No boundary bundle or production authority has been supplied for this current
|
||||
assessment. Target environment, provider and production proof therefore remain
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"schema_version": {
|
||||
"const": "0.1.0"
|
||||
"const": "0.2.0"
|
||||
},
|
||||
"evidence_kind": {
|
||||
"const": "govoplan.installed-composition"
|
||||
@@ -125,7 +125,7 @@
|
||||
"required": ["kind", "commit"],
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": ["vcs-commit", "editable-vcs"]
|
||||
"const": "vcs-commit"
|
||||
},
|
||||
"commit": {
|
||||
"type": "string",
|
||||
@@ -170,6 +170,7 @@
|
||||
"status",
|
||||
"hashed_file_count",
|
||||
"permitted_unhashed_file_count",
|
||||
"generated_unhashed_file_count",
|
||||
"unverifiable_file_count",
|
||||
"missing_file_count",
|
||||
"mismatched_file_count"
|
||||
@@ -190,6 +191,9 @@
|
||||
"permitted_unhashed_file_count": {
|
||||
"$ref": "#/$defs/count"
|
||||
},
|
||||
"generated_unhashed_file_count": {
|
||||
"$ref": "#/$defs/count"
|
||||
},
|
||||
"unverifiable_file_count": {
|
||||
"$ref": "#/$defs/count"
|
||||
},
|
||||
@@ -199,7 +203,51 @@
|
||||
"mismatched_file_count": {
|
||||
"$ref": "#/$defs/count"
|
||||
}
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": { "properties": { "status": { "const": "verified" } } },
|
||||
"then": {
|
||||
"properties": {
|
||||
"hashed_file_count": { "minimum": 1 },
|
||||
"permitted_unhashed_file_count": { "minimum": 1 },
|
||||
"unverifiable_file_count": { "const": 0 },
|
||||
"missing_file_count": { "const": 0 },
|
||||
"mismatched_file_count": { "const": 0 }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": { "properties": { "status": { "const": "partial" } } },
|
||||
"then": {
|
||||
"properties": {
|
||||
"hashed_file_count": { "minimum": 1 },
|
||||
"unverifiable_file_count": { "minimum": 1 },
|
||||
"missing_file_count": { "const": 0 },
|
||||
"mismatched_file_count": { "const": 0 }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": { "properties": { "status": { "const": "mismatch" } } },
|
||||
"then": {
|
||||
"anyOf": [
|
||||
{ "properties": { "missing_file_count": { "minimum": 1 } } },
|
||||
{ "properties": { "mismatched_file_count": { "minimum": 1 } } }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": { "properties": { "status": { "const": "unavailable" } } },
|
||||
"then": {
|
||||
"properties": {
|
||||
"hashed_file_count": { "const": 0 },
|
||||
"missing_file_count": { "const": 0 },
|
||||
"mismatched_file_count": { "const": 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"collection_issue": {
|
||||
"type": "object",
|
||||
|
||||
Reference in New Issue
Block a user