Minimal Python SDK for SecurePDF
Project description
SecurePDF
SecurePDF is a lightweight, two-layer PDF security system that prioritizes custodianship-by-access over traditional DRM. Secure your PDFs with encryption, labels, provenance tracking, and tamper detection—all while maintaining forensic accountability.
⚡ Status: v0.0.1 Released (Alpha) — Production-ready core features with 141+ passing tests.
🛡️ Core Philosophy: Custodianship-by-Access
When a recipient opens a document secured by SecurePDF, they clearly understand:
- ✅ The document is intended specifically for them
- ✅ They are the designated custodian of this specific copy
- ✅ Sharing or misuse makes them directly responsible
SecurePDF focuses on forensic accountability and clear intent rather than impossible DRM or remote-kill switches.
🏗️ Architecture
SecurePDF uses a deliberate two-layer design for maximum performance and ease of integration:
-
🚀 Go Engine (
securepdf-engine): High-performance, stateless transformation core- PDF parsing and rewriting
- AES-256 encryption (PBKDF2 key derivation)
- Labeling primitives (visible + invisible)
- Provenance and tamper detection
- Structured JSON receipts
-
🐍 Python SDK (
securepdf): Developer-friendly orchestration layer- Policy composition and validation
- Batch processing support
- Type-safe API with beartype
- Typed exceptions for all error codes
- CLI wrapper included
PDF + Policy → [ Go Engine ] → Secured PDF + Receipt (JSON)
✨ Key Features (v0.0.1)
🔐 Security
- AES-256 Encryption (default) with PBKDF2 key derivation
- AES-128 compatibility mode for broader viewer support
- Configurable Permissions: Print, copy, modify controls
- Weak Crypto Warnings: Automatic alerts for legacy encryption
🏷️ Labels & Classification
- Visible Labels: Headers and footers with page filtering
- Invisible Labels: Metadata-based classification (no visual impact)
📊 Provenance & Tracking
- Unique IDs: Auto-generated document_id and copy_id (UUIDv4)
- Timestamp Recording: Track when PDFs were secured
- Metadata Embedding: All provenance data embedded in PDF
🛡️ Tamper Detection
- SHA-256 Content Hashing: Cryptographic hash of original content
- Forensic Verification: Detect if PDF has been modified
- Multiple Hash Profiles: Objects-only, content-streams, external
📋 Audit Trail
- Structured Receipts: JSON receipts for every transformation
- Error Codes: 13 error codes (E001-E012, E099)
- Warning Codes: 8 warning codes (W001-W008)
- Comprehensive Metadata: Hashes, IDs, timestamps, versions
🚀 Quick Start
Installation
Prerequisites: Go 1.24.0+, Python 3.10+
# Clone repository
git clone https://github.com/ravishtiwari/pdf-secure.git
cd pdf-secure
# Build Go Engine
cd engine
go build -o ../bin/securepdf-engine ./cmd/securepdf-engine
# Install Python SDK
cd ../python
pip install -e .
5-Minute Tutorial
1. Create a Policy (policy.json)
{
"policy_version": "1.0",
"encryption": {
"enabled": true,
"mode": "password",
"user_password": "SecurePassword123!"
},
"provenance": {
"enabled": true,
"document_id": "auto",
"copy_id": "auto"
}
}
2. Secure a PDF (Go Engine)
securepdf-engine secure \
--in input.pdf \
--out secured.pdf \
--policy policy.json \
--receipt receipt.json
3. Or Use Python SDK
from securepdf import secure_pdf, Policy, EncryptionConfig, ProvenanceConfig
policy = Policy(
encryption=EncryptionConfig(enabled=True, user_password="SecurePassword123!"),
provenance=ProvenanceConfig(enabled=True, document_id="auto", copy_id="auto")
)
receipt = secure_pdf("input.pdf", "secured.pdf", policy)
if receipt.ok:
print(f"✅ Success! Document ID: {receipt.document_id}")
else:
print(f"❌ Failed: {receipt.error.message}")
4. Batch Processing
from securepdf import batch_secure_pdf, Policy, EncryptionConfig
policy = Policy(encryption=EncryptionConfig(enabled=True, user_password="secret"))
pairs = [
("doc1.pdf", "secured1.pdf"),
("doc2.pdf", "secured2.pdf"),
("doc3.pdf", "secured3.pdf"),
]
receipts = batch_secure_pdf(pairs, policy, max_workers=4)
print(f"✅ {sum(r.ok for r in receipts)} succeeded")
📚 Documentation
- Usage Guide - Comprehensive tutorial and API reference
- Architecture - System design and philosophy
- Engine Contract - CLI interface and receipt schema
- CHANGELOG - Complete feature list and version history
- Release Notes - v0.0.1 highlights and known limitations
🧪 Testing
SecurePDF v0.0.1 ships with 141+ tests covering all features:
# Run all tests
make all-tests
# Go tests only
make go-unit-tests go-e2e-tests
# Python tests only
make py-unit-tests py-e2e-tests
Coverage:
- ✅ All encryption modes (AES-256, AES-128; RC4-128 deprecated)
- ✅ All labeling features (visible + invisible)
- ✅ Provenance tracking (auto + custom IDs)
- ✅ Tamper detection (all hash profiles)
- ✅ Error handling (all error codes)
- ✅ Batch processing
- ✅ CLI workflows
🛣️ Roadmap
✅ V1.0 (Released: v0.0.1)
- Encryption (AES-256/128)
- Labels (visible + invisible)
- Provenance tracking
- Tamper detection
- Structured receipts
- Python SDK with batch support
🔜 V1.1 (Q2 2026)
- Better error messages and validation UX
- UTF-8/internationalization for labels
- Policy validation dry-run mode
- Enhanced observability
🚀 V2.0 (Q3-Q4 2026)
- High-throughput worker mode
- Distributed architecture support
- Org policies and audit export
- Advanced labeling options
- PDF/UA accessibility support
📁 Project Structure
securepdf/
├── engine/ # Go transformation engine
│ ├── cmd/ # CLI entry point
│ ├── pkg/ # Core packages (policy, receipt, pdf)
│ └── testdata/ # Test fixtures
├── python/ # Python SDK
│ ├── securepdf/ # Package code
│ └── tests/ # Python tests
├── docs/ # Documentation
├── bin/ # Compiled binaries
└── scripts/ # Development tools
🤝 Contributing
We welcome contributions! Please:
- Check existing issues or create a new one
- Fork the repository
- Create a feature branch
- Add tests for new features
- Ensure
make all-testspasses - Submit a pull request
Development workflow:
# Run pre-commit hooks
pre-commit install
# Run tests
make all-tests
# Format code
make fmt
# Lint code
make lint
🐛 Bug Reports & Support
- GitHub Issues: https://github.com/ravishtiwari/pdf-secure/issues
- Security Issues: Please report via GitHub Security Advisories
- Documentation: See
docs/directory
📜 License
MIT License - see LICENSE file for details.
🙏 Acknowledgments
- Implementation: Ravish
- AI Assistance: Claude Sonnet 4.5 (Anthropic)
- PDF Library: pdfcpu (pure Go PDF library)
- Type Checking: beartype (Python runtime validation)
⚡ Quick Links
- 📖 Usage Guide - Get started in 10 minutes
- 🏗️ Architecture - Understand the design
- 📋 CHANGELOG - See what's new
- 🚀 Releases - Download binaries
- 💬 Discussions - Ask questions
SecurePDF v0.0.1 — Secure PDFs with custodianship, not DRM.
Built for accountability. Designed for developers. Ready for production.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pdf_secure-0.0.1-py3-none-win_amd64.whl.
File metadata
- Download URL: pdf_secure-0.0.1-py3-none-win_amd64.whl
- Upload date:
- Size: 7.6 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
324b0495960af6435911b79dac9ff9c119b66d3f885147591056edb080d96848
|
|
| MD5 |
d9bc00a62d6cddd72eadb6d186efe25d
|
|
| BLAKE2b-256 |
5aecf51e9bb511c121d4879ad89314df74e9060d89502cfe1ae747c1b3e02044
|
File details
Details for the file pdf_secure-0.0.1-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: pdf_secure-0.0.1-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 7.5 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06421698afc323c788411a75209a0afa84aacddbc29014abfc5da26a5f339e19
|
|
| MD5 |
68909706fe6ad3b4764b22d5f711049d
|
|
| BLAKE2b-256 |
9f0f15fc8d8af8c28032c0f94f0ad53a678d61667bef45a3c8e2f46348c5c69c
|
File details
Details for the file pdf_secure-0.0.1-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: pdf_secure-0.0.1-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 7.2 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6748f7f7fffc235aef045183f9af5bee5a863b86df59e5de2315d124663cb404
|
|
| MD5 |
74901149c557e3905d39232f6f6ad5e3
|
|
| BLAKE2b-256 |
cd47604fe8bf970d29c633341414db8db88155f75949354a856be74ff4114718
|
File details
Details for the file pdf_secure-0.0.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: pdf_secure-0.0.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.4 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bda419b3b2aa65e04535d773ea48450e855e5cd86dfa3e65c8ae5af49720d135
|
|
| MD5 |
68a9e5cddec350f22190e218ac855ebf
|
|
| BLAKE2b-256 |
36f1515385ba9c5f63cdd9297d994962688627ae6f5d745e6b6efc68cd1eac91
|
File details
Details for the file pdf_secure-0.0.1-py3-none-macosx_10_15_x86_64.whl.
File metadata
- Download URL: pdf_secure-0.0.1-py3-none-macosx_10_15_x86_64.whl
- Upload date:
- Size: 7.6 MB
- Tags: Python 3, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aaccbbcd3476e8675432f7c9fb249d729fb1b935a442499a7ea74a7c313a46e2
|
|
| MD5 |
2774b92dacde37c9352b223e610dc342
|
|
| BLAKE2b-256 |
a61447fc1016db19dd2f5ea80d5e2a30a75ffaa2bfebd40b2b68f41c4a3725a8
|