Skip to content

Register five docusigner ontologies (SigningEnvelope, EIDSignature, EnvelopeAuditEvent, HandwrittenSignature, DocumentKey) - #1111

Open
EgorPPS wants to merge 2 commits into
mainfrom
docusigner-ontologies-registration
Open

Register five docusigner ontologies (SigningEnvelope, EIDSignature, EnvelopeAuditEvent, HandwrittenSignature, DocumentKey)#1111
EgorPPS wants to merge 2 commits into
mainfrom
docusigner-ontologies-registration

Conversation

@EgorPPS

@EgorPPS EgorPPS commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Registers the five ontologies written by docusigner — document signing with eID, where signers are addressed by eName and every signature is made with the signer's own eID key. Live at https://docusigner.postplatforms.com

Schema schemaId Written to
SigningEnvelope 256510c7-692c-4bf5-8136-820cd178a266 initiator's vault (canonical) + every signer's vault (reference)
EIDSignature ede4c610-9e22-4074-9598-82c915058f4f the signer's own vault
EnvelopeAuditEvent 8c2c245e-8714-41da-8407-14ab5ce8ea38 the vault of whoever performed the step
HandwrittenSignature 2a062bd7-c7a3-451e-b4ff-d1ada729bf46 the person's own vault
DocumentKey 83e80d2b-eb06-46f9-9ef8-a2d0ea262801 every party's own vault

All five are in production use today. None is a placeholder.

Why these are separate types, not fields on existing ones

EIDSignature vs the registered Signature (b2c3d4e5-…-f12345678901). Signature sets additionalProperties: false and carries fileId / userId / md5Hash. A signature over a signing envelope needs envelopeId, fieldsHash, fieldSchemaVersion, role and order, and additionalProperties: false forecloses every one of them. It also needs the signer's own field values inlinefieldsHash cannot be recomputed without them, and verification must not depend on the signing platform's database still existing. Different subject, different verification procedure.

SigningEnvelope vs File. A File is bytes. A document under signature is a process: who was asked, in what order, what each of them has done, and — critically — the initiator's seal binding this document to exactly this list of signers. Without that seal an envelope is unsigned data that any admitted platform could rewrite.

DocumentKey vs putting the key in the envelope. The key is shared per party, on each party's own vault, so a signer can open the document in an application that is not ours. Its lifetime and its ACL are not the envelope's.

HandwrittenSignature. A person's drawn or typed signature image is their data, reusable across any application that needs it, and does not belong to whichever product they happened to draw it in.

Shape, in one line each

SigningEnvelopeoneOf discriminated on isReference. The canonical form (isReference: false) lives on the initiator's vault and requires initiatorSignature, initiatorSignedPayload, sealSchemaVersion and participants; the reference form lives on each signer's vault, carries canonicalOwnerEName + canonicalEnvelopeId, and is forbidden from carrying any of the canonical-only fields. The discriminator is enforced both ways so a reference cannot masquerade as an original.

EIDSignature — one participant's signature: signedPayload (the exact string handed to the wallet), signature, fieldsHash, fieldValues inline, docPlaintextSha256.

EnvelopeAuditEvent — one recorded step. isAttested says whether the actor signed it; dependencies makes signedPayload and signature live and die together, because half a proof is not a proof.

DocumentKey — AES-256-GCM key material, oneOf on isReference like the envelope.

HandwrittenSignature — the image (imageUri, imageSha256), how it was made (method: drawn / typed / uploaded), and whether it is the owner's default.

Cross-vault model

(eName, envelopeId) is the addressable unit, so every reference carries canonicalOwnerEName alongside canonicalEnvelopeId — an envelope id without a tenant addresses nothing. The canonical record is the single source of truth; signers hold references, never copies, because N copies of a document under signature is N versions of what was agreed.

What is NOT here, deliberately

  • The completed PDF is not referenced by a w3ds://file URI. It would land on the same public CDN as the source blob, carrying the decrypted document plus the identities of everyone who signed it. Only its hash is recorded, as an integrity checksum rather than as evidence.
  • No additionalProperties: false anywhere. eVault does not validate — measured: its own uploadFile writes envelopes that violate the registered File schema — so the restriction buys no safety and forecloses extension permanently.
  • identityAssurance is not a claim by the signer. It records what the signing platform knew about that person's identity at the moment they signed, read from their own vault. It sits beside the signature and is not covered by it; the schema description says so explicitly, so no reader can mistake it for something the signer asserted.

Checks

Schemas are draft-07 and validated by an ajv conformance suite in the docusigner repository, which asserts both directions of every discriminator and every required-field dependency. (That suite is how dependentRequired — a draft 2019-09 keyword, silently ignored under draft-07 — was caught and replaced with dependencies.)

None of these five schemaIds currently resolves on the ontology service, so nothing here collides.

…nvelopeAuditEvent, HandwrittenSignature, DocumentKey)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@EgorPPS
EgorPPS requested a review from coodos as a code owner August 20, 2026 07:55
@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3fb32423-3894-4bed-b1fe-55b56ac93eab


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…ound nothing'

This record is written once beside a signature and read for years, so a
momentary storage failure recorded as 'unknown' becomes a permanent false
statement about somebody whose identity is in fact established. The two are now
distinct levels, and the schema description says explicitly that a reader must
not collapse them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@EgorPPS

EgorPPS commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Pushed a correction to identityAssurance.level (on both eidSignature and signingEnvelope).

The enum was verified | attested | unknown. It is now verified | attested | unknown | unavailable, splitting two things that were one value:

  • unknown — we looked, and nothing at all is known about who holds this eName. An observation about the person.
  • unavailable — we could not look: their storage did not answer. An admission about us.

Worth a schema change rather than a comment because of where this value lives. It is written once, beside a signature, and read for years — there is no later pass that corrects it, the way a cache is corrected by the next refresh. A rate limit at the wrong second would therefore freeze "nothing is known about who holds this eName" into a contract about somebody whose passport had in fact been checked, and neither party would ever have a way to discover that the platform had simply failed to ask.

The description now states that the two must not be collapsed by a reader, since a reader who treats them as one reintroduces exactly the fault.

Credit where due: this came out of comparing notes with the Nootropic session, which was tracking the same class of fault — a transport failure being reported as a substantive answer — across several platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants