From 0aa31c526bb9061471c01712e0c5c1bdb26717fb Mon Sep 17 00:00:00 2001 From: Username Date: Thu, 25 Dec 2025 00:28:33 +0100 Subject: [PATCH] docs: add PKI usage guide with examples --- TASKLIST.md | 7 +- documentation/pki.md | 186 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+), 6 deletions(-) create mode 100644 documentation/pki.md diff --git a/TASKLIST.md b/TASKLIST.md index ee87c34..ab9be9e 100644 --- a/TASKLIST.md +++ b/TASKLIST.md @@ -11,16 +11,11 @@ Prioritized, actionable tasks. Each task is small and completable in one session | ☐ | Create Ansible deployment role | ☐ | Add Kubernetes manifests (Deployment, Service, ConfigMap) -## Priority 4: Documentation - -| Status | Task -|--------|-------------------------------------------------------------- -| ☐ | Add PKI usage examples to documentation - ## Completed | Date | Task |------------|-------------------------------------------------------------- +| 2024-12 | Add PKI usage examples (documentation/pki.md) | 2024-12 | Create CONTRIBUTING.md with development setup | 2024-12 | Fix all mypy type errors (now enforced in CI) | 2024-12 | Enhance CI with security-tests job, SBOM generation, memory checks diff --git a/documentation/pki.md b/documentation/pki.md new file mode 100644 index 0000000..e09a967 --- /dev/null +++ b/documentation/pki.md @@ -0,0 +1,186 @@ +# 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 +./fpaste config server https://paste.example.com + +# Register (requires PKI password if set on server) +./fpaste register --configure + +# Creates ~/.config/fpaste/{client.key, client.crt} 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 +# Set PKI password (required for certificate operations) +export FLASKPASTE_PKI_PASSWORD="your-secure-password" + +# Optional: enable public registration +export FLASKPASTE_REGISTRATION_ENABLED=true + +# 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 Status + CA initialized: yes + CA fingerprint: a1b2c3d4e5f6... + CA expires: 2034-12-25 + Issued certs: 5 + Revoked: 1 +``` + +### 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 (Admin) + +```bash +./fpaste pki status # Get serial number +./fpaste 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 PKI password securely (environment variable, secrets manager) +- Protect CA private key (encrypted with AES-256-GCM) +- Use strong proxy secret for header trust validation +- Revoke compromised certificates promptly +- Monitor audit logs for AUTH_FAILURE events + +## 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