Pass a user or owner password through OpenOptions to decrypt a PDF at load time, then work with it like any other document.
use pdfluent::prelude::*;
fn main() -> Result<()> {
let doc = PdfDocument::open_with(
"confidential.pdf",
OpenOptions::new().with_password("hunter2"),
)?;
println!("Opened {} pages", doc.page_count());
Ok(())
}PdfDocument::open_with takes a path and an OpenOptions. Chain .with_password(...) to pre-provision the user or owner password. Owner passwords grant full access regardless of permissions.
use pdfluent::prelude::*;
let opts = OpenOptions::new().with_password("hunter2");
let doc = PdfDocument::open_with("confidential.pdf", opts)?;A wrong password returns Error::DecryptionFailed with reason WrongPassword. Match on the stable error code to prompt the user or fall back to a password-recovery flow.
use pdfluent::prelude::*;
match PdfDocument::open_with(
"confidential.pdf",
OpenOptions::new().with_password("maybe_wrong"),
) {
Ok(doc) => println!("opened with {} pages", doc.page_count()),
Err(e) if e.code() == "E-SECURITY-DECRYPTION-FAILED" => {
eprintln!("wrong password — try again");
}
Err(e) => return Err(e),
}Don't hard-code secrets. Read the password from your runtime's secret manager — environment variable, vault, or a config file loaded through your existing secret-management layer.
use pdfluent::prelude::*;
let pw = std::env::var("PDF_OPEN_PASSWORD")
.expect("PDF_OPEN_PASSWORD env var not set");
let doc = PdfDocument::open_with(
"confidential.pdf",
OpenOptions::new().with_password(pw),
)?;If the PDF is already in memory (blob from a database, response from an API), use from_bytes_with with the same OpenOptions. No filesystem roundtrip required.
use pdfluent::prelude::*;
let bytes: Vec<u8> = fetch_from_backend()?;
let doc = PdfDocument::from_bytes_with(
&bytes,
OpenOptions::new().with_password("hunter2"),
)?;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.