Core Concepts

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.

Overview

VaultPDF writes two distinct records for every render request:

RecordWherePurpose
JSONL audit trailSharePoint Audit Logs library or Azure BlobComprehensive lifecycle log for compliance and troubleshooting
VaultPDF_Activity itemSharePoint listHuman-readable render history browsable directly in SharePoint

This page covers the JSONL audit trail. The Activity list is written automatically based on your SharePoint configuration -- no separate setup is required.


Choose an Audit Tier

Select your audit tier by setting auditLogs in storage-config.json. If you omit this setting, VaultPDF defaults to basic.

TierConfig valueRecommended for
Basic'basic'Low-to-medium volume deployments already using SharePoint for output
Blob'blob'Medium-to-high volume deployments routing other outputs to Azure Blob
Enterprise'enterprise'High volume, compliance requirements, or guaranteed-delivery scenarios

All three tiers produce the same event schema and the same JSONL file format. The difference is where the files land and how reliably events are delivered under load.

Tier comparison

FeatureBasicBlobEnterprise
Infrastructure requiredSharePoint onlyAzure Blob StorageAzure Blob + Service Bus
Concurrent render safetyPartial (best-effort)SafeFully serialised
Guaranteed deliveryNoNoYes (queue + dead-letter)
Dead-letter monitoringNoNoYes
Suitable for high volumeNoYesYes
Additional costNoneLow (storage)Low (storage + Service Bus)

Basic Tier (auditLogs: 'basic')

Audit events are appended to a JSONL file in the SharePoint Audit Logs library. No additional Azure infrastructure is required.

When to use

  • Your deployment already routes all output to SharePoint
  • Render volume is moderate (under ~50,000 events per month)
  • You do not have strict compliance requirements for zero event loss

Setup

  1. Ensure the Audit Logs library exists in your SharePoint site and its drive ID is set in sp-config.json:
{
  "driveIds": {
    "Audit Logs": "<drive-id>"
  },
  "features": {
    "auditLogs": true
  }
}
  1. In storage-config.json, either omit auditLogs (basic is the default) or set it explicitly:
{
  "libraryRoutes": {
    "auditLogs": "basic"
  }
}

Blob Tier (auditLogs: 'blob')

Audit events are written directly to an Azure Blob AppendBlob. This gives lower latency and safe concurrent writes from multiple render instances.

When to use

  • You are already routing generated documents to Azure Blob
  • You want reliable audit writes without the overhead of a Service Bus queue
  • You do not need guaranteed delivery or dead-letter monitoring

Setup

  1. Create an audit-logs container in your Azure Storage account.
  2. Ensure the VaultPDF app's Managed Identity has Storage Blob Data Contributor on the storage account.
  3. Update storage-config.json:
{
  "libraryRoutes": {
    "auditLogs": "blob"
  },
  "accountName": "your-storage-account",
  "blobContainers": {
    "auditLogs": "audit-logs"
  }
}

Enterprise Tier (auditLogs: 'enterprise')

Audit events are enqueued to an Azure Service Bus queue. A separate Audit Worker dequeues them and writes to Azure Blob. This guarantees delivery -- events that cannot be written after repeated attempts are moved to a dead-letter queue for manual review rather than silently dropped.

When to use

  • High or unpredictable render volume
  • Compliance requirements that cannot tolerate any audit event loss
  • You need alerting on dead-lettered audit events

Azure resources to provision

  1. Create a Standard or Premium Azure Service Bus namespace.
  2. Create a queue with these settings:
SettingRecommended value
Queue nameaudit-events
Max delivery count10
Dead-lettering on message expiryEnabled
Message TTLP7D (7 days)
Lock durationPT1M (1 minute)
SessionsDisabled
  1. Create two Shared Access Policies on the queue:

    • render-send -- Send rights only (used by the VaultPDF render service)
    • worker-listen -- Listen rights only (used by the Audit Worker service)
  2. Create an audit-logs container in your Azure Storage account.

  3. Ensure the Audit Worker's Managed Identity has Storage Blob Data Contributor on the storage account.

Configuration

Update storage-config.json on the render service:

{
  "libraryRoutes": {
    "auditLogs": "enterprise"
  },
  "accountName": "your-storage-account",
  "blobContainers": {
    "auditLogs": "audit-logs"
  }
}

Set the following app settings on the render service:

SettingValue
AUDIT_SERVICEBUS_CONNECTION_STRINGConnection string for the render-send policy (use a Key Vault reference)

Set the following app settings on the Audit Worker service:

SettingValue
AUDIT_SERVICEBUS_CONNECTIONConnection string for the worker-listen policy (use a Key Vault reference)
AUDIT_SERVICEBUS_QUEUE_NAMEaudit-events (or your custom queue name)
AUDIT_BLOB_ACCOUNT_NAMEYour Azure Storage account name
AUDIT_BLOB_CONTAINERaudit-logs (or your custom container name)

AuditEvent Schema

All three tiers write events in the same format. Each line in a JSONL file is one event with no trailing comma.

Core fields (always present)

FieldTypeDescription
correlationIdstringUnique ID for the render request
actionstringLifecycle step (see table below)
statusstring'Success', 'Failure', or 'Warning'
timestampstringISO 8601 timestamp

Additional fields

FieldTypeDescription
tenantIdstring | nullSharePoint tenant identifier
userIdstring | nullEntra ID of the user who triggered the render
templatePathstring | nullRelative path of the template used
payloadPathstring | nullRelative path of the payload document
outputPathstring | nullDestination path of the generated PDF
blobUrlstring | nullAzure Blob URL of the output (when routed to blob)
blobSasUrlstring | nullTime-limited SAS URL (browser-accessible)
fileSizeBytesnumber | nullSize of the generated PDF in bytes
durationMsnumber | nullRender duration in milliseconds
errorMessagestring | nullError detail on status: 'Failure'
templateVersionstring | nullContent hash or version label of the template
extraobject | nullArbitrary extension fields from the render payload

Action values

ValueDescription
'PayloadReceived'Render request accepted and validated
'PDFGenerated'PDF created successfully
'PDFGenerationFailed'PDF generation failed
'UploadStarted'Upload to storage provider initiated
'UploadCompleted'Upload finished successfully
'UploadFailed'Upload failed
'AuditWriteStarted'Audit record write initiated
'AuditWriteCompleted'Audit record written and confirmed
'AuditWriteFailed'Audit record write failed
'ActivityPosted'VaultPDF_Activity item created or updated

Example event

{
  "correlationId": "BC-INV-2026-03-31",
  "action": "UploadCompleted",
  "status": "Success",
  "timestamp": "2026-03-31T14:22:03.451Z",
  "userId": "[email protected]",
  "templatePath": "/Templates/Invoice.vpdf",
  "payloadPath": "/Payloads/BC-INV-2026-03-31.json",
  "outputPath": "Invoice/2026/03/BC-INV-2026-03-31_Invoice_2026-03-31.pdf",
  "blobSasUrl": "https://vaultpdfstorage.blob.core.windows.net/generated-documents/Invoice/2026/03/...",
  "fileSizeBytes": 84210,
  "durationMs": 1203,
  "errorMessage": null
}

File Naming & Rotation

Audit files are scoped to calendar month and split into numbered parts when size thresholds are exceeded.

Naming pattern

audit-{YYYY}-{MM}-part{N}.jsonl

Examples:

audit-2026-03-part1.jsonl
audit-2026-03-part2.jsonl
audit-2026-04-part1.jsonl

Rotation thresholds

A new part file is created when either threshold is exceeded:

ThresholdDefaultOverride
File size50 MBSet AUDIT_MAX_PART_SIZE_BYTES on the Audit Worker (enterprise)
Record countUnlimitedNot configurable

At each month boundary, part numbering resets to 1 regardless of the current file size.


On this page