A practical guide for Rust developers. Learn how to add encryption with permissions, perform proper redaction, apply digital signatures, and process files on your server.
Apply 128-bit RC4 or 256-bit AES encryption. Set user and owner passwords. Restrict printing, copying, and editing per PDF spec.
use pdfluent::{PdfDocument, EncryptOptions, Permissions};
fn main() -> pdfluent::Result<()> {
let mut doc = PdfDocument::open("contract.pdf")?;
let opts = EncryptOptions::aes256()
.with_user_password("view-only")
.with_owner_password("owner-secret-42")
.with_permissions(Permissions::print_only());
doc.encrypt(opts)?;
doc.save("contract-encrypted.pdf")?;
println!("Document encrypted with AES-256");
Ok(())
}True PDF redaction that permanently removes content from the content stream — not just the visible layer.
use pdfluent::{PdfDocument, RedactOptions};
fn main() -> pdfluent::Result<()> {
let mut doc = PdfDocument::open("sensitive.pdf")?;
doc.redact("CONFIDENTIAL", RedactOptions::new())?;
doc.redact(r"\d{3}-\d{2}-\d{4}", RedactOptions::new().regex(true))?;
doc.save("redacted.pdf")?;
Ok(())
}Enterprise digital signatures with PAdES-LTV and S/MIME support. 0 failures on 20,000 PDFs. HSM integration available.
use pdfluent::{PdfDocument, Pkcs12Signer, SignOptions, PadesProfile};
fn main() -> pdfluent::Result<()> {
let mut doc = PdfDocument::open("contract.pdf")?;
let signer = Pkcs12Signer::from_pfx_file("signing.p12", "cert-password")?;
let opts = SignOptions::new()
.reason("Approved")
.location("Amsterdam, NL")
.profile(PadesProfile::LongTerm);
doc.sign(&signer, opts)?;
doc.save("contract-signed.pdf")?;
let report = doc.verify_signatures()?;
println!("All signatures valid: {}", report.all_valid());
Ok(())
}PDFluent runs entirely in-process. No HTTP calls to external services, no telemetry, no license server checks at runtime. Your documents stay inside your infrastructure.
use pdfluent::prelude::*;
fn main() -> Result<()> {
// On-premise setup: license from env var, no phone-home,
// no telemetry. All processing is fully in-process.
// Licensing: 30-day trial built into every package; production use requires a commercial licence.
// Details: https://pdfluent.com/docs/licensing
let doc = PdfDocument::open("invoice.pdf")?;
println!("Opened document with {} pages", doc.page_count());
Ok(())
}US and EU regulators are actively pushing organizations away from C-based PDF dependencies. PDFluent is written in Rust — no C, no CVEs, no manual memory management.
use pdfluent::PdfDocument;
// The Result type makes error handling explicit — no segfaults possible.
// Buffer overflows and use-after-free bugs are eliminated by the Rust compiler.
fn process_pdf(path: &str) -> anyhow::Result<()> {
// open() returns Result<Document, Error> — never a null pointer.
let doc = PdfDocument::open(path)?;
let page_count = doc.page_count();
let title = doc.metadata().title().unwrap_or("(no title)");
println!("Opened: {} ({} pages)", title, page_count);
// doc is dropped here — memory is freed deterministically.
// No garbage collector, no memory leak, no use-after-free.
Ok(())
}