certauth/SKILL.md

245 lines
7.1 KiB
Markdown

# 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.