0

Permissions

How pdfcn honors a PDF's permission flags, and how to override them.

Every PDF carries a set of permission flags — whether it may be printed, copied, annotated, or edited. embedpdf reads those flags on open and enforces them at the source: the print plugin refuses to print a document that forbids it, the selection plugin refuses to copy, and so on. That enforcement is already in place; nothing needs installing to turn it on.

What the plugins don't do is tell the user. A button wired to a forbidden action still looks clickable, and clicking it just does nothing. pdfcn's chrome closes that gap — a control whose action the document forbids renders disabled, with a tooltip that says why.

What reflects the flags

These four controls read the active document's effective permissions and disable themselves when the matching flag is denied. Each is a standalone component, so this works whether you install them individually or through the viewer block.

ControlRequires permissionName in overrides
PdfPrintButtonPrintprint
PdfCaptureButtonCopy contentscopyContents
PdfAnnotationToolbarModify annotationsmodifyAnnotations
PdfRedactionToolbarModify contentsmodifyContents

There's nothing to wire up. A control disables itself when its permission is denied; when the flag is present, it behaves normally.

Here's the print button against a document whose print flag is denied — disabled, with a tooltip on hover. Download sits beside it untouched, since nothing gates it:

"use client";

import { PdfToolbar } from "@/components/pdf-toolbar";

Each control's own page carries the same demo for its flag: copying, annotating, and editing.

Overriding a document's flags

Permissions resolve in layers: a per-document override wins over the PDF's own flags. Pass a permissions config alongside a document to force a flag on or off, regardless of what the file says.

<PdfViewer
  documents={[
    {
      url: "/sample.pdf",
      permissions: {
        // true = force allow, false = force deny.
        overrides: { print: false, copyContents: false },
      },
    },
  ]}
  className="h-[720px]"
>
  <PdfViewerContent />
</PdfViewer>

Use false to deny an action the PDF otherwise allows — a viewer that never prints, say. Use true to grant one the PDF withholds, which is what you'd reach for when your app is the authority on access and the file's own flags are noise.

An override left undefined falls through to the PDF's flag, so you only list the ones you mean to change.

Ignoring the PDF's flags entirely

To start from "everything allowed" and layer overrides on top — rather than starting from what the file declares — set enforceDocumentPermissions to false:

permissions: {
  // Ignore the PDF's flags; treat every action as allowed…
  enforceDocumentPermissions: false,
  // …except the ones you deny here.
  overrides: { print: false },
}

This is the escape hatch for documents whose flags are wrong or missing, when your own backend already decides who may do what.

Where the model comes from

The flags, the layered resolution, and the plugin-level enforcement are embedpdf's, documented under Security. pdfcn adds the part a headless engine can't: chrome that shows the user which actions the document has taken off the table.