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 <noreply@anthropic.com>
This commit is contained in:
Shankar
2026-03-25 04:09:03 -04:00
parent 16f5c92988
commit 3a48a9e584
5 changed files with 204 additions and 483 deletions
+1 -1
View File
@@ -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)
-253
View File
@@ -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
+201 -226
View File
@@ -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=<next_cursor_value>&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="<paste the id from the response>"
```
### 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=<next_cursor_value>&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
+1 -1
View File
@@ -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 |