feat: a salted transcript chain, evidence bundles and disclosure - #216
Merged
Merged
Conversation
The transcript opens with a header that records the run's inputs, and each fact is committed as a salted leaf in a SHA-256 chain, so the fingerprint survives redaction. Confidentiality levels are ordered integers named in the header, and each fact type has a default level: attestations are public, failed attempts, prompt answers and deviations restricted, persons and material digests confidential. Roles are declared once, and steps name their role by id. Transcript lines put the fields every line has first. rite bundle create packages a run as an evidence bundle: the transcript, the ceremony definition and the artifacts, under an index. rite bundle disclose derives a disclosure at a level from a bundle; withheld lines keep their time, level and checkpoints, so the disclosure verifies to the same fingerprint. rite verify checks both kinds of bundle: a line withheld at or below the threshold fails, a line disclosed above it fails, a disclosure holding the ceremony definition fails, and the index must list every file the transcript records. A report of a disclosure says what it withholds. The transcript writer refuses a level its header does not declare, as the reader does. rite run ends with the commands that verify, report and bundle the run. Before 1.0 the transcript format, the fact vocabulary and the bundle format are 0: they change between releases without a new number, the header's producer names the release, and rite verify warns when another release wrote the transcript. A backend operation names the backend the step ran with in a field of its own; the backend's identity is on its BackendBound fact. Actions record operations through Reporter::backend_operation, which takes the step and the backend from the step being run. The resolver refuses numbers outside the range canonical JSON records exactly (integers within 2^53 - 1). JSON Schemas for the transcript and the bundle index are published under docs/schema, generated from the model types in tests, with descriptions of their own and every bound the format has. Each schema's $id is https://ritely.io/schemas/<release>/, and bundle.json and the transcript's first line name it as $schema. The demo folder holds a bundle of one run, its public disclosure and a report of each. docs/transcript-format.md specifies the transcript for anyone writing a verifier, and docs/evidence-bundles.md describes bundles and disclosures.
They record through Reporter::backend_operation; the imports only compile under the piv and yubikey features, which the workspace lint does not enable.
rite-runtime draws from the operating system through os_random, and rite-openssl from OpenSSL through random_bytes. Each is the only place its crate starts a buffer as zeros and fills it. Transcript salts are decoded straight into their array. The local checks in CONTRIBUTING.md are the CI lint and test commands, including the PIV and YubiKey features.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The transcript opens with a header that records the run's inputs, and each fact is committed as a salted leaf in a SHA-256 chain, so the fingerprint survives redaction. Confidentiality levels are ordered integers named in the header, and each fact type has a default level: attestations are public, failed attempts, prompt answers and deviations restricted, persons and material digests confidential. Roles are declared once, and steps name their role by id. Transcript lines put the fields every line has first.
rite bundle create packages a run as an evidence bundle: the transcript, the ceremony definition and the artifacts, under an index. rite bundle disclose derives a disclosure at a level from a bundle; withheld lines keep their time, level and checkpoints, so the disclosure verifies to the same fingerprint. rite verify checks both kinds of bundle: a line withheld at or below the threshold fails, a line disclosed above it fails, a disclosure holding the ceremony definition fails, and the index must list every file the transcript records. A report of a disclosure says what it withholds. The transcript writer refuses a level its header does not declare, as the reader does. rite run ends with the commands that verify, report and bundle the run.
Before 1.0 the transcript format, the fact vocabulary and the bundle format are 0: they change between releases without a new number, the header's producer names the release, and rite verify warns when another release wrote the transcript.
A backend operation names the backend the step ran with in a field of its own; the backend's identity is on its BackendBound fact. Actions record operations through Reporter::backend_operation, which takes the step and the backend from the step being run.
The resolver refuses numbers outside the range canonical JSON records exactly (integers within 2^53 - 1).
JSON Schemas for the transcript and the bundle index are published under docs/schema, generated from the model types in tests, with descriptions of their own and every bound the format has. Each schema's $id is https://ritely.io/schemas//, and bundle.json and the transcript's first line name it as $schema.
The demo folder holds a bundle of one run, its public disclosure and a report of each. docs/transcript-format.md specifies the transcript for anyone writing a verifier, and docs/evidence-bundles.md describes bundles and disclosures.