Protect a PDF with a user password and an owner password. Choose AES-256 and configure fine-grained permission flags.
use pdfluent::prelude::*;
fn main() -> Result<()> {
let mut doc = PdfDocument::open("report.pdf")?;
doc.encrypt(
EncryptOptions::aes256()
.with_user_password("open123")
.with_owner_password("owner_secret")
.with_permissions(
Permissions::full_access()
.with_modify(false)
.with_copy(false),
),
)?;
doc.save("report_protected.pdf")?;
Ok(())
}Open the document you want to protect. Use a mutable binding.
use pdfluent::prelude::*;
let mut doc = PdfDocument::open("report.pdf")?;EncryptOptions::aes256() uses AES-256, which is the current best practice. EncryptOptions::aes128() is accepted but the 1.0 backend currently always emits AES-256 state; if strict 128-bit output matters for interop, track this as a known deviation.
let opts = EncryptOptions::aes256();The user password is required to open the document. The owner password unlocks all permissions. If you omit with_user_password, the document opens without a password but still enforces permission flags.
let opts = opts
.with_user_password("open_document_2025")
.with_owner_password("full_access_secret");Start from a preset (Permissions::full_access, print_only, read_only, or annotate) and opt out of individual rights with the with_*(false) builders: with_print, with_modify, with_copy, with_annotate, with_fill_forms, with_extract_accessibility, with_assemble, with_print_high_quality.
let perms = Permissions::full_access()
.with_modify(false)
.with_copy(false);
let opts = opts.with_permissions(perms);Call encrypt() then save() to write the protected file. encrypt takes EncryptOptions by value (no reference).
doc.encrypt(opts)?;
doc.save("report_protected.pdf")?;No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.
Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.
Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.