Cryptographic Document Vault & Ephemeral Sharing Platform
Passli is an enterprise-grade, privacy-first personal records vault and ephemeral cryptographic sharing platform. Store sensitive documents with AES-256-GCM authenticated encryption at rest and share them with verified recipients via time-gated Share Passesโwithout exposing master cloud credentials, unencrypted email attachments, or cascading folder permissions.
The Problem โข Capabilities โข Architecture โข Quick Start โข Testing โข Deployment Guide
When sharing sensitive records with doctors, employers, financial institutions, or rental agencies, users are traditionally forced to:
- Send raw email attachments that persist indefinitely across third-party mail relays and recipient local storage.
- Share master cloud storage links (Google Drive, Dropbox, iCloud), risking permanent access leakage and folder cascading.
- Hand over unlocked physical devices to unverified third parties during identity or credential inspections.
Passli replaces these vulnerabilities with time-gated, cryptographic Share Passes. You select specific records, define an expiration window (15m, 30m, 1h, 2h, 24h, or single-use view), set download or view-only constraints, and generate an isolated QR code with an 8-character Share Key. When the session expires or is revoked by the owner, recipient access is severed immediately.
- Domain Taxonomy: Organize records into structured categories (
Medical,Education,Vehicle,Personal & Identity,Professional,Other). - Encrypted Document Browser: Filterable vault with instant search and cryptographic SHA-256 integrity inspection.
- Storage Migration CLI: Includes
python manage.py encrypt_vault_storagefor seamless batch migration of legacy storage records.
- Hashed Key Storage: Plaintext 8-character Share Keys (
XXXX-XXXX) are never persisted in the database; only salted PBKDF2-HMAC-SHA256 hashes are retained. - Two-Factor Access Guard: Access requires scanning the isolated session URL plus entering the valid Share Key.
- Granular Permissions: Restrict recipients to in-browser viewing only or grant file download permissions.
- Server-Enforced Expirations: Server-side session termination on timer expiry (15 min to 24 hrs) or burn-after-reading 1-time access.
- Immediate 1-Click Revocation: Instantly terminate any active pass and sever recipient sessions in real-time.
- Mobile-First Experience: Optimized for smartphones scanning QR codes, with swipeable document selector chips and touch-friendly viewers.
- Session Countdown Timer: Real-time ticker notifying recipients of remaining access duration.
- Memory Wipe on Exit: Explicit session termination button clearing in-browser decrypted session references.
- Email Verification: User registration protected by time-gated 6-digit numeric OTP codes.
- Secure Password Reset: One-time cryptographic token links powered by Django's
PasswordResetTokenGenerator. - Automated Security Notifications:
- Immediate password reset confirmation emails.
- Welcome and onboarding guidance upon account activation.
- Brute-force QR passcode alerts triggered after 5 consecutive failed verification attempts.
- SMTP Connectivity Diagnostic: Built-in CLI command
python manage.py test_smtp [recipient]to verify Gmail / SMTP connectivity and authentication.
- Structured Audit Logging: Structured access trail recording IP addresses, user agents, verification successes, failed attempts, and brute-force lockouts.
- Database-Backed Rate-Limiting & Lockouts: Persistent tracking per pass and IP address inside atomic transactions with select_for_update(). Enforces a 1-minute lockout after 5 consecutive failures, doubling up to 24 hours on subsequent failures, and returns HTTP 429 with Retry-After.
- System Telemetry & Storage Analytics: Real-time storage consumption (MB/GB), category breakdown bars, and active pass monitors at
/admin-dashboard/. - User Governance: Searchable user management directory with quota inspection, account activation toggles, and staff role promotions.
- Global File Inventory: Platform-wide vault explorer with SHA-256 hash inspection, encryption status verification, and physical disk file cleanup.
- Emergency Pass Governance: System-wide pass monitor with instant emergency revocation capabilities.
- Unified Settings Dashboard: Accessible at
/settings/for standard users and administrators withCache-Control: no-storeand strict CSRF protection. - Profile Customization: Optional display name (up to 50 characters, control character sanitized) and profile avatar.
- Validated Avatar Pipeline: Validated with Pillow MIME headers (JPEG, PNG, WebP only; max 2 MB; 10M pixel decompression bomb guard; animated/multi-frame files rejected), square-cropped, resized to 256x256, and re-encoded to WebP with EXIF/metadata stripped. Served strictly through an authenticated Django route with
X-Content-Type-Options: nosniffandCache-Control: private(no public/media/routing). - Username Change Policy: Usernames can be changed at most once every 30 days, enforced under atomic database row locks (
select_for_update()). Validated against reserved system identifiers and '@' symbol exclusion to prevent login ambiguity. - Two-Step Email Change: Email addresses are never modified without verification. Changes require current password authorization, store pending state isolated from the user record, dispatch a 6-digit OTP to the new address, and send security notifications to the old address if verified. Addresses are atomically re-checked upon confirmation.
- Dual-Path Password Change:
- Standard: Requires current password re-authentication, enforces
AUTH_PASSWORD_VALIDATORS, rejects previous passwords, updates session auth hashes to maintain current session while invalidating all other sessions, and sends notification to verified emails. - Forgot Password: Authorized users with verified emails can receive a 6-digit email OTP (purpose
change_password), unlocking a 10-minute session window to reset their password without the old credential.
- Standard: Requires current password re-authentication, enforces
- Database-Backed Action Throttling: 5 consecutive failed current-password attempts lock the action for 15 minutes, doubling exponentially per subsequent failure up to 24 hours.
- Account Event Audit: Records security milestones (
username_changed,email_change_requested,email_changed,password_changed,password_otp_sent,avatar_updated,avatar_removed,reauth_failed) with sanitized client IP and user agent metadata. - Transparent Security Disclosures:
- No Two-Factor Authentication (2FA/TOTP): Account login and settings do not currently implement time-based one-time password (TOTP) or hardware security key 2FA.
- Avatars Stored Unencrypted: Unlike vault documents which use AES-256-GCM AEAD encryption at rest, avatar images are stored as standard WebP image files on disk under
MEDIA_ROOT/avatars/. - Email OTPs via SMTP: Verification and reset codes are delivered as 6-digit numerical OTPs via standard transactional SMTP email.
flowchart TD
subgraph Ingestion["Document Upload & Storage"]
A[Plaintext File Upload] --> B[Compute SHA-256 Checksum]
B --> C[Generate 12-byte CSPRNG Nonce]
C --> D[AES-256-GCM AEAD Encryption]
D --> E[Assemble Payload: Nonce + Ciphertext + Tag]
E --> F[(Encrypted Vault Storage on Disk)]
end
subgraph Inspection["In-Memory Decrypted Streaming"]
F --> G[Read Encrypted Payload]
G --> H{Extract Nonce & Verify Tag}
H -- Tag Valid --> I[Decrypt to Memory Buffer - io.BytesIO]
H -- Tamper / Corrupt --> J[Raise VaultDecryptionError -> HTTP 404]
I --> K[Stream to Browser with nosniff & no-store headers]
end
| Specification | Passli Share Pass | Cloud Shared Folders | Email Attachments |
|---|---|---|---|
| Encryption Standard | Client-isolated AES-256 + PBKDF2 key hashing | Server-side at rest only | Unencrypted MIME transit |
| Credential Exposure | Zero exposure (Ephemeral session) | Exposes folder trees & account metadata | Permanent static copies on recipient host |
| Session Expiration | Strict server-enforced timer | Manual disabling; indefinite persistence | Impossible; persists forever in inboxes |
| Granular Access | Itemized per-pass document bundling | All-or-nothing folder cascades | Detached static payloads |
| Audit Visibility | Real-time structured access logs & IP feed | Basic access history (Enterprise only) | Zero visibility after send |
passli/
โโโ accounts/ # User authentication, profiles, superadmin governance & telemetry
โ โโโ admin_views.py # Custom Platform Admin Console views & metric aggregations
โ โโโ admin_urls.py # Admin dashboard routing (/admin-dashboard/)
โ โโโ emails.py # Transactional email service (OTP, password reset, security alerts)
โ โโโ management/commands/ # Accounts management commands (ensure_superadmin, test_smtp)
โ โโโ models.py # User profiles, email verification OTP models
โ โโโ views.py # Signin, registration, OTP verify, password reset views
โโโ documents/ # Document vault, AES-256-GCM encryption models, categorization
โ โโโ management/commands/ # Storage migration commands (encrypt_vault_storage)
โ โโโ models.py # Document model with AES-256-GCM lifecycle & SHA-256 digests
โ โโโ services/
โ โ โโโ crypto_service.py # AES-256-GCM AEAD encryption/decryption primitives & key management
โ โโโ views.py # In-memory decrypted preview & download streams
โโโ sharing/ # Share Pass generation, cryptographic verification & recipient portal
โ โโโ models.py # SharePass model with salted PBKDF2 hash validation
โ โโโ recipient_views.py # Public recipient authentication & in-memory decrypted stream portal
โ โโโ recipient_urls.py # Recipient endpoint routing (/p/<pass_id>/)
โ โโโ utils.py # QR code generator & 8-character Share Key generator
โโโ audit/ # Structured security event logging & immutable audit trail
โ โโโ models.py # ShareAccessLog model & log_share_event utility
โ โโโ views.py # User audit history feed & filtering
โโโ config/ # Django settings, WSGI/ASGI handlers, global URL configuration
โโโ templates/ # Semantic HTML5 templates (Vanilla CSS & Material Symbols)
โ โโโ administration/ # Custom Admin Console templates (overview, users, documents, passes)
โ โโโ documents/ # Vault list, upload, detail, edit, delete templates
โ โโโ emails/ # HTML & plaintext email templates (OTP, reset, alert, welcome)
โ โโโ sharing/ # Recipient verify, portal, and create templates
โ โโโ base.html # Master responsive layout with glassmorphic navbar
โโโ static/ # Front-end design assets
โ โโโ css/styles.css # Human-crafted Vanilla CSS custom properties & design tokens
โ โโโ js/main.js # Client-side micro-interactions & token generators
โ โโโ img/ # Brand vector logos and favicon assets
โโโ tests/ # Automated test suites
โ โโโ unit/ # Comprehensive unit tests
โ โ โโโ test_vault_encryption.py # AES-256-GCM crypto, AAD, tamper, & streaming tests
โ โ โโโ test_recipient_lockout.py # Rate-limiting, brute-force & exponential backoff tests
โ โ โโโ test_security_claims.py # Architectural transparency & security claim validation
โ โ โโโ test_email_integration.py # OTP, password reset, and security alert tests
โ โ โโโ test_documents.py # Document vault CRUD & IDOR tests
โ โ โโโ test_recipient_portal.py # Recipient verification & streaming tests
โ โ โโโ test_sharing.py # Share Pass lifecycle tests
โ โ โโโ test_security.py # Security headers, rate-limiting, and CSRF tests
โ โ โโโ test_accounts.py # User auth & profile tests
โ โ โโโ test_administration.py # Admin Console governance tests
โ โ โโโ test_audit.py # Audit trail & logging tests
โ โ โโโ test_landing.py # Public landing page tests
โ โโโ selenium/ # Django test client end-to-end user journey suite
โโโ selenium_presentation_suite/ # Standalone Selenium 4 presentation test framework
โ โโโ main.py # Test runner & Tkinter dashboard entry point
โ โโโ dashboard.py # Live Desktop Tkinter PASS/FAIL visual dashboard
โ โโโ test_runner.py # Multi-threaded test runner & report engine
โ โโโ driver_factory.py # Persistent Chrome WebDriver session manager
โ โโโ test_config.py # Selectors, timeouts, and credentials configuration
โ โโโ tests/ # 16 full-lifecycle tests + 3 controlled negative demos
โโโ .github/
โ โโโ assets/ # Visual branding, animated demo GIFs & architecture infographics
โ โโโ workflows/ci.yml # Multi-stage CI pipeline (Ruff, pip-audit, Docker, Postgres, Coverage)
โโโ docs/ # Architectural specifications, brand system, and deployment runbooks
โ โโโ ARCHITECTURE.md # Cryptographic design, wire format, and in-memory streaming
โ โโโ BRANDING.md # Visual identity catalog, design tokens, and color system
โ โโโ DEPLOY_PYTHONANYWHERE.md # Production deployment guide for PythonAnywhere
โ โโโ DEPLOYMENT.md # Multi-host deployment options (Docker, Render, Fly.io)
โโโ Dockerfile # Multi-stage production container image with unprivileged appuser
โโโ manage.py # Django CLI management entry point
- Python: 3.11 or 3.12
- Git
- pip and virtualenv
git clone https://github.com/alinawazcode/passli.git
cd passli# Windows (PowerShell)
python -m venv .venv
.\.venv\Scripts\Activate.ps1
# Linux / macOS
python3 -m venv .venv
source .venv/bin/activate# Production dependencies
pip install -r requirements.txt
# For local development and testing
pip install -r requirements-dev.txt# Copy sample environment configuration
cp .env.example .envKey .env configuration options:
DEBUG=False
SECRET_KEY=replace-with-a-secure-random-key-in-production
# Vault Master Encryption Key (32-byte hex string)
# Optional in development (derived automatically from SECRET_KEY via HKDF-SHA256 if unset)
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
VAULT_MASTER_KEY=
# Cryptographic Key Rotation (Optional)
VAULT_MASTER_KEY_PREVIOUS=
VAULT_KEY_VERSION=1
# Reverse Proxy Trusted Hop Count (Default: 1)
TRUSTED_PROXY_COUNT=1
# Initial Superadmin Configuration (for ensure_superadmin command)
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_PASSWORD=replace-with-a-strong-admin-password
DJANGO_SUPERUSER_EMAIL=admin@passli.dev
# Optional Secondary Superadmin Configuration (for co-author / co-maintainer)
DJANGO_SECONDARY_SUPERUSER_USERNAME=
DJANGO_SECONDARY_SUPERUSER_PASSWORD=
DJANGO_SECONDARY_SUPERUSER_EMAIL=
# Host & Origin Whitelisting
ALLOWED_HOSTS=localhost,127.0.0.1,yourusername.pythonanywhere.com
CSRF_TRUSTED_ORIGINS=https://yourusername.pythonanywhere.com
APP_URL=https://yourusername.pythonanywhere.com
# Gmail SMTP Email Integration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=your-email@gmail.com
SMTP_PASS=replace-with-your-16-char-google-app-password
EMAIL_FROM=your-email@gmail.compython manage.py migrate
python manage.py ensure_superadmin
python manage.py collectstatic --no-inputpython manage.py runserverNavigate to http://localhost:8000/ in your browser.
Passli includes specialized Django management commands for operational administration:
| Command | Description | Example Usage |
|---|---|---|
encrypt_vault_storage |
Migrates unencrypted legacy files to AES-256-GCM authenticated ciphertext at rest, or re-encrypts existing files to bind UUID AAD and rotate keys. | python manage.py encrypt_vault_storage --dry-runpython manage.py encrypt_vault_storage --batch-size 100python manage.py encrypt_vault_storage --reencrypt-legacypython manage.py encrypt_vault_storage --force |
test_smtp |
Diagnoses SMTP credentials, connection negotiation, SSL/TLS, and dispatches a test message. | python manage.py test_smtp recipient@example.com |
ensure_superadmin |
Idempotently creates or updates system superadmin accounts from environment variables without password resets. | python manage.py ensure_superadmin |
Passli enforces strict automated test verification across all platform features.
# Run the complete unit test suite
python manage.py test tests.unit
# Run dedicated vault encryption tests (crypto, AAD, tamper, streaming, migration)
python manage.py test tests.unit.test_vault_encryption
# Run lockout and rate-limiting tests
python manage.py test tests.unit.test_recipient_lockout
# Run email integration tests (OTP verification, password reset, security alerts)
python manage.py test tests.unit.test_email_integration
# Run specific domain test suites
python manage.py test tests.unit.test_documents
python manage.py test tests.unit.test_sharing
python manage.py test tests.unit.test_recipient_portal
python manage.py test tests.unit.test_security
python manage.py test tests.selenium
# Execute full test suite with code coverage analysis
coverage run --source=accounts,audit,config,documents,sharing manage.py test tests.unit tests.selenium
coverage report --fail-under=80Passli includes an interactive desktop presentation testing suite (selenium_presentation_suite/) with a thread-safe Tkinter dashboard engineered for live university and evaluator demonstrations:
# Launch the live desktop Tkinter testing dashboard (browser stays open continuously):
python selenium_presentation_suite/main.py
# Or execute full 16-test suite directly via CLI with customizable step delays:
python selenium_presentation_suite/main.py --cli --suite full --delay 2.0
# Run after-login authenticated features only:
python selenium_presentation_suite/main.py --cli --suite auth --delay 2.0
# Run an individual test case (e.g. TC13 Vault Documents):
python selenium_presentation_suite/main.py --test TC13 --delay 2.0
# Run in headless mode:
python selenium_presentation_suite/main.py --cli --suite full --headless --close-browserSee selenium_presentation_suite/README.md and selenium_presentation_suite/TEST_CASES.md for full test specifications.
Passli includes an optimized, non-root Dockerfile ready for local containerization:
# Build the Docker image
docker build -t passli .
# Run container with dynamic port binding
docker run -p 8000:8000 -e SECRET_KEY="local-docker-secret-key-12345" -e DEBUG=True passli| URL Path | View Handler | Access Level | Description |
|---|---|---|---|
/ |
landing_view |
Public | Interactive public landing page with simulator |
/register/ |
register_view |
Public | User account registration |
/verify-email/ |
verify_email_view |
Authenticated | 6-digit numeric OTP email verification |
/login/ |
CustomLoginView |
Public | Secure user authentication |
/logout/ |
CustomLogoutView |
Authenticated | CSRF-protected session teardown |
/password-reset/ |
password_reset_request_view |
Public | Password recovery request form |
/password-reset/confirm/<token>/ |
password_reset_confirm_view |
Public | Cryptographic one-time reset token confirm |
/dashboard/ |
dashboard_view |
Authenticated | User vault overview and quick actions |
/documents/ |
documents_list_view |
Authenticated | Filterable encrypted document vault |
/documents/upload/ |
documents_upload_view |
Authenticated | AES-256 upload dropzone and metadata |
/documents/<id>/preview/ |
document_preview_view |
Authenticated | In-memory decrypted preview stream |
/documents/<id>/download/ |
document_download_view |
Authenticated | In-memory decrypted file download |
/documents/<id>/edit/ |
document_edit_view |
Authenticated | Document title/category metadata update |
/documents/<id>/delete/ |
document_delete_view |
Authenticated | Document and encrypted disk file removal |
/share/ |
share_list_view |
Authenticated | Active and expired share passes list |
/share/create/ |
share_create_view |
Authenticated | Ephemeral pass generator with TTL selection |
/share/<uuid>/ |
share_detail_view |
Authenticated | Pass telemetry, QR code display, & key |
/share/<uuid>/revoke/ |
share_revoke_view |
Authenticated | 1-click immediate pass revocation |
/share/<uuid>/qr/download/ |
share_qr_download_view |
Authenticated | Isolated QR code image download |
/p/<uuid>/ |
recipient_verify_view |
Public / Rate-limited | Recipient 8-char Share Key gateway |
/p/<uuid>/portal/ |
recipient_portal_view |
Verified Recipient | Recipient document viewer & countdown timer |
/p/<uuid>/doc/<id>/preview/ |
recipient_doc_preview_view |
Verified Recipient | In-memory decrypted stream for recipient |
/p/<uuid>/doc/<id>/download/ |
recipient_doc_download_view |
Verified Recipient | Decrypted file download (if permitted) |
/p/<uuid>/leave/ |
recipient_leave_view |
Verified Recipient | Recipient session exit & token purge |
/audit/ |
audit_list_view |
Authenticated | Personal cryptographic access audit feed |
/admin-dashboard/ |
admin_dashboard_overview |
Superadmin | Platform governance & storage telemetry |
/admin-dashboard/users/ |
admin_dashboard_users |
Superadmin | User directory & account activation toggles |
/admin-dashboard/documents/ |
admin_dashboard_documents |
Superadmin | Global file repository & SHA-256 digests |
/admin-dashboard/passes/ |
admin_dashboard_passes |
Superadmin | Emergency system-wide pass revocation |
/admin-dashboard/audit/ |
admin_dashboard_audit |
Superadmin | Global security threat feed & lockout monitor |
By default, uploaded encrypted vault files are stored in media/ via Django's file storage (configurable via MEDIA_ROOT).
On containerized hosts with ephemeral local filesystems (Render, Fly.io):
- Persistent Volume: Attach a persistent volume mounted at the configured
MEDIA_ROOTdirectory (/app/media) to ensure documents persist across container restarts. - Standard / VPS Hosts: On PythonAnywhere and traditional VPS instances, disk storage is persistent by default.
- Cloud Object Storage (S3 / Cloudflare R2): In distributed multi-server environments, configure
django-storageswith an S3-compatible backend.
Passli can be deployed across multiple environments including PythonAnywhere, Docker, Render, Fly.io, or standard Linux VPS servers:
- PythonAnywhere Deployment: See the comprehensive step-by-step guide in docs/DEPLOY_PYTHONANYWHERE.md.
- General & Docker Deployment: See docs/DEPLOYMENT.md.
Before running the server, always apply migrations and collect static assets:
python manage.py migrate
python manage.py collectstatic --no-inputTo provision an initial superadministrator account from environment variables, run:
python manage.py ensure_superadminIf your deployment experiences an infinite redirect loop (HTTP 301/302 repeatedly redirecting to HTTPS):
- Set
SECURE_SSL_REDIRECT=Falsein your environment variables. - Verify whether your host or upstream proxy forwards
X-Forwarded-Protowith this one-line curl command:If the upstream proxy does not sendcurl -s -D - https://<your-domain> -o /dev/null | grep -iE "location|http"
X-Forwarded-Proto: https, Django will believe the incoming request is insecure and continuously redirect. KeepSECURE_SSL_REDIRECT=Falseuntil the proxy is properly configured.
Passli is designed with full architectural transparency:
- Server Holds the Master Key: Document encryption and decryption occur server-side. Anyone with access to the host environment variables (
VAULT_MASTER_KEY) can decrypt stored vault records. - Not Zero-Knowledge: Passli uses server-side AES-256-GCM authenticated encryption. There is no client-side encryption.
- Server-Enforced Access: Pass expiry and revocation are enforced by application business logic and authentication controls rather than hardware-based cryptographic self-destruction.
- No Independent Security Audit: Passli is an independent open-source project and has not undergone third-party cryptographic audits or SOC 2 certification.
- Free-Hosting Constraints: When deployed on free tiers like PythonAnywhere Beginner, storage is limited (512 MB total for code, db, and files), outbound traffic is restricted to whitelisted destinations (Gmail SMTP), and web applications require periodic manual confirmation in the dashboard.
Security and cryptographic isolation are core to Passli. For vulnerability disclosure guidelines, threat models, and cryptographic parameters, please refer to SECURITY.md or contact alinawaz.code@gmail.com.
Contributions, bug reports, and feature proposals are welcome! Please read CONTRIBUTING.md and our CODE_OF_CONDUCT.md before opening a pull request.
For project inquiries, partnerships, enterprise deployments, or general questions, connect with the project maintainers:
- Ali Nawaz โ Lead Architecture & Backend Engineering โข @alinawazcode
- Muqadas Fareed โ Co-Author & Project Maintainer โข @Muqadas-Fareed-devt
- Email Contact: alinawaz.code@gmail.com
This project is open-source and licensed under the MIT License.