# CertAuth Key Vault - API & Web UI Guide ## Overview CertAuth is a self-contained Certificate Authority running on `192.168.8.248` (accessible as `certauth.ms` on the local network). It uses two YubiKey 5 Nano devices as hardware security modules — one for the Root CA and one for the Intermediate CA — requiring physical touch + PIN to sign certificates. ## Authentication Two auth methods are supported: ### JWT Token (API) ```bash # Login curl -X POST https://certauth.ms/api/token \ -H "Content-Type: application/json" \ -d '{"username":"certauth","password":"CHANGE_ME_ADMIN_PASS"}' # Response: {"access_token": "eyJ...", "token_type": "bearer"} # Use token in subsequent requests curl -H "Authorization: Bearer $TOKEN" https://certauth.ms/api/domains ``` ### Cookie Auth (Web UI / curl) ```bash # Login via web endpoint (sets cookie) curl -c cookies.txt -L https://certauth.ms/login \ -d "username=certauth&password=CHANGE_ME_ADMIN_PASS" # Use cookie in subsequent requests curl -b cookies.txt https://certauth.ms/api/domains/web ``` Or use `-b "token=$TOKEN"` with the token value for cookie-auth endpoints. ## Admin Credentials - **Username**: `certauth` - **Password**: `CHANGE_ME_ADMIN_PASS` - **PFX download password**: `certauth` ## API Endpoints All endpoints require authentication. The server is at `https://certauth.ms`. ### Health Check ```bash curl -k https://certauth.ms/api/health # → {"status":"ok"} ``` ### CA Chain Download ```bash curl -k https://certauth.ms/api/ca-chain -o ca-chain.crt ``` Returns the Intermediate + Root CA chain in PEM format. --- ### Domains **List domains:** ```bash curl -H "Authorization: Bearer $TOKEN" https://certauth.ms/api/domains ``` **Register domain (API):** ```bash curl -X POST https://certauth.ms/api/domains \ -H "Authorization: Bearer $TOKEN" \ -d "name=example.com&description=My+website" ``` **Register domain (web/cookie auth):** ```bash curl -b cookies.txt -X POST https://certauth.ms/api/domains/web \ -d "name=example.com&description=My+website" ``` --- ### Certificates **List certificates:** ```bash curl -H "Authorization: Bearer $TOKEN" https://certauth.ms/api/certs ``` **Request certificate (API):** ```bash curl -X POST https://certauth.ms/api/certs/request \ -H "Authorization: Bearer $TOKEN" \ -d "cn=example.com&sans=example.com%2Cwww.example.com&days=365&domain_id=1" ``` **Request certificate (web/cookie auth):** ```bash curl -b cookies.txt -X POST https://certauth.ms/api/certs/web/request \ -d "cn=example.com&sans=example.com%2Cwww.example.com&days=365&domain_id=0" ``` Parameters: - `cn` — Common Name (required) - `sans` — Comma-separated Subject Alternative Names (URL-encoded) - `days` — Validity in days (default: 365) - `domain_id` — Domain ID to link to (0 = auto-match by CN) **Sign/Issue certificate:** ```bash curl -X POST https://certauth.ms/api/certs/{cert_id}/sign \ -H "Authorization: Bearer $TOKEN" ``` **Sign/Issue certificate (web/cookie auth):** ```bash curl -b cookies.txt -X POST https://certauth.ms/api/certs/{cert_id}/sign/web ``` ⚠️ **Signing requires physical YubiKey touch + PIN** — this will block until the operator touches YubiKey 2 and enters the PIN. **Download PEM (cert + chain):** ```bash curl -b cookies.txt https://certauth.ms/api/certs/{cert_id}/pem -o cert.pem ``` **Download PFX (cert + key + chain, password: `certauth`):** ```bash curl -b cookies.txt https://certauth.ms/api/certs/{cert_id}/pfx -o cert.pfx ``` --- ### History **View certificate history:** ```bash curl -b cookies.txt https://certauth.ms/history ``` --- ### Setup Scripts **Bash installer (Linux/macOS):** ```bash curl -sL https://certauth.ms/setup.sh | sudo bash -s 192.168.8.248 ``` **PowerShell installer (Windows):** ```powershell iwr https://certauth.ms/setup.ps1 -UseBasicParsing | iex ``` ## Complete Workflow Example Here's a full end-to-end example to register a domain, request a cert, issue it, and download: ```bash # 1. Login and get token TOKEN=$(curl -s -X POST https://certauth.ms/api/token \ -H "Content-Type: application/json" \ -d '{"username":"certauth","password":"CHANGE_ME_ADMIN_PASS"}' \ | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])") # 2. Register domain curl -s -X POST https://certauth.ms/api/domains \ -H "Authorization: Bearer $TOKEN" \ -d "name=myapp.local&description=Internal+app" # 3. Request certificate CERT_ID=$(curl -s -X POST https://certauth.ms/api/certs/request \ -H "Authorization: Bearer $TOKEN" \ -d "cn=myapp.local&sans=myapp.local%2Cwww.myapp.local&days=365&domain_id=0" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") echo "Certificate ID: $CERT_ID" # 4. Issue certificate (requires YubiKey touch!) curl -s -X POST https://certauth.ms/api/certs/$CERT_ID/sign \ -H "Authorization: Bearer $TOKEN" # 5. Download PEM (cert + intermediate + root) curl -s -H "Authorization: Bearer $TOKEN" \ https://certauth.ms/api/certs/$CERT_ID/pem -o myapp.pem # 6. Download PFX (cert + key + chain, password: certauth) curl -s -H "Authorization: Bearer $TOKEN" \ https://certauth.ms/api/certs/$CERT_ID/pfx -o myapp.pfx # 7. Verify openssl verify -CAfile ca-chain.crt myapp.pem ``` ## Certificate Details - **Key type**: EC P-384 (SECP384R1) - **Signature algorithm**: ECDSA-SHA384 - **CA chain**: Intermediate CA (YubiKey 2) → Root CA (YubiKey 1) - **Extensions**: Server Auth + Client Auth EKU, proper AKI/SKI - **Validity**: 365 days per leaf cert (configurable) - **PFX password**: `certauth` ## Installing CA Chain on Clients The `setup.sh` endpoint serves a self-installing bash script that: 1. Auto-detects the server IP (or prompts) 2. Downloads the CA chain 3. Installs it to the OS trust store 4. Supports: Debian/Ubuntu, RHEL/CentOS/Fedora, Arch, Alpine, macOS For macOS specifically, the CA is installed to the System Keychain with `security add-trusted-cert`. For LibreWolf (which disables enterprise roots by default): - Set `security.enterprise_roots.enabled = true` in `about:config` - OR import the root CA via `certutil` into LibreWolf's NSS database ## Key Files on Server | Path | Description | |------|-------------| | `/etc/ssl/ca/root/root-ca.crt` | Root CA certificate | | `/etc/ssl/ca/intermediate/intermediate-ca.crt` | Intermediate CA certificate | | `/etc/ssl/ca/ca-chain.crt` | Full chain (intermediate + root) | | `/etc/ssl/ca/issued/` | Issued leaf certificates and keys | | `/etc/ssl/certauth/tls.pem` | Server cert + chain (for Caddy) | | `/etc/ssl/certauth/tls.key` | Server private key | | `/opt/certauth/api/` | API application files | | `/var/lib/certauth/certauth.db` | SQLite database | ## DNS - `certauth.ms` → `192.168.8.248` (served by dnsmasq on the server) - Also added to router DNS for network-wide resolution ## Troubleshooting - **SSL_ERROR_BAD_CERT_DOMAIN**: Make sure you're using `https://certauth.ms` not the IP. Firefox/NSS has quirks with IP Address SANs. - **SEC_ERROR_UNKNOWN_ISSUER**: The CA chain isn't trusted. Install via `setup.sh` or import manually. - **Signing fails**: YubiKey 2 must be touched and PIN entered when signing. - **DNS not resolving**: Check that `certauth.ms` is in your router's DNS or AdGuard Home config.