From 3eb4749b4d6ab7a941d6ee2a1f92d0c67292ac4e Mon Sep 17 00:00:00 2001 From: shankar0123 Date: Wed, 25 Mar 2026 04:09:03 -0400 Subject: [PATCH] docs: merge quickstart and demo guide into single quickstart.md Consolidated two overlapping docs into one cohesive guide framed around the 47-day certificate lifespan reduction. Covers setup, dashboard walkthrough, API exploration, cert creation, discovery, CLI, MCP, demo data reference, and a 10-step stakeholder presentation flow. Removed demo-guide.md and updated all cross-references in README, compliance-pci-dss.md, and testing-guide.md. Co-Authored-By: Claude Opus 4.6 --- README.md | 3 +- docs/compliance-pci-dss.md | 2 +- docs/demo-guide.md | 253 ---------------------- docs/quickstart.md | 427 +++++++++++++++++-------------------- docs/testing-guide.md | 2 +- 5 files changed, 204 insertions(+), 483 deletions(-) delete mode 100644 docs/demo-guide.md diff --git a/README.md b/README.md index 653cf5f..24fa0d3 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,7 @@ certctl is a self-hosted platform that automates the entire certificate lifecycl | Guide | Description | |-------|-------------| | [Concepts](docs/concepts.md) | TLS certificates explained from scratch — for beginners who know nothing about certs | -| [Quick Start](docs/quickstart.md) | Get running in 5 minutes with accurate API examples | -| [Demo Walkthrough](docs/demo-guide.md) | 5-7 minute guided stakeholder presentation | +| [Quick Start](docs/quickstart.md) | Get running in 5 minutes — dashboard, API, CLI, discovery, stakeholder demo flow | | [Advanced Demo](docs/demo-advanced.md) | Issue a certificate end-to-end with technical deep-dives | | [Architecture](docs/architecture.md) | System design, data flow diagrams, security model | | [Connectors](docs/connectors.md) | Build custom issuer, target, and notifier connectors | diff --git a/docs/compliance-pci-dss.md b/docs/compliance-pci-dss.md index 143af6b..00eadb6 100644 --- a/docs/compliance-pci-dss.md +++ b/docs/compliance-pci-dss.md @@ -785,7 +785,7 @@ Certctl v3 (Pro) adds paid features that strengthen PCI-DSS compliance posture: For additional guidance on certctl features and PCI-DSS mapping: - Review the [Architecture Guide](architecture.md) for system design. - Check [Connectors Documentation](connectors.md) for issuer/target/notifier capabilities. -- Run the [Demo Guide](demo-guide.md) to see features in action. +- Run the [Quick Start Guide](quickstart.md) to see features in action. - Consult your QSA for final compliance determination. **Last Updated**: March 24, 2026 (certctl v1.0 with M18b discovery and M19 audit logging) diff --git a/docs/demo-guide.md b/docs/demo-guide.md deleted file mode 100644 index f619343..0000000 --- a/docs/demo-guide.md +++ /dev/null @@ -1,253 +0,0 @@ -# certctl Demo Guide - -A 5-10 minute guided walkthrough of certctl's dashboard and API. Perfect for stakeholder presentations and team demos. - -New to certificates? Read the [Concepts Guide](concepts.md) first. Want a hands-on demo where you issue certificates yourself? See the [Advanced Demo](demo-advanced.md). - -## Quick Start - -```bash -git clone https://github.com/shankar0123/certctl.git -cd certctl -docker compose -f deploy/docker-compose.yml up -d --build -``` - -Wait ~30 seconds for PostgreSQL to initialize and the server to start, then open: - -**http://localhost:8443** - -You'll see the dashboard pre-loaded with 15 demo certificates across multiple teams, environments, and statuses — including expiring, expired, active, failed, wildcard, and in-progress renewals. - -## What You'll See - -### Dashboard Overview -The main dashboard shows at a glance: -- **Total certificates** managed across your infrastructure -- **Expiring soon** — certificates within 30 days of expiration (yellow/red) -- **Expired** — certificates past their expiration date -- **Active** — healthy certificates with time remaining -- **Renewal success rate** — percentage of automated renewals that succeeded - -Below the stats, interactive charts provide deeper visibility: an **expiration heatmap** (90-day weekly buckets), **renewal success rate trends** (30-day line chart), **certificate status distribution** (donut chart), and **issuance rate** (30-day bar chart). - -### Certificates View -Click "Certificates" in the sidebar to see the full inventory: -- Search by name or domain -- Filter by status (Active, Expiring, Expired, Failed) or environment (Production, Staging) -- Sort by any column -- Click any row to see full details: metadata, version history, deployment targets, and audit trail - -### Demo Scenarios to Walk Through - -**1. "We're about to have an outage"** -Filter by status → Expiring. You'll see `auth-production` (12 days), `cdn-production` (8 days), and `mail-production` (5 days). These are real alerts the platform would catch automatically. - -**2. "A renewal failed"** -Look at `vpn-production` — status: Failed. Click it to see the audit trail showing the ACME challenge failure after 3 retry attempts. The system sent a webhook notification to the ops channel. - -**3. "Who owns this cert?"** -Click any certificate to see the owner, team, environment, and tags. Every cert has clear accountability. - -**4. "What happened to the legacy app?"** -Filter by status → Expired. `legacy-app` expired 3 days ago, `old-api-v1` expired 15 days ago. Both have policy violations flagged. - -**5. "Show me the agent fleet"** -Click "Agents" in the sidebar. Four agents are online, one (`iis-prod-agent`) went offline 3 hours ago — you'd want to investigate that. - -**6. "What policies are enforced?"** -Click "Policies" to see the active rules: required owner metadata, allowed environments, max certificate lifetime, minimum renewal window. Check the violations list to see which certs are non-compliant. - -**7. "Can I revoke a compromised cert?"** -Click any active certificate, then click the "Revoke" button. A modal appears with RFC 5280 reason codes (Key Compromise, Superseded, Cessation of Operation, etc.). After revocation, the cert shows a revocation banner with the reason and timestamp. - -**8. "Show me short-lived credentials"** -Click "Short-Lived" in the sidebar. This view shows certificates with TTL under 1 hour — live countdown timers, auto-refresh every 10 seconds, and profile-based filtering. These are for service-to-service auth where rapid expiry replaces revocation. - -**9. "What about bulk operations?"** -On the Certificates page, select multiple certificates using the checkboxes. A bulk action bar appears with options to trigger renewal, revoke (with reason codes), or reassign ownership — all with progress tracking. - -**10. "How do I see the deployment history?"** -Click any certificate, then scroll to the deployment timeline. A visual 4-step timeline shows the lifecycle: Requested → Issued → Deploying → Active. Previous versions show a rollback button. - -**11. "What about certificates already running in production?"** -Enable discovery on agents by setting `CERTCTL_DISCOVERY_DIRS` to directories containing certificates (e.g., `/etc/nginx/certs`). Agents scan on startup and every 6 hours, report findings to the control plane. For network-based discovery without agents, enable `CERTCTL_NETWORK_SCAN_ENABLED=true` and configure scan targets via the API — the server probes TLS endpoints on configured CIDR ranges and ports. Click "Discovered Certificates" to see what agents and network scans found — claim unmanaged certs to bring them under certctl's management, or dismiss them. - -## REST API Walkthrough - -The dashboard is backed by a real REST API (91 endpoints). Try these while the demo is running: - -```bash -# List all certificates -curl -s http://localhost:8443/api/v1/certificates | jq . - -# Get expiring certs -curl -s "http://localhost:8443/api/v1/certificates?status=expiring" | jq . - -# Advanced query: sort by expiration, sparse fields, cursor pagination -curl -s "http://localhost:8443/api/v1/certificates?sort=-expires_at&fields=id,common_name,expires_at" | jq . - -# Time-range filter: certs expiring before June 2026 -curl -s "http://localhost:8443/api/v1/certificates?expires_before=2026-06-01T00:00:00Z" | jq . - -# Get a specific certificate -curl -s http://localhost:8443/api/v1/certificates/mc-api-prod | jq . - -# Get deployment targets for a certificate -curl -s http://localhost:8443/api/v1/certificates/mc-api-prod/deployments | jq . - -# List agents -curl -s http://localhost:8443/api/v1/agents | jq . - -# View audit trail (immutable API audit log of all actions) -curl -s http://localhost:8443/api/v1/audit | jq . - -# View policy violations (replace POLICY_ID with a real policy ID, e.g. pr-require-owner) -curl -s http://localhost:8443/api/v1/policies/pr-require-owner/violations | jq . - -# Check system health -curl -s http://localhost:8443/health | jq . - -# Dashboard stats and metrics -curl -s http://localhost:8443/api/v1/stats/summary | jq . -curl -s http://localhost:8443/api/v1/stats/certificates-by-status | jq . -curl -s http://localhost:8443/api/v1/stats/expiration-timeline | jq . -curl -s http://localhost:8443/api/v1/stats/job-trends | jq . -curl -s http://localhost:8443/api/v1/stats/issuance-rate | jq . -curl -s http://localhost:8443/api/v1/metrics | jq . -curl -s http://localhost:8443/api/v1/metrics/prometheus # Prometheus format - -# Certificate profiles -curl -s http://localhost:8443/api/v1/profiles | jq . - -# Agent groups -curl -s http://localhost:8443/api/v1/agent-groups | jq . - -# Revoke a certificate -curl -s -X POST http://localhost:8443/api/v1/certificates/mc-api-prod/revoke \ - -H "Content-Type: application/json" \ - -d '{"reason": "superseded"}' | jq . - -# CRL and OCSP endpoints -curl -s http://localhost:8443/api/v1/crl | jq . -curl -s http://localhost:8443/api/v1/crl/iss-local -o /tmp/crl.der - -# List discovered certificates -curl -s http://localhost:8443/api/v1/discovered-certificates | jq . - -# Discovery summary (counts by status) -curl -s http://localhost:8443/api/v1/discovery-summary | jq . - -# Network scan targets (active TLS scanning) -curl -s http://localhost:8443/api/v1/network-scan-targets | jq . -``` - -## CLI Tool - -certctl ships with a command-line tool (`certctl-cli`) for terminal users: - -```bash -# Build the CLI -cd cmd/cli && go build -o certctl-cli . - -# Set credentials -export CERTCTL_SERVER_URL="http://localhost:8443" -export CERTCTL_API_KEY="test-key-123" - -# List certificates (JSON or table format) -./certctl-cli --format json certs list -./certctl-cli certs list - -# Get certificate details -./certctl-cli certs get mc-api-prod - -# Trigger renewal -./certctl-cli certs renew mc-api-prod - -# Revoke a certificate (with RFC 5280 reason) -./certctl-cli certs revoke mc-api-prod --reason keyCompromise - -# List agents -./certctl-cli agents list - -# List pending jobs -./certctl-cli jobs list - -# Bulk import certificates from PEM files -./certctl-cli import /path/to/certs.pem - -# Check system health and stats -./certctl-cli status -``` - -## MCP Server for AI Integration - -certctl exposes its 78 API endpoints as tools via the Model Context Protocol (MCP), enabling integration with Claude, Cursor, and other AI assistants: - -```bash -# Build and run the MCP server -cd cmd/mcp-server && go build -o mcp-server . - -export CERTCTL_SERVER_URL="http://localhost:8443" -export CERTCTL_API_KEY="test-key-123" - -./mcp-server -``` - -The MCP server: -- Exposes all 78 API endpoints as MCP tools with typed schemas -- Handles binary responses (DER CRL, OCSP responses) -- Uses stdio transport for Claude/Cursor/OpenClaw integration -- Zero external dependencies — pure Go with official MCP SDK - -You can then ask Claude questions like: -- "What certificates are expiring in the next 30 days?" -- "Revoke the payments certificate due to key compromise" -- "Show me the audit trail for the last 10 actions" -- "List all certificates with PCI compliance tags" - -## Dashboard Demo Mode - -The dashboard includes a **Demo Mode** that works without any backend. Build and serve the frontend with Vite: - -```bash -cd web -npm install -npm run dev -# Dashboard available at http://localhost:5173 -``` - -When the API is unreachable, the dashboard automatically loads realistic mock data and shows a subtle "Demo Mode" badge. This is perfect for screenshots, presentations, or quick demos without any infrastructure. - -## Teardown - -```bash -docker compose -f deploy/docker-compose.yml down -v -``` - -The `-v` flag removes the PostgreSQL data volume so you get a clean slate next time. - -## Presenting to Stakeholders - -If you're demoing to a team or customer, here's a suggested flow: - -1. **Start with the dashboard** — "This is your certificate inventory at a glance, with real-time charts showing expiration trends and renewal health" -2. **Show the expiring certs** — "These three would have caused outages without this platform" -3. **Click into auth-production** — "Here's the full lifecycle: who owns it, where it's deployed, deployment timeline, when it was last renewed" -4. **Show revocation** — "If a key is compromised, one click revokes the cert with an RFC 5280 reason code. CRL and OCSP are served automatically" -5. **Show the failed VPN cert** — "The system tried 3 times, then alerted the team via Slack, Teams, PagerDuty, or OpsGenie" -6. **Show agents and fleet overview** — "Agents run on your infrastructure, handle key generation locally (ECDSA P-256). Fleet view shows OS, architecture, and version distribution" -7. **Show profiles** — "Certificate profiles enforce crypto constraints — key types, max TTL, compliance requirements" -8. **Show policies** — "Guardrails prevent teams from going outside approved scope" -9. **Show bulk operations** — "Select multiple certs, trigger renewal or revoke in bulk with progress tracking" -10. **Show certificate discovery** — "We discover certificates two ways: agents scan local filesystems, and the server actively probes TLS endpoints on your network. We deduplicate by fingerprint, show you what we found, and let you claim them or dismiss them" -11. **Show the immutable audit trail** — "Every action in the system is recorded: who did it, what they did, when, what changed. Export to CSV/JSON for compliance" -12. **Show advanced query features** — "Sort by any field, filter by date range, paginate efficiently with cursor-based pagination, select just the fields you need" -13. **Show the CLI and MCP server** — "Terminal users get `certctl-cli` with 12 subcommands. AI assistants get MCP integration with 78 tools. Everything is API-first" - -The whole walkthrough takes 5-10 minutes. - -## Next Steps - -- **[Advanced Demo](demo-advanced.md)** — Go hands-on: create a team, issue a certificate via API, trigger renewal, and watch it appear in the dashboard -- **[Concepts Guide](concepts.md)** — Understand TLS certificates, CAs, and private keys from scratch -- **[Architecture](architecture.md)** — Deep dive into the control plane, agent model, and connector architecture diff --git a/docs/quickstart.md b/docs/quickstart.md index 9a2dca8..fc1e551 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,6 +1,8 @@ # Quick Start Guide -Get certctl running locally and managing certificates in under 5 minutes. With TLS certificate lifespans dropping to 47 days by 2029, automated lifecycle management isn't optional — it's infrastructure. This guide gets you hands-on with certctl's automation loop: tracking, renewing, and deploying certificates without manual intervention. +Certificate lifespans are dropping to **47 days by 2029**. At that cadence, a team managing 100 certificates is processing 7+ renewals per week — every week, forever. Manual processes break. certctl automates the entire lifecycle: issuance, renewal, deployment, revocation, and audit — with zero human intervention. + +This guide gets you running in 5 minutes and walks you through everything certctl does. New to certificates? Read the [Concepts Guide](concepts.md) first — it explains TLS, CAs, and private keys in plain language. @@ -23,7 +25,7 @@ cd certctl docker compose -f deploy/docker-compose.yml up -d --build ``` -The `--build` flag is important — it builds the server image including the React frontend. Without it, Docker may use a stale cached image that doesn't include the dashboard. +The `--build` flag builds the server image including the React frontend. Without it, Docker may use a stale cached image. **For production deployments**, copy `deploy/.env.example` to `deploy/.env` and customize the credentials: ```bash @@ -32,7 +34,7 @@ cp deploy/.env.example deploy/.env docker compose -f deploy/docker-compose.yml up -d --build ``` -Wait about 30 seconds for PostgreSQL to initialize and the server to boot. Check that everything is healthy: +Wait about 30 seconds for PostgreSQL to initialize, then verify: ```bash docker compose -f deploy/docker-compose.yml ps @@ -46,7 +48,6 @@ certctl-server Up (healthy) certctl-agent Up ``` -Verify the server responds: ```bash curl http://localhost:8443/health ``` @@ -58,98 +59,123 @@ curl http://localhost:8443/health Open **http://localhost:8443** in your browser. -The dashboard comes pre-loaded with 15 demo certificates across multiple teams, environments, and statuses. You'll see expiring certs, expired certs, active certs, failed renewals — a realistic snapshot of what a certificate inventory looks like in a real organization. +The dashboard comes pre-loaded with 15 demo certificates across multiple teams, environments, and statuses — expiring certs, expired certs, active certs, failed renewals. A realistic snapshot of what certificate management looks like in a real organization. -Explore the sidebar: Certificates, Agents, Policies, Jobs, Audit Trail, Notifications. Everything you see in the dashboard is backed by the REST API. +### What you're looking at + +The main dashboard shows total certificates, how many are expiring soon, how many have expired, the renewal success rate, and four charts: an **expiration heatmap** (90-day weekly buckets), **renewal success rate trends** (30-day line chart), **certificate status distribution** (donut chart), and **issuance rate** (30-day bar chart). + +Explore the sidebar: Certificates, Agents, Policies, Jobs, Audit Trail, Notifications, Profiles, Teams, Owners, Agent Groups, Fleet Overview, Short-Lived Credentials, Discovery. + +### Scenarios to walk through + +**"We're about to have an outage"** — Filter certificates by status → Expiring. You'll see `auth-production` (12 days), `cdn-production` (8 days), and `mail-production` (5 days). At 47-day lifespans, this is every other week. certctl catches these automatically and triggers renewal before they expire. + +**"A renewal failed"** — Look at `vpn-production` — status: Failed. Click it to see the audit trail showing the ACME challenge failure after 3 retry attempts. The system sent a webhook notification to the ops channel. No one had to notice manually. + +**"Who owns this cert?"** — Click any certificate. Owner, team, environment, tags. Clear accountability. Notifications route to the owner's email automatically. + +**"Can I revoke a compromised cert?"** — Click any active certificate, then "Revoke." A modal with RFC 5280 reason codes (Key Compromise, Superseded, Cessation of Operation). After revocation, CRL and OCSP are served automatically — clients stop trusting the cert immediately. + +**"What about certificates already in production?"** — Click "Discovered Certificates." Agents scan local filesystems for existing certs. The server probes TLS endpoints on configured CIDR ranges. Both feed into a triage workflow: claim unmanaged certs to bring them under automation, or dismiss them. + +**"Show me the agent fleet"** — Click "Agents." Four agents online, one offline. Click "Fleet Overview" for OS/architecture grouping, version distribution, and per-platform listing. Agents generate ECDSA P-256 keys locally — private keys never leave your infrastructure. + +**"What about bulk operations?"** — On the Certificates page, select multiple certificates with checkboxes. A bulk action bar appears: trigger renewal, revoke with reason codes, or reassign ownership — all with progress tracking. At 47-day lifespans with hundreds of certs, bulk operations aren't optional. + +**"Short-lived credentials?"** — Click "Short-Lived" in the sidebar. Live countdown timers for certificates with TTL under 1 hour. Auto-refresh every 10 seconds. These are for service-to-service auth where rapid expiry replaces revocation. ## Explore the API -The dashboard reads from the same REST API you can call directly. All endpoints live under `/api/v1/` and return JSON. +Everything you see in the dashboard is backed by the REST API. All endpoints live under `/api/v1/` and return JSON. -### List all certificates +### Core operations ```bash +# List all certificates curl -s http://localhost:8443/api/v1/certificates | jq . -``` -The response has this shape: -```json -{ - "data": [ - { - "id": "mc-api-prod", - "name": "API Production", - "common_name": "api.example.com", - "sans": ["api.example.com", "api-v2.example.com"], - "environment": "production", - "owner_id": "o-alice", - "team_id": "t-platform", - "issuer_id": "iss-local", - "status": "Active", - "expires_at": "2026-05-28T00:00:00Z", - "tags": {"service": "api-gateway", "tier": "critical"}, - "created_at": "2026-03-14T00:00:00Z", - "updated_at": "2026-03-14T00:00:00Z" - } - ], - "total": 15, - "page": 1, - "per_page": 50 -} -``` - -### Filter by status - -```bash -# Get only expiring certificates +# Filter by status curl -s "http://localhost:8443/api/v1/certificates?status=Expiring" | jq . -# Get only production certificates +# Filter by environment curl -s "http://localhost:8443/api/v1/certificates?environment=production" | jq . -``` -### Get a specific certificate - -```bash +# Get a specific certificate curl -s http://localhost:8443/api/v1/certificates/mc-api-prod | jq . -``` -### List agents +# Get deployment targets for a certificate +curl -s http://localhost:8443/api/v1/certificates/mc-api-prod/deployments | jq . -```bash +# List agents curl -s http://localhost:8443/api/v1/agents | jq . -``` -### Check agent pending work - -```bash -# Replace with an actual agent ID from the list above +# Check agent pending work curl -s http://localhost:8443/api/v1/agents/agent-nginx-prod/work | jq . -``` -### View audit trail - -```bash +# View audit trail curl -s http://localhost:8443/api/v1/audit | jq . -``` -### View policy rules - -```bash +# View policies and violations curl -s http://localhost:8443/api/v1/policies | jq . +curl -s http://localhost:8443/api/v1/policies/pr-require-owner/violations | jq . + +# Notifications +curl -s http://localhost:8443/api/v1/notifications | jq . + +# Profiles and agent groups +curl -s http://localhost:8443/api/v1/profiles | jq . +curl -s http://localhost:8443/api/v1/agent-groups | jq . ``` -### View notifications +### Sorting, filtering, and pagination ```bash -curl -s http://localhost:8443/api/v1/notifications | jq . +# Sort by expiration date (ascending) +curl -s "http://localhost:8443/api/v1/certificates?sort=notAfter" | jq . + +# Sort descending (prefix with -) +curl -s "http://localhost:8443/api/v1/certificates?sort=-createdAt" | jq . + +# Time-range filters (RFC3339) +curl -s "http://localhost:8443/api/v1/certificates?expires_before=2026-05-01T00:00:00Z" | jq . +curl -s "http://localhost:8443/api/v1/certificates?created_after=2026-03-01T00:00:00Z" | jq . + +# Sparse fields — request only what you need +curl -s "http://localhost:8443/api/v1/certificates?fields=id,common_name,status,expires_at" | jq . + +# Cursor pagination — efficient for large inventories +curl -s "http://localhost:8443/api/v1/certificates?page_size=5" | jq '{next_cursor: .next_cursor, count: (.data | length)}' +curl -s "http://localhost:8443/api/v1/certificates?cursor=&page_size=5" | jq . +``` + +Supported sort fields: `notAfter`, `expiresAt`, `createdAt`, `updatedAt`, `commonName`, `name`, `status`, `environment`. + +### Stats and metrics + +```bash +# Dashboard summary +curl -s http://localhost:8443/api/v1/stats/summary | jq . + +# Certificates by status +curl -s http://localhost:8443/api/v1/stats/certificates-by-status | jq . + +# Expiration timeline (next 90 days) +curl -s "http://localhost:8443/api/v1/stats/expiration-timeline?days=90" | jq . + +# Job trends (last 30 days) +curl -s "http://localhost:8443/api/v1/stats/job-trends?days=30" | jq . + +# JSON metrics +curl -s http://localhost:8443/api/v1/metrics | jq . + +# Prometheus format (for Prometheus, Grafana Agent, Datadog) +curl -s http://localhost:8443/api/v1/metrics/prometheus ``` ## Create Your First Certificate -Let's create a new managed certificate from scratch using the API. This will create a certificate record that certctl will track, renew, and deploy. - -### Step 1: Create a certificate +Create a certificate record that certctl will track, renew, and deploy automatically. ```bash curl -s -X POST http://localhost:8443/api/v1/certificates \ @@ -168,47 +194,26 @@ curl -s -X POST http://localhost:8443/api/v1/certificates \ }' | jq . ``` -The server returns the created certificate. Since we didn't include an `id` field, the server auto-generates one using the name and a timestamp: -```json -{ - "id": "My First Certificate-1710403200000000000", - "name": "My First Certificate", - "common_name": "myapp.example.com", - "status": "Pending", - "created_at": "2026-03-14T..." -} -``` - Save the certificate ID (or provide your own `id` in the request body, e.g. `"id": "mc-my-first"`): ```bash CERT_ID="" ``` -### Step 2: Trigger renewal - +Trigger renewal: ```bash curl -s -X POST http://localhost:8443/api/v1/certificates/$CERT_ID/renew | jq . ``` -This creates a renewal job that will be processed by the scheduler. - -### Step 3: Check the certificate - +Check the result: ```bash curl -s http://localhost:8443/api/v1/certificates/$CERT_ID | jq . ``` -### Step 4: Check the audit trail - -```bash -curl -s http://localhost:8443/api/v1/audit | jq '.data[0:3]' -``` - Refresh the dashboard at http://localhost:8443 — your new certificate appears in the inventory. -### Step 5: Revoke a certificate +### Revoke a certificate -If a certificate's private key is compromised or the service is decommissioned, revoke it: +When a private key is compromised or a service is decommissioned: ```bash curl -s -X POST http://localhost:8443/api/v1/certificates/$CERT_ID/revoke \ @@ -216,111 +221,17 @@ curl -s -X POST http://localhost:8443/api/v1/certificates/$CERT_ID/revoke \ -d '{"reason": "superseded"}' | jq . ``` -Supported RFC 5280 reason codes: `unspecified`, `keyCompromise`, `caCompromise`, `affiliationChanged`, `superseded`, `cessationOfOperation`, `certificateHold`, `privilegeWithdrawn`. If you omit the reason, it defaults to `unspecified`. - -Check the CRL to confirm: +Supported RFC 5280 reason codes: `unspecified`, `keyCompromise`, `caCompromise`, `affiliationChanged`, `superseded`, `cessationOfOperation`, `certificateHold`, `privilegeWithdrawn`. +Confirm via CRL: ```bash curl -s http://localhost:8443/api/v1/crl | jq . ``` -## Understanding the Demo Data - -The demo comes pre-loaded with realistic data so you can explore certctl's features immediately: - -| Resource | Count | Examples | -|----------|-------|---------| -| Teams | 5 | Platform, Security, Payments, Frontend, Data | -| Owners | 5 | Alice, Bob, Carol, Dave, Eve | -| Issuers | 4 | Local Dev CA, Let's Encrypt Staging, step-ca Internal, DigiCert (disabled) | -| Agents | 5 | nginx-prod, nginx-staging, f5-prod, iis-prod, data-agent | -| Targets | 5 | NGINX (prod/staging/data), F5 LB, IIS | -| Certificates | 15 | Various statuses: Active, Expiring, Expired, Failed, Wildcard | -| Policies | 4 | Required owner, allowed environments, max lifetime, min renewal window | -| Profiles | 3 | Default TLS, Short-Lived, High-Security | -| Agent Groups | 5 | Linux agents, ARM agents, Production subnet, etc. | - -Certificates have varied statuses so you can see what each state looks like in the dashboard: healthy certs with 45+ days remaining, certs about to expire (5-12 days), certs that already expired, and a failed renewal. - -## Advanced API Features - -### Sorting and filtering - -```bash -# Sort certificates by expiration date (ascending) -curl -s "http://localhost:8443/api/v1/certificates?sort=notAfter" | jq . - -# Sort descending (prefix with -) -curl -s "http://localhost:8443/api/v1/certificates?sort=-createdAt" | jq . - -# Time-range filters (RFC3339 format) -curl -s "http://localhost:8443/api/v1/certificates?expires_before=2026-05-01T00:00:00Z" | jq . -curl -s "http://localhost:8443/api/v1/certificates?created_after=2026-03-01T00:00:00Z" | jq . -``` - -Supported sort fields: `notAfter`, `expiresAt`, `createdAt`, `updatedAt`, `commonName`, `name`, `status`, `environment`. - -### Sparse field selection - -Request only the fields you need to reduce response size: - -```bash -curl -s "http://localhost:8443/api/v1/certificates?fields=id,common_name,status,expires_at" | jq . -``` - -### Cursor-based pagination - -For large datasets, cursor pagination is more efficient than page-based: - -```bash -# First page -curl -s "http://localhost:8443/api/v1/certificates?page_size=5" | jq '{next_cursor: .next_cursor, count: (.data | length)}' - -# Next page (use the next_cursor from the previous response) -curl -s "http://localhost:8443/api/v1/certificates?cursor=&page_size=5" | jq . -``` - -### Stats and metrics - -```bash -# Dashboard summary -curl -s http://localhost:8443/api/v1/stats/summary | jq . - -# Certificates by status -curl -s http://localhost:8443/api/v1/stats/certificates-by-status | jq . - -# Expiration timeline (next 90 days) -curl -s "http://localhost:8443/api/v1/stats/expiration-timeline?days=90" | jq . - -# Job trends (last 30 days) -curl -s "http://localhost:8443/api/v1/stats/job-trends?days=30" | jq . - -# System metrics (JSON) -curl -s http://localhost:8443/api/v1/metrics | jq . - -# System metrics (Prometheus format — for scraping by Prometheus, Grafana Agent, Datadog) -curl -s http://localhost:8443/api/v1/metrics/prometheus -``` - -### Certificate profiles - -```bash -# List all profiles -curl -s http://localhost:8443/api/v1/profiles | jq . - -# Get a specific profile -curl -s http://localhost:8443/api/v1/profiles/prof-default | jq . -``` - -### Certificate deployments - -```bash -# View deployment targets for a certificate -curl -s http://localhost:8443/api/v1/certificates/mc-api-prod/deployments | jq . -``` - ### Interactive approval workflow +For high-value certificates where you want human oversight: + ```bash # Approve a pending job curl -s -X POST http://localhost:8443/api/v1/jobs/JOB_ID/approve \ @@ -333,49 +244,25 @@ curl -s -X POST http://localhost:8443/api/v1/jobs/JOB_ID/reject \ -d '{"reason": "Key type does not meet compliance requirements"}' | jq . ``` -## Tear Down +## Certificate Discovery -```bash -docker compose -f deploy/docker-compose.yml down -v -``` +Find certificates already running in your infrastructure — ones you didn't issue through certctl. -The `-v` flag removes the PostgreSQL data volume so you get a clean slate next time. - -### Certificate Discovery - -Agents can scan your infrastructure for existing certificates you're not yet managing: +### Filesystem discovery (agent-based) ```bash # Configure agent to scan directories export CERTCTL_DISCOVERY_DIRS="/etc/nginx/certs,/etc/ssl/certs,/var/lib/certs" - -# Agent scans on startup + every 6 hours, reports findings to control plane +# Agent scans on startup + every 6 hours ``` -Query discovered certificates: +### Network discovery (agentless) ```bash -# List all discovered certs from a specific agent -curl -s "http://localhost:8443/api/v1/discovered-certificates?agent_id=agent-nginx-prod" | jq . - -# Get discovery summary (counts by status) -curl -s http://localhost:8443/api/v1/discovery-summary | jq . - -# Claim a discovered cert (link to managed cert) -curl -s -X POST "http://localhost:8443/api/v1/discovered-certificates/DISCOVERY_ID/claim" \ - -H "Content-Type: application/json" \ - -d '{"managed_certificate_id": "mc-api-prod"}' | jq . -``` - -### Network Certificate Discovery - -The server can also discover certificates by scanning TLS endpoints directly — no agent required: - -```bash -# Enable network scanning (set in environment or docker-compose) +# Enable network scanning export CERTCTL_NETWORK_SCAN_ENABLED=true -# Create a scan target (e.g., scan your internal network on port 443) +# Create a scan target curl -s -X POST http://localhost:8443/api/v1/network-scan-targets \ -H "Content-Type: application/json" \ -d '{ @@ -389,17 +276,105 @@ curl -s -X POST http://localhost:8443/api/v1/network-scan-targets \ # Trigger an immediate scan curl -s -X POST http://localhost:8443/api/v1/network-scan-targets/nst-internal-network/scan | jq . - -# List scan targets with results -curl -s http://localhost:8443/api/v1/network-scan-targets | jq . ``` -Discovered network certificates appear in the same `GET /api/v1/discovered-certificates` list as filesystem-discovered certs, with `agent_id=server-scanner` and `source_format=network`. +### Triage discovered certificates + +```bash +# List discovered certs +curl -s "http://localhost:8443/api/v1/discovered-certificates?agent_id=agent-nginx-prod" | jq . + +# Summary counts +curl -s http://localhost:8443/api/v1/discovery-summary | jq . + +# Claim a discovered cert (bring under management) +curl -s -X POST "http://localhost:8443/api/v1/discovered-certificates/DISCOVERY_ID/claim" \ + -H "Content-Type: application/json" \ + -d '{"managed_certificate_id": "mc-api-prod"}' | jq . +``` + +## CLI Tool + +```bash +cd cmd/cli && go build -o certctl-cli . + +export CERTCTL_SERVER_URL="http://localhost:8443" +export CERTCTL_API_KEY="test-key-123" + +./certctl-cli certs list # List certificates +./certctl-cli certs get mc-api-prod # Certificate details +./certctl-cli certs renew mc-api-prod # Trigger renewal +./certctl-cli certs revoke mc-api-prod --reason keyCompromise +./certctl-cli agents list # List agents +./certctl-cli jobs list # List jobs +./certctl-cli import /path/to/certs.pem # Bulk import +./certctl-cli status # Health + stats +``` + +## MCP Server (AI Integration) + +```bash +cd cmd/mcp-server && go build -o mcp-server . + +export CERTCTL_SERVER_URL="http://localhost:8443" +export CERTCTL_API_KEY="test-key-123" + +./mcp-server +``` + +Exposes all 78 API endpoints as MCP tools via stdio transport. Ask Claude: "What certificates are expiring in the next 30 days?", "Revoke the payments cert due to key compromise", "Show me the audit trail." + +## Demo Data Reference + +| Resource | Count | Examples | +|----------|-------|---------| +| Teams | 5 | Platform, Security, Payments, Frontend, Data | +| Owners | 5 | Alice, Bob, Carol, Dave, Eve | +| Issuers | 4 | Local Dev CA, Let's Encrypt Staging, step-ca Internal, DigiCert (disabled) | +| Agents | 5 | nginx-prod, nginx-staging, f5-prod, iis-prod, data-agent | +| Targets | 5 | NGINX (prod/staging/data), F5 LB, IIS | +| Certificates | 15 | Various statuses: Active, Expiring, Expired, Failed, Wildcard | +| Policies | 4 | Required owner, allowed environments, max lifetime, min renewal window | +| Profiles | 3 | Default TLS, Short-Lived, High-Security | +| Agent Groups | 5 | Linux agents, ARM agents, Production subnet, etc. | + +## Dashboard Demo Mode + +The dashboard works without a backend for screenshots and presentations: + +```bash +cd web && npm install && npm run dev +# Dashboard at http://localhost:5173 +``` + +When the API is unreachable, the dashboard loads realistic mock data with a "Demo Mode" badge. + +## Presenting to Stakeholders + +A suggested 5-minute flow: + +1. **Dashboard** — "Certificate inventory at a glance. Real-time charts show expiration trends and renewal health." +2. **Expiring certs** — "These three would have caused outages. At 47-day lifespans, this happens every other week." +3. **Certificate detail** — "Full lifecycle: who owns it, where it's deployed, deployment timeline, version history with rollback." +4. **Revocation** — "One click revokes with an RFC 5280 reason code. CRL and OCSP served automatically." +5. **Failed renewal** — "System tried 3 times, then alerted the team via Slack, Teams, PagerDuty, or OpsGenie." +6. **Agent fleet** — "Agents handle key generation locally (ECDSA P-256). Private keys never leave your infrastructure." +7. **Discovery** — "Agents scan filesystems, server probes TLS endpoints. We find what you're not managing yet." +8. **Bulk operations** — "Select multiple certs, renew or revoke in bulk. At 47-day lifespans with hundreds of certs, this is essential." +9. **Audit trail** — "Every action recorded. Export to CSV/JSON for compliance." +10. **CLI + MCP** — "Terminal users get `certctl-cli`. AI assistants get MCP integration. Everything is API-first." + +## Tear Down + +```bash +docker compose -f deploy/docker-compose.yml down -v +``` + +The `-v` flag removes the PostgreSQL data volume for a clean slate. ## What's Next -- **[Advanced Demo](demo-advanced.md)** — Issue a real certificate via the Local CA and watch it appear in the dashboard -- **[Demo Walkthrough](demo-guide.md)** — Guided 5-minute stakeholder presentation +- **[Advanced Demo](demo-advanced.md)** — Issue a real certificate via the Local CA end-to-end - **[Architecture](architecture.md)** — How the control plane, agents, and connectors work together - **[Connector Guide](connectors.md)** — Build custom connectors for your infrastructure -- **[CLI Reference](cli.md)** — Manage certificates from your terminal +- **[Concepts Guide](concepts.md)** — TLS certificates, CAs, and private keys explained from scratch diff --git a/docs/testing-guide.md b/docs/testing-guide.md index e41c85d..51303de 100644 --- a/docs/testing-guide.md +++ b/docs/testing-guide.md @@ -3665,7 +3665,7 @@ docker compose logs certctl-server 2>&1 | grep -v "^certctl-server" | grep -cv " | 24.1.4 | `docs/architecture.md` | Component diagram matches `docker compose ps`. Says "21 tables", "78 MCP Tools", "900+ tests". | PASS if numbers match | | 24.1.5 | `docs/connectors.md` | All 5 issuer types and 5 target types documented. F5/IIS marked as stubs. | PASS if all documented | | 24.1.6 | `docs/features.md` | Endpoint count (93), MCP tools (78), table count (21), test count (900+) all accurate. | PASS if numbers match | -| 24.1.7 | `docs/demo-guide.md` | Demo walkthrough works against fresh `docker compose up`. | PASS if all steps work | +| 24.1.7 | `docs/quickstart.md` | Quick start + demo walkthrough works against fresh `docker compose up`. | PASS if all steps work | | 24.1.8 | `docs/demo-advanced.md` | All parts executable against running stack. Network discovery section present. | PASS if all executable | | 24.1.9 | `docs/compliance.md` | Framework links resolve, mapping references real features. | PASS if links work | | 24.1.10 | `docs/compliance-soc2.md` | API endpoints cited actually exist in the router. | PASS if endpoints exist |