Core Concepts

Audit Logs

How to configure REFRACT PDF's audit system. Covers the basic (SharePoint JSONL) and blob (Azure Blob AppendBlob) audit tiers, the AuditEvent schema, file naming, and setup steps for each tier. The enterprise tier is withdrawn.

Overview

REFRACT PDF writes two distinct records for every render request:

RecordWherePurpose
JSONL audit trailSharePoint Audit Logs library or Azure BlobComprehensive lifecycle log for compliance and troubleshooting
REFRACT_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, REFRACT PDF 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, and audit logs in your audit-logs storage container

Both tiers produce the same event schema and the same JSONL file format. The difference is where the files land.

The enterprise tier is withdrawn; see Enterprise Tier.

Tier comparison

FeatureBasicBlob
Where the files are writtenSharePoint Audit Logs libraryAzure Blob Storage (deployed on every install)
Concurrent render safetyEvery write is conditional and a lost race is retried up to 5 times; an event is lost only if all 5 attempts lose, and that failure is loggedSafe
Suitable for high volumeNoYes
Additional costNoneLow (storage)

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 audit logs in an Azure Storage container rather than a SharePoint library
  • You want the audit files under your storage account's own retention and immutability settings (see Retention Policy)

Setup

  1. Create an audit-logs container in your Azure Storage account.
  2. Ensure the REFRACT PDF 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'): withdrawn

This tier has been withdrawn and there is nothing to set up. Use the Blob Tier instead.

The enterprise audit tier (auditLogs: 'enterprise') is withdrawn. It was never available: no REFRACT installer deploys its Service Bus queue or its Audit Worker, and with this value audit events were written to the SharePoint Audit Logs library instead, with no immutability policy. Do not configure it. Starting with the release that withdraws it, a storage-config.json that names enterprise is refused: renders with audit logging fail with 503 and code AUDIT_TIER_WITHDRAWN until auditLogs is set to blob or basic. If you configured it, change it to blob. Events already written to the SharePoint library stay there; they are not moved.


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
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'REFRACT_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": "user@contoso.onmicrosoft.com",
  "templatePath": "/Templates/Invoice.rpkg",
  "payloadPath": "/Payloads/BC-INV-2026-03-31.json",
  "outputPath": "Invoice/2026/03/BC-INV-2026-03-31_Invoice_2026-03-31.pdf",
  "blobSasUrl": "https://contosorefractstorage.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

Where the files are written:

  • Basic tier: the SharePoint Audit Logs library, in a folder per month: {YYYY}/{MM}/audit-{YYYY}-{MM}-part{N}.jsonl. The first file of every month is part1.
  • Blob tier: the audit-logs container, at the container root: audit-{YYYY}-{MM}-part{N}.jsonl.

To read a month back, take every part and order them by N as a number: part10 comes after part9, while an alphabetical sort puts it after part1.

Rotation thresholds

A new part file is created before an event would pass any threshold:

ThresholdBasic tier (SharePoint)Blob tier
File size3.5 MB, so every write stays under the 4 MB SharePoint simple-upload limit50 MB
Events (one block each)Unlimited45,000 committed blocks, below Azure's 50,000-block limit for an append blob. An append that still reaches the limit rolls to the next part and retries

None of these thresholds can be configured.

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


On this page