/// Litzki Systems LLC — Draft Product Spec
SovereignAttestation — Format & Verification Procedure
Status: draft product spec, Litzki Systems LLC. Not an IETF document, not part of draft-litzki-sovp-03. It reuses that draft's cryptographic primitives (Ed25519, RFC 8785 JCS, DNS-anchored keys) but defines a separate document type for a separate trust claim.
1. What this is (and is not)
Two documents exist for a domain that has gone through SOVP validation:
| Document | Location | Signed by | Claim |
|---|---|---|---|
sovp-identity.json |
subject domain's own /.well-known/ |
subject domain's own key (_sovp.<subject-domain>, possibly custody-managed) |
“I am this domain” — self-asserted identity |
sovp-attestation.json |
subject domain's own /.well-known/ |
Litzki Systems LLC issuer key (_sovp-attestation.litzki-systems.com) |
“Litzki certifies this verdict about this domain” — third-party attestation |
These are independent trust claims from independent signers, verified against independent DNS-anchored keys. A verifier who cares about the verdict trusts the attestation, signed by the issuer. The identity document's own scan block (if present) is explicitly out-of-scope for trust decisions per draft-litzki-sovp-03 §5 — it is not, and must not be read as, a substitute for this attestation.
2. Document structure
{
"@context": "https://litzki-systems.com/protocol/sovp-attestation-v1",
"@type": "SovereignAttestation",
"subject": {
"domain": "example.com",
"canonical_url": "https://example.com"
},
"attestation": {
"verdict": "CERTIFIED",
"sovereignScore": 87.4,
"contentQuality": 91,
"aiReadiness": 88,
"infrastructureScore": 79,
"authorityScore": 62,
"coherenceScore": 70,
"parameterCount": 268,
"vault_payload_digest": "<sha256 hex, optional>",
"scanned_at": "2026-07-22T10:00:00Z",
"valid_until": "2026-10-20T10:00:00.000Z",
"spec_url": "https://litzki-systems.com/protocol/sovp-attestation-v1"
},
"issuer": {
"uid": "urn:sovp:litzki-systems-llc",
"canonical_url": "https://litzki-systems.com"
},
"integrity_proof": {
"signature": "<base64>",
"created": "2026-07-22T10:00:03.000Z",
"public_key_ref": "dns:txt:_sovp-attestation.litzki-systems.com",
"nonce": "<uuid4>"
}
}
spec_url points at this specification, not at the IETF identity draft — the attestation is a Litzki product artifact, and pointing at the draft would misrepresent it as an IETF-specified object.
attestation.vault_payload_digest is optional: a SHA-256 hex digest of the JCS-canonicalized Sovereign Vault record this attestation was issued for. Because it sits inside the signed scope, it binds the vault record's grading threshold and scores to this signature — the vault record can no longer be edited after issuance without invalidating the attestation. Attestations issued before this field existed, and verifiers that don't check it, remain valid.
3. Signed scope
The Ed25519 signature covers every top-level field except integrity_proof — @context, @type, subject, attestation, issuer. This differs from the SovereignIdentity document, where vendor extensions (like scan) sit outside the signed scope; here, the verdict and scores are the entire point of the document, so they are inside the signed scope by construction.
4. Canonicalization
Identical rule to draft-litzki-sovp-03 §4: the payload (all signed fields) MUST be serialized using an RFC 8785-compliant JSON Canonicalization Scheme (JCS) implementation before signing or verifying. Non-compliant canonicalizers (ad hoc JSON.stringify, handwritten sorters that don't recurse into arrays, etc.) MUST NOT be used — they silently break cross-implementation verification even when the signature math is otherwise correct. Reference implementation here uses the canonicalize npm package (RFC 8785 conformant); a Python verifier should use the jcs PyPI package for the same reason.
5. Signature algorithm
Ed25519 in pure mode (RFC 8032 §5.1) over JCS(payload) directly — no external pre-hash is applied before the sign/verify call (Ed25519 already applies SHA-512 internally). This is directly verifiable with standard tools, e.g.:
openssl pkeyutl -verify -rawin \
-pubin -inkey issuer_pubkey.pem \
-sigfile signature.bin \
-in canonical_payload.json
where canonical_payload.json is the JCS-canonicalized payload bytes and signature.bin is the base64-decoded integrity_proof.signature.
6. Key location (trust anchor)
The issuer's Ed25519 public key is published as a DNS TXT record:
_sovp-attestation.litzki-systems.com IN TXT "v=SOVP1; k=<base64-raw-32-byte-key>"
Format identical to draft-litzki-sovp-03 §10.1. This label is deliberately distinct from _sovp.litzki-systems.com (the SovereignIdentity key for litzki-systems.com itself) and from any _sovp.<subject-domain> label (the subject's own identity key). A verifier resolves the issuer key from DNS independently — never trusts a key embedded in the document itself, and never trusts a key found under the subject domain's own _sovp label for this purpose.
Recommended TTL: operationally dependent, not a fixed value. Short (300 seconds, per draft-litzki-sovp-03 §8.1) while the issuer key rotates frequently; longer (3600 seconds or more) once the issuer key is stable — a longer TTL reduces resolver load and lookup latency for verifiers with no revocation-speed cost as long as no rotation is imminent. Lower the TTL back to 300 seconds ahead of a planned key rotation, so the old key falls out of caches quickly once the new one is published. Same revocation mechanism either way (update/remove the TXT record).
7. Expiry semantics
attestation.valid_until is either an ISO-8601 timestamp or the literal string "permanent".
Verification produces two independent results, not one collapsed boolean:
signature_valid(bool) — purely cryptographic. Never affected by dates. A tampered document issignature_valid: falseregardless of whethervalid_untilhas passed.status("valid"|"expired") — purely a comparison ofvalid_untilagainst the current time. Independent ofsignature_valid.
A genuine attestation past its valid_until is {signature_valid: true, status: "expired"} — it was never forged, it lapsed. Consumers MUST NOT report an expired-but-genuine attestation as “invalid” or “tampered”; those are different failure modes with different remediation (re-scan vs. security incident).
8. Verification procedure (informal)
- Fetch
https://<subject-domain>/.well-known/sovp-attestation.json. - Resolve
_sovp-attestation.litzki-systems.comTXT record; parsev=SOVP1; k=<base64>. - Strip
integrity_prooffrom the document; JCS-canonicalize the rest. - Ed25519-verify
integrity_proof.signatureagainst the canonical bytes using the DNS-resolved public key. - Compare
attestation.valid_untilagainst current time. - Report
signature_validandstatusseparately (see §7).
Reference implementation: verify-attestation.mjs (offline reference verifier, Node.js + canonicalize).