01Record file
AttestScope Protocol · version 0.1.1. One JSON file per record, UTF-8, named <Issuer name> <record_id>.json (Riftveil: Riftveil RV-261026-143205-7K3M-Q9XD-2B8F.json).
{
"format": "attestscope",
"version": "0.1.1",
"record_id": "RV-261026-143205-7K3M-Q9XD-2B8F",
"issuer": "RV",
"origin": "generated",
"issued_at": "2026-10-26T14:32:05Z",
"assessment": { "protocol": "1.0.0", "model": "claude-sonnet-5", "assistant": "riftveil.ai", "language": "en" },
"content": { "project": "…", "context": "…", "report": "…" },
"proof": {
"fingerprint": { "alg": "sha-256", "profile": "riftveil-report-v1", "value": "…64 hex…" },
"seal": { "value": "S1-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX", "verify": "https://riftveil.ai/api/verify" },
"signature": { "alg": "ed25519", "key": "ed25519-1", "value": "…86 base64url characters…", "keys": "https://riftveil.ai/keys.json" }
},
"notice": "…"
}
| Field | Rule |
|---|---|
format, version |
"attestscope" and "0.1.1". Files of version 0.1 read "assay-record" and "0.1-draft"; they stay valid and every verifier MUST still read them. |
issued_at |
MUST repeat the date and time of the record_id. A verifier MUST reject a file where they differ, and a record whose ID is dated in the future. |
origin |
generated (the issuer produced the report) or registered (produced elsewhere, only its fingerprint was sent). Covered by the seal and the signature through their label. |
assessment |
For riftveil-report-v1, protocol and model are in the fingerprint. For riftveil-content-v1, assistant is. language is informative. |
content |
The exact texts. They stay with the person who holds the file; the issuer keeps nothing. |
proof.fingerprint |
Recomputed by every verifier from content (and the fields above). Never trusted as written. |
proof.seal |
Checked by the issuer's endpoint against the recomputed fingerprint. |
proof.signature |
REQUIRED in version 0.1.1. The issuer's Ed25519 signature over the same message as the seal. Anyone can check it with the issuer's published public key, without asking the issuer. See Record ID, seal and signature. |
proof.timestamps |
OPTIONAL. A list of time stamps over the same message, from time-stamping authorities (RFC 3161). See Record ID, seal and signature. |
notice |
Informative. Not covered by any fingerprint. |
Two forms of the same record
| Form | Holds | Kept by | Used for |
|---|---|---|---|
| Record file | Everything above, content included |
The signer, with the PDF, in the decision file | Verifying that a text is intact |
| Register entry (planned, 0.2) | Everything except content |
A register: Microsoft 365, the client's servers, or hosted (planned) | Counting, following up, auditing the structure |
Version 0.1.1 defines the record file; the register entry is planned for 0.2.
A register never needs the project: the fingerprint lets it prove which content a record belongs to without holding it. Whoever holds the record file holds the content: share it as you would share the report.
Follow-up and decision (follow_up, optional)
Filled in by the person who decides, never by a model, after the report. It has its own fingerprint, its own seal and its own signature, so it can be added without touching the proof of the assessment.
"follow_up": {
"profile": "riftveil-decision-v2",
"verified_by": { "last_name": "…", "first_name": "…", "role": "…" },
"checked": "What the person checked themselves",
"questions": [ { "n": 1, "question": "…", "suggested_owner": "CFO", "assigned_to": "…" } ],
"decision": "proceed | conditions | stop",
"conditions": "…",
"place": "…",
"signature": { "method": "drawn | typed", "typed": "…", "image": "data:image/png;base64,…" },
"final_document": { "name": "Board memo.pdf", "size": 284113, "sha256": "…64 hex…" },
"previous": { "profile": "riftveil-decision-v2", "…": "the follow-up this one completes, with its proof" },
"decided_at": "2026-10-26T16:05:12Z",
"proof": {
"fingerprint": { "alg": "sha-256", "profile": "riftveil-decision-v2", "value": "…64 hex…" },
"seal": { "value": "S1-…", "sealed_at": "2026-10-26T16:05:12Z", "verify": "https://riftveil.ai/api/verify" },
"signature": { "alg": "ed25519", "key": "ed25519-1", "value": "…", "keys": "https://riftveil.ai/keys.json" }
}
}
| Field | Rule |
|---|---|
profile |
riftveil-decision-v2 in a 0.1.1 file. riftveil-decision-v1 (version 0.1) appears in a 0.1.1 file only under previous, when a 0.1 file was completed. |
| Fingerprint input | riftveil-decision-v2: JSON.stringify({ v: 2, id, report_fingerprint, verified_by, checked, questions, decision, conditions, place, signature, final_document, previous }), with every field present: empty strings when not filled, final_document as { name: "", size: 0, sha256: "" } when absent, previous as { fingerprint, seal, sealed_at } of the follow-up it completes, or three empty strings. report_fingerprint is the recomputed fingerprint of the assessment: a follow-up belongs to one report only. riftveil-decision-v1: the same object without final_document and previous, with v: 1. |
signature |
A simple electronic signature made on screen by the person who decides. Not to be confused with proof.signature, the issuer's signature. The seal and the issuer's signature prove when the follow-up existed and that it has not changed, never who wrote it. |
final_document |
OPTIONAL. The document that actually goes out after the decision (a memo, a contract, a deck): its file name, its size in bytes and the SHA-256 of its bytes, computed on the signer's device. The document itself is never sent. A verifier can then say whether a given document is the one that was decided. |
previous |
OPTIONAL. When a person completes a sealed follow-up later (answers to the questions, conditions met), the new follow-up holds the earlier one in full, with its proof, and its fingerprint covers the earlier fingerprint, seal and seal time. Each earlier follow-up keeps its own proof. The earlier follow-up MUST be sealed, and sealed strictly before the one that completes it. A file SHOULD NOT hold more than 20 earlier follow-ups. |
decided_at |
Informative, set by the signer's device. Not covered by the fingerprint or the seal: the proven time is proof.seal.sealed_at. |
proof.seal |
Issued by the issuer on the follow-up fingerprint and the issuer's clock (sealed_at); it requires a valid seal of the assessment. Only fingerprints are sent: names, decision, signature and documents never leave the signer's device. |
proof.signature |
REQUIRED when the follow-up of a 0.1.1 file is sealed. The issuer's Ed25519 signature over the same message as the follow-up seal. |
| Unsealed follow-up | Allowed. A verifier shows it as present but unsealed: nothing proves when it was written or that it was not changed. |
| Who wrote it | Not proven. Anyone who holds the record file can seal a follow-up for it, under any name, and several follow-ups can exist for one report. The seal and the issuer's signature prove when a follow-up existed and that it has not changed since; identity needs the organisation's account or a qualified signature (planned). A verifier MUST NOT present the name in a follow-up as verified. |
Later versions will add outcome (what became of the decision) and readers[] (the chain of second readers), each with its own fingerprint.
02Record ID, seal and signature
AttestScope Protocol · version 0.1.1 · normative for every implementation, including Riftveil.
The key words MUST, MUST NOT, SHOULD and MAY are used as in RFC 2119.
1. Format
<ISSUER>-<YYMMDD>-<HHMMSS>-<RRRR>-<RRRR>-<RRRR>
RV-261026-143205-7K3M-Q9XD-2B8F
| Part | Rule |
|---|---|
ISSUER |
2 to 6 letters A to Z, registered in ISSUERS.md. RV is Riftveil. An implementation MUST NOT use a prefix it has not registered. XT is reserved for tests and MUST NOT appear in a record used for a decision. |
YYMMDD |
UTC date at which the ID is assigned (years 2000 to 2099). |
HHMMSS |
UTC time at which the ID is assigned, to the second, from a clock synchronised with a public time source. |
RRRR-RRRR-RRRR |
60 bits from a cryptographically secure random generator, written in Crockford base32 (0-9 A-Z without I L O U), 12 characters in 3 groups of 4. |
Pattern: ^[A-Z]{2,6}-\d{6}-\d{6}-[0-9A-HJKMNP-TV-Z]{4}-[0-9A-HJKMNP-TV-Z]{4}-[0-9A-HJKMNP-TV-Z]{4}$
2. Assignment
- The ID MUST be assigned by code, at the moment the record is created.
- The ID MUST NOT be produced, suggested or completed by a language model. Models repeat "random" values; an ID written by a model is not unique.
- The ID MUST NOT be derived from the content (a hash of the project or of the report): two identical projects assessed twice are two records.
- An ID MUST NOT be reused, even for a new version of the same record. A new version gets a new ID and points to the previous one.
- Readers MUST accept lower case and spaces; the canonical form is upper case with hyphens.
3. Why duplicates are practically excluded
- Two issuers cannot collide: the prefixes differ.
- Within one issuer, two IDs can only collide if they are assigned in the same second and draw the same 60 random bits (1 chance in 1.15 × 10¹⁸ for any pair).
- At 1 million records a day for one issuer, the probability of a single duplicate is about 1 in 500 million per year. At 1,000 records per second, about 1 in 70,000 per year.
- This is a probability, not a mathematical impossibility. An issuer that needs absolute uniqueness MAY also check each new ID against its own register and draw again on a match; it MUST NOT shorten the random part to do so.
4. Seal
An issuer MUST seal each record of version 0.1.1, so that it can confirm, without storing anything, that it issued the ID for this content. (In version 0.1 the seal was recommended.)
- Fingerprint. SHA-256, in hexadecimal, of the content the issuer defines as the record content. The definition (profile) MUST be published and MUST include the ID whenever the issuer produced the content itself.
- Message.
"<label>|" + id + "|" + fingerprint, in UTF-8. For a follow-up:"<label>|" + id + "|" + fingerprint + "|" + sealed_at. - Seal.
S<k>-followed by the first 160 bits ofHMAC-SHA256(key_k, message), in Crockford base32, 8 groups of 4.kis the key number; a new key gets a new number and old keys stay available for verification. - One label per origin. An issuer that both produces reports and registers reports produced elsewhere MUST use a different label for each, so that a seal can never be presented as the other origin. The follow-up has its own label.
- Key. It MUST stay secret with the issuer, in a secret store, never in code, a shared file or a conversation.
- Verification endpoint. The issuer MUST publish one that answers valid or not valid, and the origin, for
{ id, fingerprint, seal }, and stores nothing.
A valid seal shows that the issuer assigned the ID, at the time given by its clock, for this fingerprint and this origin. A seal concerns date and integrity; the substance stays with the person who signs.
Legal scope. A seal defined in this section is a code computed by the issuer with a secret key. It shows that the issuer assigned the ID, at the time given by the issuer's clock, for this fingerprint and this origin.
5. Signature
Since version 0.1.1, the issuer also signs each message it seals, with a public-key signature. A seal can only be checked by the issuer; a signature can be checked by anyone, with the issuer's public key, without asking the issuer.
- Algorithm. Ed25519 (RFC 8032), pure, without pre-hashing.
- Message. Exactly the message of the seal (section 4), byte for byte, in UTF-8. The signature therefore covers the same ID, fingerprint, origin and, for a follow-up, seal time.
- Encoding. The 64-byte signature in base64url (RFC 4648, section 5), without padding: 86 characters. Only the canonical encoding is valid: a verifier MUST reject a value whose last character carries non-zero spare bits. Neither the signature nor the seal may be used as an identifier.
- Field.
proof.signaturein the record,follow_up.proof.signaturein the follow-up:{ "alg": "ed25519", "key": "<key id>", "value": "<base64url>", "keys": "<URL of the key list>" }.keysis informative: anyone can write a file, so a verifier MUST NOT use it to choose the key list (section 6). - Required. A 0.1.1 file MUST carry
proof.signature, and a sealed follow-up of a 0.1.1 file MUST carryfollow_up.proof.signature. An issuer that has no signing key writes version 0.1 files. - Private key. It MUST be created and kept by the issuer in a secret store, never in code, a shared file or a conversation. It MUST NOT be the sealing key. It MUST be available only to the production service of the issuer, never to test or preview deployments reachable by others; an issuer SHOULD also bind signing to its production host name.
- Signing later (countersignature). An issuer MAY sign, at a later time, the message of a report whose seal it has just checked, only when the record is dated before the issuer started signing (
valid_fromof its first key). This lets a 0.1 record become a 0.1.1 record when a follow-up is added. A verifier MUST show such a signature as made after the date of the record. An issuer MUST NOT sign later a report dated after it started signing: such a record already carries its signature, so a stolen sealing key cannot be turned into new signatures for it.
A valid signature shows that the holder of the issuer's private key signed this message. It says nothing more than the seal, and nothing less: it concerns date and integrity, never the substance.
6. Public keys
The issuer MUST publish its public keys in a key list, at a fixed address registered with its prefix in ISSUERS.md, and SHOULD publish the same list in at least two other places it does not host on the same server. A verifier MUST take the key list from the address registered for the prefix of the record_id (or from a copy of that list it already trusts), never from the record file. Riftveil: https://riftveil.ai/keys.json, keys/riftveil.json in the AttestScope specification repository on GitHub, and https://attestscope.ai/keys/riftveil.json.
{
"issuer": "RV",
"updated": "2026-10-26",
"rules": "…",
"keys": [
{
"id": "ed25519-1",
"alg": "ed25519",
"public_key": "…43 base64url characters…",
"status": "active",
"valid_from": "2026-10-26",
"valid_until": null,
"compromised_at": null
}
]
}
| Field | Rule |
|---|---|
id |
ed25519-<n>, numbered like the sealing keys. A number is never reused. |
public_key |
The 32-byte public key, base64url without padding. |
status |
active (signs today), retired (no longer signs; its signatures stay valid) or compromised. |
valid_from, valid_until |
Dates (UTC) between which the key signed. valid_until is null while the key is active. |
compromised_at |
For a compromised key: the date from which its private part may have been known to someone else. |
issuer, updated, rules |
The issuer prefix, the date of the last change, and the rules of the list in plain words. Informative. |
Rules of the list:
- No key is ever removed from the list. A retired key stays, with its dates.
- A compromised key stays on the list, marked
compromisedand dated. A verifier MUST NOT report a signature made with it as valid on its own, whatever its date; the record then needs other evidence (a time stamp, a register). - A verifier MUST show when the time of a record (the time in its ID, or
sealed_atfor a follow-up) is beforevalid_fromof the key that signed it (a signature made later, see section 5), and MUST NOT report as valid a signature over a record dated aftervalid_until. - A verifier MUST NOT accept, as a valid record of this issuer, an unsigned file (version 0.1) whose ID is dated after the issuer started signing: its signature has been removed.
- The three published copies MUST be identical. A verifier that finds a difference MUST NOT rely on the list.
- The issuer keeps checking its HMAC seals with every sealing key for at least twelve months after announcing that it will stop checking them.
7. Time stamps
proof.timestamps (and follow_up.proof.timestamps) is an OPTIONAL list. Each entry is a time stamp over the SHA-256 of the same message as the seal and the signature:
"timestamps": [
{ "type": "rfc3161", "tsa": "Name of the authority", "imprint": "…64 hex…", "token": "…base64 of the DER TimeStampToken…" }
]
| Field | Rule |
|---|---|
type |
rfc3161. Other types MAY be defined later. |
tsa |
Name of the time-stamping authority, informative. |
imprint |
SHA-256, in hexadecimal, of the message (section 4). It MUST equal the message imprint inside the token. |
token |
The RFC 3161 TimeStampToken, DER, in base64. |
A time stamp proves the date independently of the issuer. A time stamp issued by a qualified trust service provider under a qualified time-stamping service is a qualified electronic time stamp within the meaning of Regulation (EU) No 910/2014. An organisation MAY use its own time-stamping authority. Several time stamps MAY be added to the same record. At Riftveil, time stamps from a third-party authority are planned as an option with AttestScope traceability; Riftveil adds none today. The date and time of the issuer's clock, sealed and signed (issued_at through the ID, sealed_at), are the issuer's time stamp (at Riftveil: the Riftveil time stamp).
8. Riftveil profiles
| Origin | Label | Profile | Fingerprint input |
|---|---|---|---|
| generated on riftveil.ai | riftveil-seal-v1 |
riftveil-report-v1 |
JSON.stringify({ v: 1, id, protocol, model, project, context, report }) |
| produced elsewhere, registered | riftveil-register-v1 |
riftveil-content-v1 |
JSON.stringify({ v: 1, assistant, project, context, report }) |
| follow-up and decision (0.1.1) | riftveil-decision-v1 |
riftveil-decision-v2 |
see record-file.md |
| follow-up and decision (0.1) | riftveil-decision-v1 |
riftveil-decision-v1 |
see record-file.md |
The label of the follow-up stays riftveil-decision-v1 for both profiles: the profile version is inside the fingerprint input (v). Strings are used exactly as sent to and returned by the model (generated) or as pasted by the person who registers (registered). Verification: POST https://riftveil.ai/api/verify. Keys: https://riftveil.ai/keys.json.
9. Record file
The record file is the record itself, in JSON: see record-file.md. A record is verified on its record file, never on a printout, a screenshot or a PDF alone: the ID, the fingerprint, the seal and the signature can be copied onto an altered document, the text of a record file cannot be altered without the check failing. See verification.md.
03Verification
The rule
A record is verified on its record file, never on a printout, a screenshot or a PDF alone.
- Check the form:
issued_atrepeats the time of therecord_id, the ID is not dated in the future, every text field is a string. Otherwise: not conforming. Recompute the fingerprint from the content of the record file, following its profile. - If it differs from the fingerprint written in the file: content altered. Stop.
- Signature (version 0.1.1). Take the issuer's key list from the address registered for the prefix of the
record_id(ISSUERS.md; Riftveil:https://riftveil.ai/keys.json), never fromproof.signature.keys, which is written in the file. Find the key named byproof.signature.key, and check the Ed25519 signature over the seal message, built from the recomputed fingerprint and the origin the file states. Not valid, missing, or made with a key absent from the list: signature not valid. Made with a key markedcompromised: key compromised, not valid on its own. Made with a key whosevalid_fromis after the date of the record: valid, shown as signed later (section 5 of Record ID, seal and signature). A version 0.1 file (no signature) whose ID is dated after the issuer started signing: signature removed, not valid. This step needs nobody's answer: the issuer is not asked. - Seal. Send
{ id, fingerprint (recomputed), seal }to the issuer's endpoint. If the seal is not valid: not issued. If it is valid for another origin than the one the file states: forged origin. Stop. - Otherwise: valid. Show the content of the file and ask the person to compare it with the document they were given. If they differ, the document was altered, whatever it says.
- If the file holds a
follow_up: recompute its fingerprint (it includes the report fingerprint recomputed in step 1). Different: follow-up altered. No seal: follow-up present, not sealed. Otherwise check its signature as in step 3, over the follow-up message (withsealed_at), and send it with the request of step 4 asdecision: { fingerprint, seal, sealedAt }; the answer addsdecision: { valid, sealedAt }. - If the follow-up holds
previous: verify each earlier follow-up the same way, down the chain, including its signature when it is a 0.1.1 follow-up. An earlier follow-up that is altered, not valid, badly signed, or not sealed strictly before the one that completes it is reported as such; the follow-up that completes it stays valid, since its fingerprint covers only the earlier proof. A verifier MAY stop after 20 earlier follow-ups and report the file as not conforming. - If the follow-up holds
final_document: when a person presents a document, compute the SHA-256 of its bytes on their device and compare it withfinal_document.sha256. Equal: this is the document that was decided. Different: not the document that was decided.
Steps 3 and 4 answer the same question in two ways: the signature with the public key, by anyone; the seal by the issuer. A verifier without network access to the issuer can still check the signature, with a copy of the key list.
Checking the three values alone (ID, fingerprint, seal) only proves that they belong together, not that a given text is the record.
Riftveil endpoints
| Endpoint | Body | Answer |
|---|---|---|
POST https://riftveil.ai/api/verify |
{ id, fingerprint, seal, signature?, decision? } |
{ valid: true, id, issuedAt, origin, signature?, decision? } or { valid: false }; signature is { valid, key, status?, reason? }, and a key marked compromised always gives valid: false |
POST https://riftveil.ai/api/register |
{ fingerprint, profile: "riftveil-content-v1" } |
{ id, seal, signature, issuedAt, origin: "registered", profile } |
POST https://riftveil.ai/api/decide |
{ id, report_fingerprint, report_seal, fingerprint } |
{ seal, sealedAt, origin, signature, report_signature } |
GET https://riftveil.ai/keys.json |
The key list (section 6 of Record ID, seal and signature) |
/api/verify accepts requests from any site (CORS), receives fingerprints only and stores nothing; given signature: { key, value } (and decision.signature), it also checks the signatures with the published keys, as a convenience. /api/register and /api/decide are used from riftveil.ai pages, behind a bot check; they also receive fingerprints only and keep nothing but a daily counter per hashed IP address. report_signature is the signature of the report's seal message: it lets a 0.1 record, or a registered one, be completed into a 0.1.1 record. https://riftveil.ai/issuers.json lists the registered prefixes.
Pages and widget
https://riftveil.ai/verify.html(FR:/fr/verify.html): verification by record file, or by the three values with a warning. The signature is checked in the browser with the public key; a final document can be compared there; "Complete the follow-up" reopens the record to add a follow-up that completes the earlier one.https://riftveil.ai/register.html(FR:/fr/register.html): registration of a report produced elsewhere; the fingerprint is computed in the browser and the record file is downloaded; the follow-up can then be filled in and sealed, as for a report generated on riftveil.ai.- Widget for any page (it verifies the assessment, its signature, and the seal and signature of the follow-up; earlier follow-ups and the follow-up itself are shown on riftveil.ai/verify, which is the full verifier):
<div data-riftveil-verify data-lang="fr"></div>
<script src="https://riftveil.ai/embed/verify.js" defer></script>
The host page's Content-Security-Policy must allow script-src and connect-src https://riftveil.ai.
What remains possible, and what to do about it
| Risk | Status |
|---|---|
| Altered text in a PDF | Detected when the record file is used; not detected on a PDF alone. A qualified electronic seal on the PDF is planned. |
| Document changed after the decision | Detected when the follow-up names a final document and the document is presented for comparison. |
| ID copied from another record | Detected: the record file shows the other record's text. |
| Registered report presented as generated | Detected: one label per origin, in the seal and in the signature. |
| Fabricated project assessed for real | Not detectable, and not the purpose: the seal proves provenance and integrity, never truth. |
| Theft of the sealing key | Key in a secret store, rotation by key number without invalidating earlier seals. The signing key is a separate key. |
| Theft of the signing key | Key in a secret store, numbered; the key is marked compromised and dated in the published list, and is never removed from it. |
| Issuer no longer available | The signature stays verifiable with the published key list. |
| Follow-up added by someone other than the person named | Not prevented: the seal proves when, not who. The name is shown as declared, never as verified. |
| Signature removed to pass as 0.1 | Detected: an unsigned file dated after the issuer started signing is rejected. |
| Nobody verifies | Organisational: make the record file mandatory in the decision file. |
04Conformance
AttestScope Protocol · version 0.1.1. The key words MUST, MUST NOT, SHOULD and MAY are used as in RFC 2119.
A conformance claim names the role and the version: "writes AttestScope 0.1.1 record files", "verifies AttestScope 0.1.1 record files", "issues AttestScope 0.1.1 records under prefix XX". A conformance claim to this specification concerns the format only. The attestation recorded in an AttestScope Record is the signer's, on the scope of their own review.
Writer
A tool that writes record files:
- MUST produce UTF-8 JSON that validates against
schema/attestscope-0.1.1.schema.json. - MUST copy the texts into
contentexactly as they were assessed, sent and returned, without trimming, reformatting or translation. - MUST compute
proof.fingerprint.valuefrom those exact texts with the profile it names, and fill the fields that profile needs:assessment.protocolandassessment.modelforriftveil-report-v1,assessment.assistantforriftveil-content-v1. - MUST NOT let a language model write, suggest or complete the
record_id, the fingerprint, the seal, the signature or any field offollow_up. - MUST leave
follow_upabsent, or with every field empty, until a person fills it in. - MUST compute the fingerprint of a final document on the signer's device, and MUST NOT send the document.
- When a person completes a sealed follow-up, MUST keep the earlier follow-up in full under
previous, with its proof, and MUST NOT change it. - SHOULD name the file
<Issuer name> <record_id>.json.
Issuer
An issuer assigns IDs, seals and signs:
- MUST use a prefix registered in ISSUERS, and MUST NOT issue records under
XTfor real decisions. - MUST assign IDs by code, in the format of Record ID, seal and signature, from a clock synchronised with a public time source.
- MUST keep its sealing keys and its signing keys in a secret store, as separate keys, number them, and keep retired sealing keys available for verification.
- MUST use one label per origin and one for the follow-up.
- MUST sign every message it seals in a 0.1.1 record, with the private key of an active key of its published list.
- MUST publish its key list at the address named in its signatures, keep it identical wherever it is published, never remove a key from it, and mark and date a compromised key.
- MUST publish a verification endpoint that answers valid or not valid, the origin, and for a follow-up the seal time, for fingerprints only, and stores nothing.
- MUST NOT keep the texts, a list of IDs or a list of fingerprints for verification purposes.
- MUST check the seal of the report before sealing a follow-up.
- MUST keep its signing key out of every test or preview deployment reachable by others, and MUST NOT sign later a report dated after it started signing.
- SHOULD rate-limit sealing, signing and registration, fail closed when its counters are unavailable, and protect them against automated abuse.
Verifier
A tool that verifies record files:
- MUST recompute every fingerprint from the file, following its profile, and MUST NOT trust a fingerprint as written.
- MUST report "altered" when a recomputed fingerprint differs from the one in the file, and stop there for that part.
- MUST check each signature of a 0.1.1 file with the issuer's published key list, taken from the address registered for the prefix (never from the file), MUST report a missing signature as not valid, and MUST NOT report a signature made with a key marked compromised as valid on its own.
- MUST ask the issuer's endpoint to check each seal, sending only the ID, fingerprints, seals and seal times, when the issuer can be reached.
- MUST report the origin returned by the issuer, and "forged origin" when it differs from the one the file states.
- MUST verify each earlier follow-up under
previousand report its result separately. - MUST show the sealed texts so that a person can compare them with the document they were given.
- MUST compute the fingerprint of a presented final document on the person's device, and MUST NOT send the document.
- MUST NOT present a check of the ID, fingerprint and seal alone as a verification of a document.
- MUST still verify version 0.1 files, which carry no signature, and MUST reject one whose ID is dated after the issuer started signing.
- MUST reject a file whose
issued_atdiffers from the time of itsrecord_id, a non-canonical signature encoding, and a record whose prefix isXTwhen it is presented for a decision, and MUST show a signature made after the date of the record as such. - MUST NOT present the name in a follow-up as verified.
- SHOULD state in its result that a valid record proves provenance and integrity, never that a decision was right.
05Security and privacy considerations
AttestScope Protocol · version 0.1.1.
Security and privacy: what is covered, and what is planned
What the format covers
| Risk | Countermeasure | Residual risk |
|---|---|---|
| Text altered after issue | Fingerprint recomputed from the file by every verifier | None on the record file; a PDF shown alone proves nothing |
| ID or seal copied onto another document | Verification shows the texts sealed under that ID | A person must compare the texts with the document |
| Registered report presented as generated | One label per origin, in the seal and in the signature | None |
| Follow-up moved to another report | Its fingerprint includes the report fingerprint | None |
| Follow-up edited after sealing | Its own fingerprint, seal and signature, with the issuer's time | None if sealed; an unsealed follow-up proves nothing |
| Earlier follow-up edited after it was completed | Its proof stays in the file; the follow-up that completes it covers its fingerprint, seal and seal time | None: the earlier follow-up is reported as altered |
| Document changed after the decision | final_document.sha256, compared on the reader's device |
Only when the follow-up names the document and the document is presented |
| Seal time moved | The time is inside the sealed and signed message | None |
| Forged seal | HMAC-SHA256 truncated to 160 bits, secret key | Only the issuer can check a seal: the signature covers the same message |
| Forged signature | Ed25519, private key in a secret store; the key list is taken from the address registered for the issuer, never from the file | None known |
| Issuer unreachable or gone | The signature is checked with the published key list | The list must stay published; it is published in three places |
| Stolen sealing key | Secret store, numbered keys, rotation; separate signing key; no later signature for records dated after signing started | Seals made with a stolen key cannot be told apart. New records still need the signing key. A record backdated before signing started could receive a later signature, which verifiers show as made after the date of the record |
| Stolen signing key | Secret store, numbered keys; the key is marked compromised and dated, never removed | Signatures made with it no longer prove anything on their own; a time stamp by a third party, or a register, is then needed |
| Signing key used by a test deployment | Signing key in the production environment only, signing bound to the production host | None if the rule is kept |
| Signature removed (file relabelled 0.1) | A verifier rejects an unsigned file dated after the issuer started signing | None |
| Follow-up added by someone else | Not prevented: the follow-up proves when, not who | A verifier never presents the name as verified; identity needs the organisation's account or a qualified signature (planned) |
| Mass sealing by robots | Bot check, per-IP and global daily limits, closed when counters fail | Counters on a key-value store are not atomic; a short burst can exceed a limit |
| Takeover of the issuer's code or accounts | Strong authentication on the accounts that publish the code and the key lists; three copies of the list | An attacker who controls all the copies can publish a false list; see the planned public log (0.2) |
What it does not cover, by design
- The truth of the project or the quality of the review. A seal or a signature proves provenance and integrity only.
- The identity of the signer. An on-screen signature is a simple electronic signature; the seal and the issuer's signature prove when the follow-up existed, not who wrote it.
- A date proven independently of the issuer. The issuer's clock is sealed and signed; a time stamp by a time-stamping authority (RFC 3161,
proof.timestamps) proves the date without relying on the issuer.
Privacy
- For verification, registration and the decision seal, the issuer receives fingerprints only, never texts, names, decisions, signatures or documents. An issuer that also produces the report receives the texts to write it and keeps none of them; the provider of the AI model it uses may keep them for a limited period, stated on the issuer's privacy page. A SHA-256 fingerprint cannot be turned back into the text; it only lets someone confirm a text they already have, or guess.
- The fingerprint of a final document is computed on the signer's device; the document is never sent.
- The issuer stores no texts and no list of IDs or fingerprints. Only short-lived rate-limit counters, keyed on a hash of the IP address made with a secret key of their own, are kept.
- Whoever holds a record file holds the texts, the names in the follow-up, and the name of the final document. Share it as you would share the report.
- A register entry without the texts is planned, for registers that must not hold the project.
06Registered issuer prefixes
An implementation that writes AttestScope records needs its own prefix before its first record used for a decision. Request one by email to hello@riftveil.ai, with the prefix, name, contact, URL of the verification endpoint and URL of the key list. Each request is reviewed and may be declined, for example if the prefix could be confused with another issuer's.
| Prefix | Issuer | Verification | Keys | Since |
|---|---|---|---|---|
RV |
Riftveil (riftveil.ai) | POST https://riftveil.ai/api/verify |
https://riftveil.ai/keys.json |
2026-09-27 |
XT |
Reserved for tests, never valid for a decision | none | https://attestscope.ai/test-keys.json (public test key) |
2026-09-27 |
07Versions
| Version | Date | Changes |
|---|---|---|
| 0.1.1 | 2026-10-26 | Issuer signature: Ed25519 over the same message as each seal, in proof.signature and follow_up.proof.signature, required in 0.1.1 files; public key list (keys.json) and its rules; verification without the issuer. Optional proof.timestamps (RFC 3161 time stamps, a list). Follow-up profile riftveil-decision-v2: optional final_document (fingerprint of the document that was decided, computed on the signer's device) and previous (completing a sealed follow-up later, earlier follow-ups kept with their proof). Follow-up of a registered report. format becomes "attestscope", version "0.1.1"; schema attestscope-0.1.1.schema.json, with a conditional rule on the fields each fingerprint profile needs. decided_at stated as informative. Single illustrative example (Elena Lambert). Security rules from a review before publication: later signature (countersignature) only for records dated before the issuer started signing, and shown as such; issued_at equal to the time of the ID; unsigned files dated after signing started rejected; canonical signature encoding; signing key kept out of test and preview deployments; the name in a follow-up is declared, never verified. No existing profile changes: 0.1 files stay valid. |
| 0.1 | 2026-09-27 | First public version: proof file, record ID, profiles riftveil-report-v1, riftveil-content-v1, riftveil-decision-v1, HMAC seals, follow-up with decision, verification rules, JSON Schema, test vectors. "Record file" replaces "proof file" in the text; field names are unchanged. Assay Record was the working name of the test version. In record files, the format field reads assay-record and the version field 0.1-draft. |
Reports issued on riftveil.ai before 24 October 2026 carry the working numbering 1.3.x of the Riftveil protocol in assessment.protocol (for example 1.3.3); their seal stays verifiable.
Planned for 0.2
- Canonical JSON (RFC 8785) as a fingerprint input, alongside the current profiles.
- Register entry: the record without
content, and a public log. - Per-finding follow-up,
outcome, andreaders[]with their own fingerprints. - Identity of the person who decides: the organisation's account, or a qualified electronic signature over the follow-up.
Compatibility rule
A new version never changes how an existing profile is computed. A verifier for 0.1.1 verifies every 0.1 record file; a verifier for 0.2 will verify every 0.1 and 0.1.1 record file.
Governance
Riftveil publishes the format and is its reference implementation. Comments go to hello@riftveil.ai. Changes are published in this table before they apply.
08Example
Illustrative record: Elena Lambert’s follow-up, completed two days later with the final document. The prefix XT is reserved for tests: its seals and signatures are made with the public test keys and are never valid for a decision. View on GitHub · JSON Schema on GitHub · Test key list
{
"format": "attestscope",
"version": "0.1.1",
"record_id": "XT-261026-143205-7K3M-Q9XD-2B8F",
"issuer": "XT",
"origin": "generated",
"issued_at": "2026-10-26T14:32:05Z",
"assessment": {
"protocol": "1.0.0",
"model": "claude-sonnet-5",
"assistant": "riftveil.ai",
"language": "en"
},
"content": {
"project": "We recommend consolidating our three cloud vendors into one five-year contract from Q1 2027. The chosen vendor offers a 22% discount in year one, full migration support and a single point of contact. Savings are estimated at EUR 1.4M over five years.",
"context": "Chief Financial Officer, board decision next month.",
"report": "## Record\n- Triage: CRITICAL · examined: question, answer, reasoning, perspective, applicability\n- Findings: 3, by impact CRITICAL: 1 · HIGH: 2 · MODERATE: 0 · LOW: 0\n- Assumptions: 4 with a named verifier · 0 without\n- Questions: 5 with an owner · 1 without\n- Most useful question: \"What does leaving the contract cost if the price rises after the first year?\"\n- Independence: not stated by the user, to be confirmed by the signer\n\n## 1. Context and triage\nThis project is read as a procurement and finance recommendation for a Chief Financial Officer, intended to inform a five-year vendor commitment at board level. Triage: CRITICAL, because a single five-year contract is hard to undo and the financial commitment is high for the organisation. Examined: question, answer, reasoning, perspective, applicability.\nCriteria: reversibility HIGH · impact scope MODERATE · financial commitment HIGH → two criteria at HIGH or above → CRITICAL.\n\nThe five levels of examination: question (what was actually asked) · answer (what the project says) · reasoning (how it gets there) · perspective (what it did not see) · applicability (what it looks like in the real world). Triage: the project's stakes, LOW, MODERATE, HIGH or CRITICAL, judged on reversibility, impact scope and financial commitment; it sets which levels are examined.\n\nIf this framing does not match your situation, say so, and the triage will be redone.\n\n## 2. What holds up\nThe recommendation names one vendor, one start date and one contract length: each can be checked against the offers. A review of what stands, not an endorsement of its content.\n\n## 3. What deserves scrutiny\n\nNote on reasoning: an AI model does not reason in the human sense; the reasoning checks below test logical consistency, not the process that produced the project.\n\n**Pre-mortem: three plausible causes of failure · Impact: CRITICAL**\nObserved: the memo gives no scenario in which the consolidation fails.\nEffect on the decision: three plausible causes are left unexamined: prices rise after year one, a workload cannot move in time, the single vendor's service degrades with no way out.\nTo check: for each cause, what the contract says and who in the organisation would see it coming.\n\n**Exit cost not quantified · Impact: HIGH**\nObserved: the memo proposes a single five-year contract without quantifying what leaving it would cost.\nEffect on the decision: if the price rises after the first year, that cost weighs on the board's decision.\nTo check: ask procurement for the exit cost of each offer, year by year.\n\n**Prices for years 2 to 5 not given · Impact: HIGH**\nObserved: \"a 22% discount in year one\" supports \"savings are estimated at EUR 1.4M over five years\".\nEffect on the decision: a discount limited to year one says nothing about years two to five, where most of the contract value lies.\nTo check: the price schedule for every year of the contract, in the draft contract itself.\n\n## 4. Assumptions the project relies on\n1. Prices after year one stay close to year one. If they rise, the EUR 1.4M saving does not hold. → Who can verify: procurement, with the full price schedule.\n2. All workloads can move before the current contracts end. If not, two vendors are paid at the same time. → Who can verify: the CIO.\n3. The vendor's migration support covers the work the teams would otherwise do. If not, the internal cost is missing from the saving. → Who can verify: the CIO, with the heads of the teams concerned.\n4. One point of contact is enough for three former vendors' services. If not, service levels drop during the first year. → Who can verify: the head of IT operations.\n\n## 5. Questions before you decide\n1. What does leaving the contract cost if the price rises after the first year? Owner: procurement\n2. What are the prices for years 2 to 5 of each offer? Owner: procurement\n3. Which workloads cannot move before the current contracts end? Owner: CIO\n4. What internal effort does the migration need, beyond the vendor's support? Owner: CIO\n5. Which service levels does the contract guarantee, and what happens if they are missed? Owner: head of IT operations\n6. Who will answer to the board if the saving is not there in year three?\n\nNo verdict. The decision is yours."
},
"proof": {
"fingerprint": {
"alg": "sha-256",
"profile": "riftveil-report-v1",
"value": "44ad2fc8676594a6105c621a93dd051de1648c47253351689c8b7f24f84689d9"
},
"seal": {
"value": "S1-REQ8-RW0G-J013-M23D-C969-73JZ-MF93-1W6J",
"verify": "https://riftveil.ai/api/verify"
},
"signature": {
"alg": "ed25519",
"key": "ed25519-1",
"value": "RLk8n-uArHiModfTXjm3Inw8iWm4zVQAMPYczqz-pRtfVx_Z3vbBmV2hQrsdpme4TCZtanhr_mUfWOttBsPsDQ",
"keys": "https://attestscope.ai/test-keys.json"
}
},
"follow_up": {
"profile": "riftveil-decision-v2",
"verified_by": {
"last_name": "Lambert",
"first_name": "Elena",
"role": "Chief Financial Officer"
},
"checked": "The prices for years 2 to 5 of the three offers, with procurement. Exit-cost analysis received from Daniel Murphy on 28 October and presented to the board: exit capped at six months of fees.",
"questions": [
{
"n": 1,
"question": "What does leaving the contract cost if the price rises after the first year?",
"suggested_owner": "procurement",
"assigned_to": "Daniel Murphy, Head of Procurement"
},
{
"n": 2,
"question": "What are the prices for years 2 to 5 of each offer?",
"suggested_owner": "procurement",
"assigned_to": ""
},
{
"n": 3,
"question": "Which workloads cannot move before the current contracts end?",
"suggested_owner": "CIO",
"assigned_to": ""
},
{
"n": 4,
"question": "What internal effort does the migration need, beyond the vendor's support?",
"suggested_owner": "CIO",
"assigned_to": ""
},
{
"n": 5,
"question": "Which service levels does the contract guarantee, and what happens if they are missed?",
"suggested_owner": "head of IT operations",
"assigned_to": ""
},
{
"n": 6,
"question": "Who will answer to the board if the saving is not there in year three?",
"suggested_owner": "",
"assigned_to": ""
}
],
"decision": "conditions",
"conditions": "Contract signed only after the exit-cost analysis, presented to the board.",
"place": "",
"signature": {
"method": "drawn",
"typed": "",
"image": "data:image/png;base64,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"
},
"final_document": {
"name": "Board memo - cloud contract.pdf",
"size": 103,
"sha256": "2df7e602ebf9f09606a0a9f30bd6ea852065c216793b99f2797707aeb512e54d"
},
"previous": {
"profile": "riftveil-decision-v2",
"verified_by": {
"last_name": "Lambert",
"first_name": "Elena",
"role": "Chief Financial Officer"
},
"checked": "The prices for years 2 to 5 of the three offers, with procurement.",
"questions": [
{
"n": 1,
"question": "What does leaving the contract cost if the price rises after the first year?",
"suggested_owner": "procurement",
"assigned_to": "Daniel Murphy, Head of Procurement"
},
{
"n": 2,
"question": "What are the prices for years 2 to 5 of each offer?",
"suggested_owner": "procurement",
"assigned_to": ""
},
{
"n": 3,
"question": "Which workloads cannot move before the current contracts end?",
"suggested_owner": "CIO",
"assigned_to": ""
},
{
"n": 4,
"question": "What internal effort does the migration need, beyond the vendor's support?",
"suggested_owner": "CIO",
"assigned_to": ""
},
{
"n": 5,
"question": "Which service levels does the contract guarantee, and what happens if they are missed?",
"suggested_owner": "head of IT operations",
"assigned_to": ""
},
{
"n": 6,
"question": "Who will answer to the board if the saving is not there in year three?",
"suggested_owner": "",
"assigned_to": ""
}
],
"decision": "conditions",
"conditions": "Contract signed only after the exit-cost analysis, presented to the board.",
"place": "",
"signature": {
"method": "drawn",
"typed": "",
"image": "data:image/png;base64,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"
},
"decided_at": "2026-10-26T16:05:12Z",
"proof": {
"fingerprint": {
"alg": "sha-256",
"profile": "riftveil-decision-v2",
"value": "2fd3a2ae0b4685c971c0cb7e780bf97736d02ff3f25f3e42ad953cfa180115c2"
},
"seal": {
"value": "S1-SP2R-M6Z9-3Y27-M5MB-YB16-57G7-MX47-8GFY",
"sealed_at": "2026-10-26T16:05:12Z",
"verify": "https://riftveil.ai/api/verify"
},
"signature": {
"alg": "ed25519",
"key": "ed25519-1",
"value": "H0tFeR7Q-VELQlHZEsR9AkvBDaKZmP2Obc7CuPehNrHaA5XHmRtrPcSsOHsPStb1MU6BcQKTS8MVWHaKDlUmAw",
"keys": "https://attestscope.ai/test-keys.json"
}
}
},
"decided_at": "2026-10-28T09:41:27Z",
"proof": {
"fingerprint": {
"alg": "sha-256",
"profile": "riftveil-decision-v2",
"value": "137a5d48553a886223ef5392e910d1e16e7d46aebb82e5fa8bef058963ff7522"
},
"seal": {
"value": "S1-30WH-D58W-8MVE-6G4Y-8KSE-30J0-G3YC-RX4S",
"sealed_at": "2026-10-28T09:41:27Z",
"verify": "https://riftveil.ai/api/verify"
},
"signature": {
"alg": "ed25519",
"key": "ed25519-1",
"value": "Nk-dIGehodcncNA9pOvyC3KMAjeoXkHQIEggGaVoZAobxLkHL8FmUMYx61uwYrl560NvoV0pVAAgerL-cWvsCQ",
"keys": "https://attestscope.ai/test-keys.json"
}
}
},
"notice": "Illustrative record. People, organisations and amounts are fictitious. The prefix XT is reserved for tests: the seals use the public test key assay-test-key-1 and the signatures the public Ed25519 test key of docs/test-vectors.json; they are never valid at riftveil.ai. The final document is a short text given in docs/test-vectors.json."
}