# PKI Guide FlaskPaste includes a built-in Public Key Infrastructure (PKI) for client certificate authentication. ## Overview The PKI system provides: - Self-contained Certificate Authority (CA) - Client certificate issuance - Certificate revocation - mTLS authentication via reverse proxy ## Quick Start with CLI ### 1. Register and Get a Certificate ```bash # Download CLI curl -o fpaste https://paste.example.com/client && chmod +x fpaste # Configure server (environment or config file) export FLASKPASTE_SERVER="https://paste.example.com" # Or: echo "server = https://paste.example.com" >> ~/.config/fpaste/config # Register and auto-configure ./fpaste register --configure # Creates ~/.config/fpaste/{client.key, client.crt, client.p12} and updates config ``` ### 2. Use Authenticated Requests ```bash # Create paste (now authenticated) echo "secret data" | ./fpaste create # List your pastes ./fpaste list # Delete a paste ./fpaste delete ``` ## Server Setup ### Enable PKI ```bash # Enable PKI and set CA password (required for certificate operations) export FLASKPASTE_PKI_ENABLED=1 export FLASKPASTE_PKI_CA_PASSWORD="your-secure-password" # Optional: set certificate validity period (default: 365 days) export FLASKPASTE_PKI_CERT_DAYS=365 # Start server python run.py ``` ### Initialize CA The CA is auto-generated on first certificate request, or manually: ```bash curl -X POST https://paste.example.com/pki/ca \ -H "Content-Type: application/json" \ -d '{"common_name": "My Paste CA"}' ``` ## CLI Certificate Management ### Check PKI Status ```bash ./fpaste pki status ``` Output: ``` pki enabled: True ca exists: True common name: FlaskPaste CA fingerprint: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 created: 2024-12-25T10:30:00Z expires: 2034-12-25T10:30:00Z download: https://paste.example.com/pki/ca.crt ``` ### Download CA Certificate ```bash # Save and configure ./fpaste pki download -o ~/.config/fpaste/ca.crt --configure # Or just view ./fpaste pki download ``` ### Issue Certificate (Admin) ```bash # Requires admin privileges (first registered user) ./fpaste pki issue -n "alice" -o ./alice-certs/ --configure ``` ### Revoke Certificate (API) Certificate revocation is done via the API: ```bash # Get certificate serial from /pki/certs curl -H "X-SSL-Client-SHA1: " https://paste.example.com/pki/certs # Revoke by serial number curl -X POST -H "X-SSL-Client-SHA1: " \ https://paste.example.com/pki/revoke/ ``` ## Self-Signed Certificate (Offline) Generate a certificate without server interaction: ```bash ./fpaste cert -o ~/.config/fpaste/ --configure # With custom options ./fpaste cert -n "my-client" -a ec -c secp384r1 -d 365 ``` ## Reverse Proxy Configuration ### nginx with mTLS ```nginx server { listen 443 ssl; server_name paste.example.com; # Server certificate ssl_certificate /etc/ssl/certs/paste.example.com.crt; ssl_certificate_key /etc/ssl/private/paste.example.com.key; # Client certificate verification ssl_client_certificate /etc/ssl/certs/flaskpaste-ca.crt; ssl_verify_client optional; location / { proxy_pass http://127.0.0.1:5000; proxy_set_header X-SSL-Client-SHA1 $ssl_client_fingerprint; proxy_set_header X-Proxy-Secret "your-shared-secret"; } } ``` ### HAProxy with mTLS ```haproxy frontend https bind *:443 ssl crt /etc/ssl/paste.pem ca-file /etc/ssl/flaskpaste-ca.crt verify optional http-request set-header X-SSL-Client-SHA1 %{+Q}[ssl_c_sha1] http-request set-header X-Proxy-Secret your-shared-secret default_backend flaskpaste backend flaskpaste server app 127.0.0.1:5000 ``` ## Trust Levels | Level | Source | Expiry | Limits | |-------|--------|--------|--------| | Anonymous | No auth | 1 day | 3 MiB | | Untrusted | Self-signed cert | 7 days | 50 MiB | | Trusted | PKI-issued cert | 30 days | 50 MiB | | Admin | First PKI user | 30 days | 50 MiB + admin ops | ## Security Considerations - Store `FLASKPASTE_PKI_CA_PASSWORD` securely (environment variable, secrets manager) - CA private key is encrypted with AES-256-GCM using the password - Use strong `FLASKPASTE_PROXY_SECRET` for header trust validation - Revoke compromised certificates promptly via the API - Monitor audit logs for `AUTH_FAILURE` events (revoked/expired certificates) ## API Reference See [api.md](api.md) for detailed PKI endpoint documentation: - `GET /pki` - PKI status - `POST /pki/ca` - Generate CA - `GET /pki/ca.crt` - Download CA certificate - `POST /pki/issue` - Issue client certificate - `GET /pki/certs` - List issued certificates - `POST /pki/revoke/{serial}` - Revoke certificate - `GET /register/challenge` - Get registration PoW challenge - `POST /register` - Register for certificate