Storage Providers
How to configure VaultPDF's storage system. Covers SharePoint setup, Azure Blob Storage setup, output routing via storage-config.json, required environment variables, and the response headers returned on each render.
Overview
VaultPDF uses two storage providers. You configure which one handles each output library using storage-config.json.
| Provider | Role |
|---|---|
| SharePoint | Always active. VaultPDF reads all templates, payloads, configurations, and assets from your SharePoint site. SharePoint can also receive generated PDFs, reports, and archive files. |
| Azure Blob Storage | Optional. Route any output library (generated documents, reports, archive, audit logs) to an Azure Storage account instead of SharePoint. |
SharePoint is always required. Azure Blob Storage is provisioned only when you route at least one output library to blob in your storage-config.json.
Step 1 -- Configure SharePoint
sp-config.json
VaultPDF needs the SharePoint site and library identifiers for your tenant. Provide these in sp-config.json, which is deployed alongside the VaultPDF service.
{
"siteId": "contoso.sharepoint.com,<site-guid>,<web-guid>",
"driveIds": {
"Templates": "<drive-id>",
"System Templates": "<drive-id>",
"Configurations": "<drive-id>",
"Payloads": "<drive-id>",
"Generated Documents": "<drive-id>",
"Reports": "<drive-id>",
"Archive": "<drive-id>",
"Audit Logs": "<drive-id>"
},
"lists": {
"VaultPDF_Activity": "<list-id>"
},
"features": {
"generatedDocuments": true,
"reports": true,
"archive": true,
"auditLogs": true
}
}How to find your IDs:
| Value | How to retrieve |
|---|---|
siteId | Call GET https://graph.microsoft.com/v1.0/sites/{hostname}:{path} and copy the id field |
driveIds | Call GET https://graph.microsoft.com/v1.0/sites/{siteId}/drives and match each library by name |
VaultPDF_Activity list ID | Call GET https://graph.microsoft.com/v1.0/sites/{siteId}/lists and match by displayName |
Feature flags
The features object controls which output libraries are active. Set a flag to false to silently skip writes to that library.
| Flag | Effect when false |
|---|---|
features.generatedDocuments | Generated PDFs are not uploaded to SharePoint |
features.reports | Error and scheduled reports are not uploaded |
features.archive | Archive writes are skipped |
features.auditLogs | Audit JSONL writes to SharePoint are skipped |
When a library is routed to Azure Blob in storage-config.json, VaultPDF automatically treats its feature flag as enabled -- you do not need to set it to true in sp-config.json.
SP_SECRETS environment variable
The SharePoint credentials are provided as a JSON string in the SP_SECRETS environment variable. Set this in your production app settings, backed by a Key Vault reference.
{
"tenantId": "<azure-ad-tenant-id>",
"clientId": "<app-registration-client-id>",
"clientSecret": "<secret>"
}The app registration must have the following Microsoft Graph application permissions on your SharePoint site:
Sites.ReadWrite.All(or site-scopedSites.Selected)Files.ReadWrite.All
Step 2 -- Choose Output Storage
By default, all generated documents are written back to SharePoint. If you want some or all output libraries routed to Azure Blob Storage instead, follow the steps below.
SharePoint only (default)
No additional configuration needed. Omit STORAGE_CONFIG_PATH from your app settings, or create a storage-config.json with all routes set to sharepoint:
{
"libraryRoutes": {
"generatedDocuments": "sharepoint",
"reports": "sharepoint",
"archive": "sharepoint",
"auditLogs": "basic"
},
"accountName": "",
"blobContainers": {}
}Azure Blob Storage (optional)
To route one or more output libraries to Azure Blob:
- Create an Azure Storage account (general-purpose v2 or later).
- Create a container for each library you want to route to Blob (e.g.
generated-documents,document-archive). - Assign the Storage Blob Data Contributor role to the VaultPDF app's Managed Identity on the storage account.
- Set
STORAGE_CONFIG_PATHin your app settings to the path of yourstorage-config.jsonfile. - Configure
storage-config.jsonas described in the next section.
Blob naming convention
Files written to Azure Blob follow this path pattern:
{DocType}/{YYYY}/{MM}/{correlationId}_{fileName}.pdfExamples:
Invoice/2026/03/BC-INV-001_Invoice_2026-03-31.pdf
Reports/RenderErrors/2026/03/abc-123_error_VaultPDF.pdf
document-archive/2026/01/abc-100_SO-00400-Invoice.pdfSAS URLs
After every upload to Blob, VaultPDF generates a time-limited SAS URL. The expiry window is set by sasUrlExpiryDays in storage-config.json (default: 30 days, max recommended: 180 days). The SAS URL is returned in the X-VaultPDF-BlobSasUrl response header and stored in the Activity list item so users can open the document directly from SharePoint.
storage-config.json
storage-config.json controls which output libraries go to SharePoint and which go to Azure Blob. Deploy this file alongside the VaultPDF service and set STORAGE_CONFIG_PATH to its path.
Full schema
{
"libraryRoutes": {
"generatedDocuments": "sharepoint | blob",
"reports": "sharepoint | blob",
"archive": "sharepoint | blob",
"auditLogs": "basic | blob | enterprise"
},
"accountName": "your-storage-account-name",
"blobContainers": {
"generatedDocuments": "generated-documents",
"reports": "reports",
"archive": "document-archive",
"auditLogs": "audit-logs"
},
"sasUrlExpiryDays": 30
}Field reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
libraryRoutes | object | Yes | -- | Per-library routing declarations |
accountName | string | When any route is blob | -- | Azure Storage account name |
blobContainers | object | When any route is blob | -- | Library to container name map |
sasUrlExpiryDays | number | No | 30 | Days until generated SAS URLs expire. Max recommended: 180. |
libraryRoutes valid values
| Library | Valid values | Default |
|---|---|---|
generatedDocuments | 'sharepoint' | 'blob' | 'sharepoint' |
reports | 'sharepoint' | 'blob' | 'sharepoint' |
archive | 'sharepoint' | 'blob' | 'sharepoint' |
auditLogs | 'basic' | 'blob' | 'enterprise' | 'basic' |
Libraries omitted from libraryRoutes fall back to their defaults. If STORAGE_CONFIG_PATH is not set at all, every library defaults to SharePoint.
Example: Reports on SharePoint, everything else on Blob
A common production configuration -- reports stay in SharePoint so users can browse them, generated documents and archive go to Blob for cost efficiency:
{
"libraryRoutes": {
"generatedDocuments": "blob",
"reports": "sharepoint",
"archive": "blob",
"auditLogs": "enterprise"
},
"accountName": "vaultpdfstorage",
"blobContainers": {
"generatedDocuments": "generated-documents",
"archive": "document-archive",
"auditLogs": "audit-logs"
},
"sasUrlExpiryDays": 90
}Example: SharePoint only
{
"libraryRoutes": {
"generatedDocuments": "sharepoint",
"reports": "sharepoint",
"archive": "sharepoint",
"auditLogs": "basic"
},
"accountName": "",
"blobContainers": {}
}Environment Variables
Set these in your production app settings. Use Key Vault references for all secrets.
| Variable | Required | Description |
|---|---|---|
SP_CONFIG_PATH | Yes | Absolute path to sp-config.json on the deployment filesystem |
SP_SECRETS | Yes | JSON string with tenantId, clientId, clientSecret for SharePoint access |
STORAGE_CONFIG_PATH | No | Absolute path to storage-config.json. When absent, all output routes default to SharePoint. |
AUDIT_SERVICEBUS_CONNECTION_STRING | When auditLogs: enterprise | Service Bus connection string with Send rights. Use a Key Vault reference. |
Response Headers
VaultPDF sets the following headers on every successful render response. Which headers are present depends on your libraryRoutes configuration.
| Header | Present when | Value |
|---|---|---|
X-VaultPDF-UploadStatus | Always | ok, failed, or skipped |
X-VaultPDF-UploadError | Upload failed or skipped | Error message (newlines stripped, max 512 chars) |
X-VaultPDF-WebUrl | generatedDocuments: sharepoint | SharePoint item web URL |
X-VaultPDF-DriveItemId | generatedDocuments: sharepoint | SharePoint DriveItem ID |
X-VaultPDF-BlobUrl | generatedDocuments: blob | Raw Blob URL |
X-VaultPDF-BlobSasUrl | generatedDocuments: blob | Time-limited SAS URL (browser-accessible) |
X-VaultPDF-AuditStatus | Audit write skipped or failed | skipped:reason or failed:message |
Your calling application should handle both X-VaultPDF-WebUrl and X-VaultPDF-BlobSasUrl -- the header that appears depends on your routing configuration.
Related Pages
- Audit Logs -- choose and configure an audit tier (basic, blob, enterprise)
- System Architecture -- how VaultPDF fits into your tenant
VaultPDF Rendering Pipeline
VaultPDF processes every template through a deterministic multi-stage rendering pipeline ensuring layout stability, visual consistency, and secure document generation, structured across 12 sequential stages from structure normalization to final PDF output.
Audit Logs
How to configure VaultPDF's audit system. Covers all three audit tiers -- basic (SharePoint JSONL), blob (Azure Blob AppendBlob), and enterprise (Service Bus + Audit Worker) -- including the AuditEvent schema, file naming, and setup steps for each tier.