docs(evidence): state both Evidence source transports across the site - #799
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aca23bacab
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Re-review requested for |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b2ab21b16
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Accepted, fixed in 15a0309. The clearer fix than qualifying each occurrence with "authenticated" is to name the property that is actually fixed. What trusted configuration pins is the authentication kind, and
The three occurrences you named, plus a fourth in the SSRF bullet that had the same list, now match it:
The diagram line grew from 76 to 80 characters. Rendered at 1728px and measured the rightmost non-white pixel: the source block ends at svg x=677.9 of the 720 viewBox, so it is still not the widest line in that block and nothing overflows. Agreed on "only Evidence Gateway ever holds a source credential" standing as written, and it is unchanged. |
PR #798 corrected the architecture page's claim that an Evidence Gateway source is always reached over HTTP. The same HTTP-only framing survived on seven more pages and in the trust-boundaries diagram, so a reader could still conclude that Evidence must cross a network boundary to reach a source, and that a source always resolves a credential. Both source transports are frozen and coequal: registry.evidence.fixed-http-json-source/v1 and registry.evidence.fixed-sqlite-extract-source/v1. A statement source has no origin, scheme, host, port, method, path, media type, redirect policy, or header; no connection string, secret reference, or authentication kind; and no network path at all. Every rewritten claim is anchored to those contracts, to bundle.schema.yaml, or to the runtime code that enforces it. Left alone, because HTTP is genuinely correct there: consuming a Relay-served API as a source, the DHIS2 and FHIR examples, source-batch, and the OpenAPI authoring path in evidencectl. Security-sensitive corrections found while re-reading the pages against source: - threat-model: the secret-file bullet claimed mode exactly 0600. The code accepts 0400 or 0600 (validate_file_metadata in crates/registry-platform-config/src/secrets.rs). An operator reading the old text would expect a 0400 secret to be refused. - threat-model: V1-I30 was stated as "every native audit event records the closed response-protection mode". The matrix scopes that to authorized-material events; the minimal authorization-refusal event records neither field. The old text overstated audit completeness. - threat-model: V1-I21 signed-JWS availability is scoped to grants issuing under the audience-scoped subject binding, not to every authorized grant. - threat-model: a cited test, file_secret_uses_open_file_owner_and_exact_mode _checks, does not exist. Replaced with the real file_secret_accepts_only_owner_read_and_optional_owner_write_modes. - trusted-context-constraints: the page said Version 1 has no source freshness family at all. A statement source must declare maximumExtractAgeSeconds, and the runtime compares it against the extract's published-at instant before any row is read, failing as DependencyUnavailable. The section heading now says "record freshness", which is the claim that still holds. - diagram: the arrow label read "one fixed HTTP request per evaluation". The ceiling is one request per acquisition stage; search-then-fetch-set runs up to five stages, so the old label was wrong on both transports. - diagram: "only Evidence Gateway holds a source credential" now reads "ever holds", since a statement source holds none. Twelve drifted path:line-range citations were repointed to the symbol names they name, which do not drift. No production code changes. Verified from docs/site: npm run check (exit 0, Vale 0 errors 0 warnings, astro check 0 errors 0 warnings) and npm test (364 pass, 0 fail). The redrawn SVG was rendered with resvg against the installed Public Sans and IBM Plex Mono and measured: rightmost ink at x=677.5 in a 720-wide viewBox, no collisions. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Codex P2: an HTTP JSON source under `authentication.kind: none` resolves no credential, so "an HTTP source is the case where a credential exists" was absolute where the schema is not. State the allowance and its bounds rather than hedge: only a `local` assurance bundle may declare `none`, only at a canonical numeric-loopback origin, and production and evidence-grade bundles reject that kind (`sources.*.authentication.kind` in bundle.schema.yaml). The SVG's "only Evidence Gateway ever holds a source credential" is a capability comparison against Relay, which never holds one, so it stands. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
…erty lists The trust-boundary diagram, its description, the figure alt text, and the SSRF bullet each listed "credential" among the properties trusted configuration fixes on an HTTP source. An HTTP source under the `none` authentication kind resolves no credential, so the list reads as an overclaim even though the fixed property is really the authentication kind. The normative sentence in the same section already says "authentication"; these four now match it. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
15a0309 to
309f4ca
Compare
This reverts commit aae53d5. The v0.24.0 release PR recorded immutable docs archive digests in `docs/site/src/data/archive-lock.yaml`, and #799 merged after it. Its content changes move the built v0.24.0 docset, so the candidate's `archive:snapshot --verify-lock` step now fails with `archive bundle v0.24.0 does not match its immutable lock entry`. A locked entry cannot be re-recorded: `assertArchiveLockImmutable` rejects any change to an existing entry, and `addArchiveLockEntry` refuses to overwrite one. The release therefore requires `main` to carry the content the lock was recorded against. This revert restores a tree byte-identical to the preparation commit b227235. Re-land #799 immediately after v0.24.0 publishes; the change is sound and belongs in the next release. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
This restores aae53d5 (#799), reverted by d1a6c7b so that protected main carried the docs content the v0.24.0 immutable archive lock was recorded against. v0.24.0 has published, and registry-docs-v0.24.0.tar.gz is now a release asset whose sha256 equals the archive-lock bundle digest. assemble-archives restores a published bundle in preference to rebuilding one, so the archived v0.24.0 docset no longer draws its bytes from the checked-out tree and docs content on main can move without disturbing it. Confirmed locally: npm run check:archives reports 3 restored, 0 bootstrapped. The docs/site tree is byte-identical to the original #799 merge. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
This restores aae53d5 (#799), reverted by d1a6c7b so that protected main carried the docs content the v0.24.0 immutable archive lock was recorded against. v0.24.0 has published, and registry-docs-v0.24.0.tar.gz is now a release asset whose sha256 equals the archive-lock bundle digest. assemble-archives restores a published bundle in preference to rebuilding one, so the archived v0.24.0 docset no longer draws its bytes from the checked-out tree and docs content on main can move without disturbing it. Confirmed locally: npm run check:archives reports 3 restored, 0 bootstrapped. The docs/site tree is byte-identical to the original #799 merge. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Follow-up to #798, which fixed the architecture page's claim that an Evidence
Gateway source is always reached over HTTP. The same HTTP-only framing survived
on seven more pages and in
registry-trust-boundaries.svg. This is the sweep,in one PR.
What was wrong
A reader could conclude from these pages that Evidence Gateway must cross a
network boundary to reach a source, and that a source always resolves a
credential. Neither holds. Both source transports are frozen and coequal:
registry.evidence.fixed-http-json-source/v1(
products/evidence/contracts/source-contract.yaml)registry.evidence.fixed-sqlite-extract-source/v1(
products/evidence/contracts/sqlite-extract-source-contract.yaml)A statement source has no origin, scheme, host, port, method, path, media type,
redirect policy, or header; no connection string, secret reference, or
authentication kind; and no network path at all. Every rewritten claim is
anchored to those contracts, to
bundle.schema.yaml, or to the runtime codethat enforces it.
Files
explanation/threat-model.mdxexplanation/integration-patterns.mdxexplanation/trusted-context-constraints.mdxexplanation/records-stay-home.mdxstart/evidence-quickstart.mdxconfigure/evidence.mdxsourcesrow of the bundle key tablespec/rs-arc-g.mdxpublic/images/registry-trust-boundaries.svg<desc>Left alone deliberately
"HTTP source" is correct in these places and was not touched: consuming a
Relay-served API as a source, the DHIS2 and FHIR examples,
source-batch(HTTP-only,
bundle.schema.yaml896-900 and 1212), and the OpenAPI authoringpath in
evidencectl.Security review notes
Re-reading these pages against source turned up seven defects. Six are
security-sensitive, and two of them previously let a reader infer a stronger
guarantee than the code provides:
0600.validate_file_metadata()incrates/registry-platform-config/src/secrets.rsaccepts0o400 | 0o600. Anoperator reading the old text would expect a
0400secret to be refused.V1-I30overstated audit completeness. The page said "every native auditevent records the closed response-protection mode". The matrix scopes that to
authorized-material events; the minimal authorization-refusal event records
neither field. Anyone relying on that field being universally present needed
to know.
V1-I21signed-JWS availability is scoped to grants issuing under theaudience-scoped subject binding, not to every authorized grant.
file_secret_uses_open_file_owner_and_exact_mode_checksis not in the tree. Replaced with the real
file_secret_accepts_only_owner_read_and_optional_owner_write_modes. Acitation pointing at nothing is how a security claim survives its proof being
deleted.
A statement source must declare
maximumExtractAgeSeconds, andvalidate_extract_age()compares it against the extract'spublishedAtbefore any row is read, failing as
ProblemCode::DependencyUnavailable. Theheading now says "record freshness", which is the claim that still holds:
that bound is on the extract file's age, not the record's.
ceiling is one request per acquisition stage;
search-then-fetch-setrunsup to five stages, so the old label was wrong on both transports.
"ever holds", since a statement source holds none.
Claims that moved toward a stronger guarantee, and therefore need their
citations checked rather than their prose: the statement transport's
credential-free, network-free, origin-free character; scripts never receiving
statement text or the connection; index binding and named-only parameters. All
rest on
sqlite-extract-source-contract.yaml, which is frozen. If that contractis ever unfrozen or its
transport_absencesblock edited, every one of thosesentences must be re-verified.
Citation drift
Twelve
path:start-endcitations no longer contained the symbol they named.All were repointed to the symbol names themselves, which do not drift. No gate
catches this today; I'd like to propose a checker separately rather than widen
this PR.
Verification
From
docs/site/:The redrawn SVG was rendered with
resvgagainst the installed Public Sans andIBM Plex Mono, then measured: rightmost ink at x=677.5 in a 720-wide viewBox, no
collisions, every label inside its box.
No production code changes.