VaultESign
VaultESign provides native electronic signing for documents rendered by VaultPDF. Your documents stay in your Azure subscription. Signers access a signing portal to verify identity, review documents, and apply legally-binding electronic signatures. All signing evidence and audit records are stored entirely within your tenant.
VaultESign manages the complete electronic signature lifecycle for VaultPDF-generated documents. It operates independently of third-party e-signature platforms.
Your document rendering, signing, and audit storage occur entirely in your Azure subscription via the Vault Dispatcher and Processor. Signers interact with a stateless signing portal hosted on Vault Shared Services by Refract Logic. Signer invitations are routed through Azure Communication Services under standard Data Processing Agreements. All signature evidence is stored as immutable audit records in your tenant, designed to meet the technical requirements for admissibility as electronic evidence under e-signature laws in most jurisdictions.
Key Difference from Traditional eSign: Unlike platforms that store your documents on external servers, Vault keeps document content in your infrastructure from rendering through final sealing.
Enterprise Feature
VaultESign requires the vaultESign feature gate on your licence.
Zero Content Egress — Document Stays in Your Azure
Your document content never leaves your Azure subscription. The eSign Portal (hosted on Vault Shared Services by Refract Logic) is stateless: it renders UI and manages temporary tokens only.
Document Flow:
Your Blob Storage → Your Dispatcher (document proxy /api/esign/document/{token}) → Signer's browser — document bytes stream directly from your storage; they never transit portal servers.
Notification Flow — invitation emails: The eSign Portal (Vault Shared Services) sends signer invitation emails directly via Vault Shared Services ACS. This applies to initial invitations, sequential next-signer activations, and resend requests. Document content is not included — only the portal link, signer name, and document name.
Notification Flow — OTP codes and completion notifications:
Your Dispatcher → notification queue → Your Processor → Vault Shared Services ACS (vault-shared mode) or Your own ACS (customer-acs mode). Set EMAIL_PROVIDER=customer-acs on both Function Apps to route these through your own ACS.
Audit Flow: Your Processor → Your Azure Blob Storage (JSONL evidence bundle) + Your Table Storage (session/slot state) — evidence certificate is generated and stored entirely in your subscription.
Signer notifications (email invitations with portal links) are routed via Azure Communication Services under the Microsoft Standard Contractual Clauses. No document bytes, form data, or signatures are included in any external transmission.
How It Works
-
A document is rendered by your Vault Dispatcher (direct on-demand render) or Vault Processor (workflow seal, batch distribution). The resulting PDF is stored in your Azure Blob Storage.
-
An initiator (SPFx command set or API caller) creates a signing session via
POST /api/esign/session(calls your customer-hosted Dispatcher). -
Your Dispatcher communicates with Vault Shared Services by Refract Logic to generate per-signer invitation emails with unique portal links and security tokens.
-
Each signer visits their portal link (hosted on Vault Shared Services), optionally verifies via OTP, reviews the document, completes any manifest fields (initials, date, text, checkboxes), and applies their signature.
-
The signer's completed submission is posted as a callback to your Dispatcher (
POST /api/esign/callback). The Dispatcher validates the HMAC signature, updates slot state, and enqueues a seal message to your Azure Service Bus. Your Processor picks up the seal message for cryptographic sealing and evidence certificate generation. -
The completed signed PDF and evidence certificate are stored in your Azure Blob Storage and (optionally) written back to SharePoint.
Infrastructure Locations
| Component | Hosted On | Purpose |
|---|---|---|
| Vault Dispatcher | Your Azure Subscription | API endpoint, session creation, callback receiver, document proxy (/api/esign/document/{token} streams PDF from your Blob to the signer's browser), token generation |
| Vault Processor | Your Azure Subscription | Signature sealing, evidence certificate generation, post-seal portal PII cleanup, audit JSONL writing |
| eSign Portal | Vault Shared Services by Refract Logic | Stateless signing UI (no document storage) |
| Notification Service | Vault Shared Services by Refract Logic | Signer email invitations via Azure Communication Services |
| Licensing API | Vault Shared Services by Refract Logic | Session validation, metering, and platform health |
Signing Modes
| Mode | Description |
|---|---|
single | One signer. Session completes when the single slot is signed. |
sequential | Multiple signers in a defined order. Each signer is notified only after the previous signer completes. |
parallel | Multiple signers notified simultaneously. Session completes when all required slots are signed. |
Slot Completion Conditions
Each slot carries a completionCondition of required or optional. The session completes when all required slots are signed, regardless of optional slot state.
Signer limit — up to 10 per session
VaultESign supports up to 10 signers per session. This covers the full range of standard business use cases: vendor contracts (1–3), loan agreements (2–4), board resolutions (up to 10). If you are integrating from a platform like DocuSign that supports larger recipient counts, note this limit when designing your signing flows. For documents requiring more than 10 signatories, consider splitting into multiple sessions per document section or using VaultWorkflow's governance approval routing.
Session Expiry
Sessions expire when the expiresInMinutes TTL elapses before all required slots are signed.
Default TTL is 30 minutes — always set expiresInMinutes explicitly
The default expiresInMinutes is 30 minutes if omitted. This is intentionally short and is almost always too brief for real signing workflows where signers need time to review the document, get OTP codes, or complete at their convenience. Always set expiresInMinutes explicitly. Recommended values:
| Use case | Suggested value |
|---|---|
| Same-day signing (urgent) | 240 — 4 hours |
| Standard business document | 4320 — 3 days |
| Complex multi-party agreement | 10080 — 7 days (maximum) |
What happens when a session expires:
- The session state transitions to
expired. - Any portal links held by signers return
410 Gone— the document is inaccessible. - All signing progress from the expired session is lost. Partially-signed sessions do not carry forward individual slot completions.
There is no extend or revive endpoint. To recover from an expired session, create a new session via POST /api/esign/session. All signers — including those who had already signed — must sign again in the new session.
POST /api/esign/session/{correlationId}/resend-invite does not rescue expired sessions. It only resends the invitation email for slots already in activated, viewed, or otp_verified state within a live session.
Session States
| State | Description |
|---|---|
pending | Session created; no signer has accessed their portal link yet. |
in_progress | At least one signer has activated their slot. |
sealing | All required slots complete; processor is generating the final signed PDF and evidence certificate. |
complete | Signed PDF and evidence certificate produced and stored in your subscription. |
cancelled | Session cancelled by the initiator before completion. |
expired | Session TTL elapsed before all required slots were completed. No seal occurs; new session required. |
Slot States (Per Signer)
| State | Description |
|---|---|
pending | Invitation sent; signer has not yet opened the portal. |
activated | Signer has opened the portal link. |
viewed | Signer has opened and scrolled through the document. |
otp_verified | Signer has passed the OTP challenge (when required). |
signed | Signer has completed all fields and submitted their signature. |
declined | Signer declined to sign. |
expired | Slot TTL elapsed. |
OTP Verification
Each signing slot can be configured to require a one-time passcode before the signer can access the document. OTP delivery channels:
| Channel | Description |
|---|---|
email | OTP delivered to the signer's email address. |
sms | OTP delivered by SMS (requires phoneNumber in slot config). |
signer-choice | The portal lets the signer select their preferred channel. |
Consent Model
Before applying their signature, each signer confirms three consent statements:
- Document reviewed: the signer confirms they have read and understood the document.
- Electronic consent: the signer consents to signing electronically in lieu of a handwritten signature.
- Binding acknowledgement: the signer acknowledges the electronic signature is legally binding.
The verbatim text of all three statements is frozen at signing time and embedded in the evidence certificate, ensuring historical accuracy independent of any future copy changes. This supports compliance and non-repudiation requirements.
Evidence Certificate
When all required slots are complete, the processor generates an evidence certificate and appends it to the signed PDF. This certificate is designed to meet the technical requirements for admissibility as electronic evidence and supports non-repudiation under e-signature laws (E-SIGN Act, UETA, eIDAS) in most jurisdictions.
Certificate Contents:
- Document metadata: title, correlation ID, SHA-256 hash of rendered PDF (proves document integrity)
- Per-signer record:
- Name and email (email hashed for storage)
- IP address and user-agent (device/browser info for audit)
- Slot state timeline (pending → activated → viewed → signed)
- Timestamp of each state transition (nanosecond precision)
- OTP verification record (if applicable)
- Consent acknowledgments:
- Verbatim text of all three consent statements
- Timestamp each consent was accepted
- Session metadata:
- Signing mode (single/sequential/parallel)
- Session expiration time
- Engine version and tenant ID
PII Protection in Storage:
Email addresses are protected with multiple layers:
- In audit storage: Stored as HMAC-SHA256 hash (one-way, cryptographic hash—no recovery)
- In operational lookup: Encrypted with AES-256-GCM at rest (allows display without plaintext logging)
- In logs: Never logged in plaintext; correlation IDs and tokens only
- In evidence certificate: Hashed for durability while protecting privacy
This ensures the evidence certificate is tamper-evident and designed to support admissibility as electronic evidence, while preventing email exposure if storage is breached.
No PII in Audit Storage
Signer email addresses are stored as HMAC-SHA256 hashes in Azure Table Storage. The plaintext email is AES-256-GCM encrypted at rest (for operational display only) and is never stored in logs or audit blobs. This dual-layer protection ensures privacy while maintaining auditability.
Data Residency & Compliance
Architecture Overview
Your Vault Platform deployment consists of:
Customer-Hosted Infrastructure (Your Azure Subscription):
- Vault Dispatcher (API, session state management, token generation)
- Vault Processor (rendering, signing, sealing, audit logging)
- Azure Blob Storage (documents, PDFs, signed documents, certificates)
- Azure Table Storage (audit records, evidence, session state)
- Application Insights (audit logging and tracing)
- SharePoint (optional integration for document storage/retrieval)
Vault Shared Services by Refract Logic (Refract Logic's Azure Subscription):
- eSign Portal (stateless UI, no document storage, session tokens only)
- Notification Service (email delivery orchestration via Azure Communication Services)
- Licensing API (metering, session validation, feature entitlements)
Data Flow - What Stays vs. What Crosses
Stays in Your Azure Subscription (stored at rest):
- Document source data (templates, field values, business context)
- Rendered PDF bytes (all rendering pipelines, all transformations)
- Signature bytes and images — stored in your Azure Table Storage and sealed into your Blob Storage; not persisted on portal servers (see note below)
- Form field values (initials, date, text, checkboxes)
- Signing workflow state (session state, slot status, completion tracking)
- Complete audit trail (every state change with timestamps)
- Evidence certificates — generated in your Processor and stored in your Blob Storage
Signature bytes transit note
The signer draws their signature in the portal's browser UI. When the signer submits, the portal constructs an HMAC-signed callback POST body — which includes the signature PNG — and sends it to your Dispatcher (POST /api/esign/callback). The signature bytes therefore transit through Vault Shared Services servers in-memory during callback dispatch. They are not stored on portal servers and the callback is HMAC-verified by your Dispatcher before use. For use cases requiring strict zero-egress of signature data, evaluate whether this in-transit processing meets your requirements.
All encrypted at rest in your storage. All in the Azure region of your choice.
Crosses to Vault Shared Services:
- Signer email address — for invitation delivery via Azure Communication Services
- Signer name and signature PNG — in-memory during HMAC callback dispatch to your Dispatcher (not stored on portal)
- Portal access token — stateless, time-limited, single-use HMAC-signed token
- Correlation ID — for distributed tracing across your Dispatcher and our systems
- Session state notifications — pending → signed, no document content
Protection of External Data:
All metadata transmitted to Vault Shared Services is protected under:
- HTTPS/TLS encryption in transit (AES-256)
- Data Processing Agreement (DPA) with Refract Logic
- Microsoft Standard Contractual Clauses (via Azure Communication Services)
- Email addresses hashed in any audit storage (HMAC-SHA256)
Compliance by Regulation
| Regulation | Your Control | Vault Shared Services | Architecture Posture |
|---|---|---|---|
| HIPAA | Document content stored in your subscription; complete audit trail in your storage; signer PII AES-encrypted at rest | Signer email + name transit in-memory during callback; not persisted; covered under Refract Logic DPA | Supports HIPAA-compliant deployments. Covered entities should review whether Refract Logic requires a BAA for their use case, particularly if signer data constitutes ePHI. |
| GDPR | All document processing in your Azure region; personal data (email, signature) encrypted at rest; data processing under DPA | Email processed under Standard Contractual Clauses with Microsoft ACS; Refract Logic DPA covers callback transit | Supports GDPR-compliant deployments. Data residency is in your chosen Azure region. |
| SOX | Immutable audit trail in your subscription; timestamped approval chain; SHA-256 document integrity; non-repudiation via consent acknowledgements | No data storage; metadata only | Architecture generates the audit evidence required to support SOX Section 302/404 documentation requirements. |
| FedRAMP / CUI | Customer-owned deployment into Azure Government regions supported; all rendering and sealing in your subscription | Portal is not FedRAMP-authorized; for CUI workloads, evaluate whether signature transit meets your ATO requirements | Supports deployment into Azure Government regions. FedRAMP authorization is a formal government process — customers operating under an existing ATO should review portal transit requirements with their ISSO. |
Compliance is a shared responsibility
The architecture descriptions above describe how Vault Platform is designed to support compliance. Achieving regulatory compliance requires your own policies, controls, and legal review. Nothing in this documentation constitutes legal or compliance advice. Covered entities, regulated industries, and government customers should engage qualified compliance counsel.
HIPAA Compliance Example
Scenario: Healthcare provider with patient consent forms
Patient Document (stays in your Azure):
├─ Rendered PDF with patient instructions
├─ Patient signature field
└─ Stored in encrypted Blob Storage
Patient Notification (routed through Vault Shared Services):
├─ Email invitation to sign (patient email + name transmitted)
├─ Unique portal link with time-limited token
├─ No document content included
Patient Signature flow:
├─ Signature drawn by patient in portal browser UI
├─ Portal POSTs HMAC-signed callback (includes signature PNG) → your Dispatcher
├─ Dispatcher validates HMAC, enqueues seal to Service Bus
├─ Processor seals PDF with evidence certificate
└─ Signed PDF + certificate stored in your Azure Blob Storage
Relevant considerations for covered entities:
├─ Document bytes (ePHI): stored in your subscription only ✓
├─ Patient email + name: transmitted to Vault Shared Services for portal session
│ → covered under Refract Logic DPA; BAA assessment recommended
├─ Patient signature PNG: transits Vault Shared Services in-memory during callback
│ → not stored; evaluate whether this meets your HIPAA requirements
├─ Audit trail: complete and immutable, in your subscription ✓
└─ Signer PII at rest: AES-256-GCM encrypted in your Azure Table Storage ✓GDPR Compliance Example
Scenario: EU financial services company with contracts
Document Processing (in your Azure region):
├─ Documents stored in EU-West Azure region
├─ All rendering in EU-West
├─ All sealing in EU-West
└─ Data residency: EU (guaranteed)
Signer Notification (routed through Vault Shared Services):
├─ Signer email transmitted to ACS
├─ Covered by Microsoft Standard Contractual Clauses
├─ Data Processing Agreement in place
└─ Signer can exercise right to erasure (email hashed, can be deleted)
Relevant considerations for GDPR:
├─ Documents stored in EU Azure region (data residency in your control) ✓
├─ Personal data (email) processed under Refract Logic DPA and Microsoft SCCs ✓
├─ Right to access: document data and audit records are in your subscription ✓
├─ Right to erasure: signer email is stored as HMAC-SHA256 hash (audit) and as
│ AES-256-GCM encrypted value (operational display). Both must be deleted to
│ satisfy erasure. The encrypted value is in your Azure Table Storage under
│ your control. Hash-only deletion does not fully satisfy right to erasure.
└─ Cross-border: signer email transits Vault Shared Services (covered under SCCs);
confirm Refract Logic's processing region meets your transfer requirements.SOX Compliance Example
Scenario: Financial services company with invoice approvals
Signing Workflow (in your infrastructure):
├─ Invoice generated by AP system
├─ Invoice rendering in your Processor
├─ Invoice sent to Approver 1 (sequential signing mode)
├─ Approver 1 signs, evidence recorded
├─ Invoice sent to Approver 2
├─ Approver 2 signs, evidence recorded
├─ Signed invoice sealed with evidence certificate
Audit Trail (immutable, in your subscription):
├─ Invoice creation timestamp (June 4, 2026, 10:30:00 UTC)
├─ Approver 1 notification (June 4, 2026, 10:31:00 UTC)
├─ Approver 1 review (June 4, 2026, 10:35:00 UTC)
├─ Approver 1 signature (June 4, 2026, 10:36:00 UTC)
├─ Approver 2 notification (June 4, 2026, 10:36:01 UTC)
├─ Approver 2 review (June 4, 2026, 11:02:00 UTC)
├─ Approver 2 signature (June 4, 2026, 11:03:00 UTC)
└─ Document sealed (June 4, 2026, 11:04:00 UTC)
Audit evidence generated (supports SOX Section 302/404 documentation):
├─ Complete approval chain documented with timestamps ✓
├─ Proof of sequential approval order (non-repudiation) ✓
├─ Document integrity verified via SHA-256 hash ✓
├─ Signed consent acknowledgements per signer ✓
└─ Immutable audit trail in your subscription, available for inspection ✓Create Signing Session: Quick Reference
POST /api/esign/sessionAuth: Entra ID JWT
Request body:
{
"correlationId": "rnd-00123",
"documentId": "DOC-456",
"docType": "vendor-contract",
"pdfBlobPath": "generatedDocuments/2026/06/rnd-00123.pdf",
"pdfHash": "sha256:abc123...",
"signingMode": "sequential",
"expiresInMinutes": 4320,
"signers": [
{
"slotIndex": 0,
"role": "vendor",
"email": "[email protected]",
"namePrefill": "Vendor Contact"
},
{
"slotIndex": 1,
"role": "manager",
"email": "[email protected]"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
correlationId | string | Yes | Correlation ID of the rendered PDF to be signed. Used for tracing and audit linking. |
documentId | string | Yes | Document identifier for audit/display purposes (e.g., invoice number, contract ID). |
docType | string | Yes | Document type label (e.g. vendor-contract, purchase-order, consent-form). |
pdfBlobPath | string | Yes | Blob Storage path of the rendered PDF to be signed. |
pdfHash | string | Yes | SHA-256 hash of the rendered PDF (e.g. sha256:abc123...). Stored in the evidence certificate as proof of document integrity at signing time. |
signingMode | single | sequential | parallel | Yes | Controls slot activation order and signing logic. |
expiresInMinutes | number | No | Session TTL in minutes. Defaults to 30. Max 10080 (7 days). Example: 4320 = 3 days. |
signers | array | Yes | One entry per signing slot. Max 10 signers per session. Order matters for sequential mode. |
signers[].slotIndex | number | Yes | Zero-based slot index. Must be unique within the request. Determines signer order. |
signers[].role | string | Yes | Matches the signature block role defined in the PDF template. Determines field positioning. |
signers[].email | string | Yes | Signer's email. Used for invitation delivery and (optionally) OTP delivery. |
signers[].namePrefill | string | No | Pre-fills the signer name field in the portal. Optional, improves UX. |
templatePath | string | No | Blob path to the .vpdf template. When provided, enables automatic field manifest extraction (initials, date fields) without requiring the immutable audit archive. |
Response 201:
{
"groupId": "a3f1c2d4-8e9b-4f0a-b2c3-1d4e5f6a7b8c",
"expiresAt": "2026-06-12T12:00:00.000Z",
"slots": [
{
"slotIndex": 0,
"sessionId": "b5c2d3e4-9f0a-4b1c-d2e3-2e5f6a7b8c9d",
"portalUrl": "https://portal.vaultpdf.io/sign?token=<slotToken>"
},
{
"slotIndex": 1,
"sessionId": "c6d3e4f5-0a1b-4c2d-e3f4-3f6a7b8c9d0e",
"portalUrl": "https://portal.vaultpdf.io/sign?token=<slotToken>"
}
]
}| Field | Type | Description |
|---|---|---|
groupId | string | UUID for this signing session. Use this to poll status, cancel, or revoke. |
expiresAt | string | ISO 8601 timestamp when the session expires. |
slots | array | Array of signing slots, one per signer. |
slots[].slotIndex | number | Zero-based slot index (matches request). |
slots[].sessionId | string | Per-slot UUID used by the portal for session state tracking. |
slots[].portalUrl | string | HTTPS URL the signer visits to complete signing. Contains an embedded single-use token (?token=). Forward this to the signer via email or your own notification. |
Field Manifest Configuration
Configure additional signing fields (initials, dates, checkboxes, text) alongside the primary signature using the Field Manifest.
Example: AP 3-Way Match
A complete governance workflow schema for AP 3-way match validation: PO vs. Goods Receipt vs. Invoice. Uses autoValidateOnCreate to run validation without portal interaction, then routes to Finance Director or AP Manager based on invoice total.
Field Manifest
Configure additional signing fields alongside the primary signature, including initials, date fields, checkboxes, and freeform text, using the VaultESign Field Manifest. All field data is stored in your Azure subscription.