← attestto.com ·
VCP v0.1 ·
All Specs
Implementation Report
VCP v0.1 Working Draft — @attestto/vcp Reference Implementation
8 tests passed · 0 failed · 3 carriers + tamper detection + idempotency + keygen
| Field | Value |
| Specification | VCP v0.1 Working Draft |
| Implementer | Attestto |
| Implementation | @attestto/vcp (Node.js CLI, MIT/Apache-2.0) |
| Language | JavaScript (Node.js ≥ 20) |
| Cryptography | @noble/curves (Ed25519), @noble/hashes (SHA-256), canonicalize (JCS RFC 8785) |
| Report Date | 2026-07-01 |
| Implementation Count | 1 (additional implementations invited) |
Test Suite Overview
| Test | Purpose | Result |
| 1. sidecar sign+verify roundtrip | Base envelope + sidecar carrier + did:key resolver | PASS |
| 2. pdf sign+verify roundtrip | PDF trailer carrier + content canonicalization | PASS |
| 3. jpeg sign+verify roundtrip | JPEG XMP APP1 carrier + segment iteration | PASS |
| 4. tampered sidecar host file fails verify | Content-hash mismatch detection (sidecar) | PASS |
| 5. tampered pdf host file fails verify | Content-hash mismatch detection (embed carrier) | PASS |
| 6. re-sign is idempotent | Re-signing replaces prior envelope; no compounded embed blocks | PASS |
| 7. help output includes spec URL | CLI advertises the specification namespace | PASS |
| 8. keygen produces resolvable did:key | Mandatory did:key support (§5.1) | PASS |
Section-by-Section Coverage
§2 Envelope structure
| Requirement | Covered by test | Status |
§2.1 required metadata fields (spec, spec_version, issuer, content_type, content_hash, hash_scope, timestamp) | 1, 2, 3 (all roundtrips construct and validate the full metadata object) | PASS |
§2.1 optional fields (subject, profile, ieal) accepted | Manual verification via vcp sign --subject / --profile | PASS |
§2.2 signature block alg = EdDSA, value base64url | 1, 2, 3 (produced envelopes conform to shape) | PASS |
§3 Canonicalization
| Requirement | Covered by test | Status |
| §3.1 metadata canonicalized via JCS (RFC 8785) | Implementation uses canonicalize package on every sign and verify path (see src/envelope.js) | PASS |
§3.2 host-file-minus-vcp-block for embed carriers | 2 (PDF), 3 (JPEG); tamper detection tests 4, 5 exercise the rule | PASS |
§3.2 host-file-unmodified for sidecar | 1 (sidecar roundtrip), 4 (tamper detection) | PASS |
§4 Carriers
| Carrier | Covered by test | Status |
| §4.1 Sidecar | 1, 4 | PASS |
| §4.2 PDF trailer | 2, 5, 6 (idempotency uses JPEG but same replacement rule applies to PDF via stripVcpTrailer) | PASS |
| §4.3 JPEG XMP | 3, 6 | PASS |
§5 DID methods
| Method | Covered by test | Status |
§5.1 did:key (mandatory for verifiers) | 1, 2, 3, 8 | PASS |
§5.2 did:pki (optional; signer accepts, verifier requires --public-key until resolver publishes) | Documented in README + CLI error text; not covered by v0.1 tests | PARTIAL |
§7 Conformance
| Requirement | Covered by test | Status |
| §7.1.1 signer produces required fields | 1, 2, 3 | PASS |
| §7.1.2 signer canonicalizes before signing | Implementation invariant; every sign path uses canonicalize() | PASS |
| §7.1.3 signer uses registered algorithm | 1, 2, 3 (only Ed25519 emitted) | PASS |
| §7.1.4 signer embeds via a defined carrier | 1, 2, 3 | PASS |
| §7.1.5 SHOULD re-signing replaces, not compounds | 6 | PASS |
| §7.2.1 verifier rejects unknown top-level fields | Not tested in v0.1; behavior specified but only enforced by strict JSON schema addition planned for v0.2 | GAP |
§7.2.2 verifier rejects unknown spec_version | Not tested in v0.1; behavior specified | GAP |
| §7.2.3 verifier recomputes content hash and rejects on mismatch | 4, 5 | PASS |
§7.2.4 verifier supports did:key | 1, 2, 3 | PASS |
| §7.2.5 distinguishes DID-resolution failure from signature failure | Distinct error paths implemented in src/did.js; not asserted by test suite in v0.1 | PARTIAL |
| §7.2.6 MAY warn on sidecar-separation risk | Not implemented; documented in README as user-facing risk | DEFERRED |
Known Gaps
The gaps below are recognized limitations of the v0.1 implementation. They do not affect correctness on well-formed input but reduce robustness on adversarial or malformed input.
- Strict unknown-field rejection (§7.2.1, §7.2.2) — a JSON Schema validation pass is planned for v0.2 to enforce this at the deserialization boundary. Current implementation ignores unknown fields silently.
did:pki resolver (§5.2) — verification of did:pki:* issuers requires the caller to supply the resolved Ed25519 public key via --public-key. A published @attestto/did-pki resolver is planned as part of the v0.2 track; will resolve against the Costa Rica Firma Digital CA hierarchy first.
- Resolution-failure vs signature-failure distinction (§7.2.5) — the code paths differ but the test suite does not yet assert that the error emitted for a resolution failure differs from the error emitted for a signature failure. A v0.2 test will make this observable.
- Sidecar separation warning (§7.2.6) — documented in README and specification; the CLI does not emit a warning when it observes an isolated sidecar (host missing). Follow-on ticket to add a
vcp verify --strict-sidecar option.
- PDF PAdES integration — v0.1 uses a
%%vcp:begin / %%vcp:end trailer after %%EOF rather than a proper PDF signature dictionary with /ByteRange. A separate pdf-pades carrier is planned for a future revision to co-exist with legacy PAdES signatures on the same document.
- MP3 and MP4 carriers — specification and implementation deferred to v0.2 per ATT-773. Embed slot analysis is documented in the internal research doc; carriers will follow the same envelope + canonicalization pattern as PDF and JPEG.
- Encryption — v0.1 signs only. A standalone
.vcp extension with encrypted payload (X25519 + XChaCha20-Poly1305) is planned for v0.2 as a distinct carrier.
- Post-quantum hybrid signature suite — only
EdDSA is specified for v0.1. A future revision will add an algorithm registry with ML-DSA + Ed25519 hybrid options; existing signatures remain valid under the algorithm they were signed with.
How to Reproduce
All tests are runnable with:
git clone https://github.com/Attestto-com/vcp-cli
cd vcp-cli
pnpm install
pnpm test
Test source: test/roundtrip.test.js. Each test spawns the CLI as a subprocess, exercising the same public surface an external implementer would use.
Invitation to External Implementers
VCP is an open specification. Additional reference implementations in other languages (Rust, Go, Python, Swift) are invited. Implementers who publish a conformance report following the shape of this document are invited to open a PR on did-sns-spec to have their report linked from the specification page.