Skip to main content

Policies & Redaction

Available in: Professional, Business, Enterprise tiers

PII-safe logging and response redaction driven by annotations in your Prisma schema. Automatically mask sensitive data in logs, API responses, and error tracking.

Why Use Policies & Redaction

Problem: Sensitive data leaks everywhere:

  • PII (emails, phone numbers, SSNs) exposed in application logs
  • Passwords and tokens accidentally logged to monitoring services
  • Sensitive fields returned in API responses to unauthorized users
  • Manual redaction is error-prone and inconsistent

Solution: Annotate sensitive fields in your Prisma schema once, then automatically redact them everywhere.

Benefits

  • Schema-Driven: Define policies once in Prisma schema
  • Auto Redaction: Works with all logging libraries
  • Compliance Ready: GDPR, HIPAA, PCI-DSS compliant logging
  • Zero Leaks: Redact before data leaves your application

Prerequisites

# Core dependencies
pnpm add @prisma/client zod

# For error tracking integration (optional)
pnpm add @sentry/node

# PZG Pro license required

Generate

Add to your schema.prisma:

generator pzgPro {
provider = "node ./lib/cli/pzg-pro.js"
output = "./generated/pro"
enablePolicies = true
}

Then run:

prisma generate

Generated Files

generated/
pro/
policies/
safe-crud/
user.ts # User safe CRUD operations
post.ts # Post safe CRUD operations
redaction/
user.ts # User PII redaction middleware
post.ts # Post PII redaction middleware
dto/
user.ts # User DTO schemas
post.ts # Post DTO schemas
index.ts # Exports and factory functions

Schema Annotations

Annotate fields in your Prisma schema:

model User {
id Int @id @default(autoincrement())

/// @pii email redact:logs
/// @policy read:role in ["admin"]
email String @unique

/// @pii phone redact:logs
phone String?

/// @sensitive redact:logs
password String

name String?
}

Basic Usage

Safe CRUD Operations

import { createSafeUserOperations } from '@/generated/pro/policies'
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

// Create safe CRUD with policy context
const userOps = createSafeUserOperations(prisma, {
userId: 'current-user-id',
role: 'user'
})

// Automatically applies read policies
const users = await userOps.findMany()

// Automatically injects userId/tenantId on create
const newUser = await userOps.create({}, {
data: { name: 'John', email: 'john@example.com' }
})

PII Redaction

import { UserRedactor } from '@/generated/pro/policies/redaction/user'

const redactor = new UserRedactor({ redactLogs: true })

// Redact sensitive fields
const safeUser = redactor.redact(user, 'api')
// Result: { email: 's***@example.com', phone: '***-***-1234' }

// Express middleware
import { createUserRedactionMiddleware } from '@/generated/pro/policies/redaction/user'

app.use(createUserRedactionMiddleware())
const sentryTransport = createRedactedSentryTransport()

Integration Examples

Express API

import express from 'express'
import { redactionMiddleware } from '@/generated/pro/policies/redaction'

const app = express()

// Apply redaction middleware
app.use(redactionMiddleware())

app.get('/users/:id', async (req, res) => {
const user = await prisma.user.findUnique({
where: { id: parseInt(req.params.id) }
})

// Response automatically redacts PII fields
res.json(user)
})

Next.js API Routes

// Wrap ctx.body before send using redactPII(ctx.body) for Koa
// Custom interceptor calling redactPII(data) in map() for NestJS

Browser Note

The generated helper uses Node crypto. In the browser, either polyfill (crypto.subtle) or use a minimal email-masking helper.

See Also