Core Concepts

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.

ProviderRole
SharePointAlways 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 StorageOptional. 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:

ValueHow to retrieve
siteIdCall GET https://graph.microsoft.com/v1.0/sites/{hostname}:{path} and copy the id field
driveIdsCall GET https://graph.microsoft.com/v1.0/sites/{siteId}/drives and match each library by name
VaultPDF_Activity list IDCall 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.

FlagEffect when false
features.generatedDocumentsGenerated PDFs are not uploaded to SharePoint
features.reportsError and scheduled reports are not uploaded
features.archiveArchive writes are skipped
features.auditLogsAudit 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-scoped Sites.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:

  1. Create an Azure Storage account (general-purpose v2 or later).
  2. Create a container for each library you want to route to Blob (e.g. generated-documents, document-archive).
  3. Assign the Storage Blob Data Contributor role to the VaultPDF app's Managed Identity on the storage account.
  4. Set STORAGE_CONFIG_PATH in your app settings to the path of your storage-config.json file.
  5. Configure storage-config.json as described in the next section.

Blob naming convention

Files written to Azure Blob follow this path pattern:

{DocType}/{YYYY}/{MM}/{correlationId}_{fileName}.pdf

Examples:

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.pdf

SAS 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

FieldTypeRequiredDefaultDescription
libraryRoutesobjectYes--Per-library routing declarations
accountNamestringWhen any route is blob--Azure Storage account name
blobContainersobjectWhen any route is blob--Library to container name map
sasUrlExpiryDaysnumberNo30Days until generated SAS URLs expire. Max recommended: 180.

libraryRoutes valid values

LibraryValid valuesDefault
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.

VariableRequiredDescription
SP_CONFIG_PATHYesAbsolute path to sp-config.json on the deployment filesystem
SP_SECRETSYesJSON string with tenantId, clientId, clientSecret for SharePoint access
STORAGE_CONFIG_PATHNoAbsolute path to storage-config.json. When absent, all output routes default to SharePoint.
AUDIT_SERVICEBUS_CONNECTION_STRINGWhen auditLogs: enterpriseService 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.

HeaderPresent whenValue
X-VaultPDF-UploadStatusAlwaysok, failed, or skipped
X-VaultPDF-UploadErrorUpload failed or skippedError message (newlines stripped, max 512 chars)
X-VaultPDF-WebUrlgeneratedDocuments: sharepointSharePoint item web URL
X-VaultPDF-DriveItemIdgeneratedDocuments: sharepointSharePoint DriveItem ID
X-VaultPDF-BlobUrlgeneratedDocuments: blobRaw Blob URL
X-VaultPDF-BlobSasUrlgeneratedDocuments: blobTime-limited SAS URL (browser-accessible)
X-VaultPDF-AuditStatusAudit write skipped or failedskipped: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.


On this page