mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 13:41:30 +00:00
docs: complete V2 audit remediation — OpenAPI spec, demos, and features
- Add 15 missing operations to openapi.yaml (M18b discovery, M20 deployments, M21 network scan, M22 Prometheus) — spec now has 93 operations matching all 93 router routes - Add 6 new component schemas (DiscoveredCertificate, DiscoveryScan, DiscoveryReport, NetworkScanTarget, NetworkScanTargetCreate, StatusMessageResponse) - Add Discovery and Network Scan tags to OpenAPI spec - Fix stale "Prometheus format deferred to V3" claim in metrics description - Add Part 4.5 (Target CRUD) to demo-advanced.md with create/update/delete curl examples - Expand Certificate Profiles section in features.md with list/get/update curl examples - Add Deployment Trigger section to features.md with curl examples - Add discovery-summary and discovery-scans curl examples to features.md - Remove 3 empty directories (internal/agent/, internal/audit/, internal/policy/) - Update features.md OpenAPI scope from "78 documented" to "93 operations" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+601
-1
@@ -58,6 +58,10 @@ tags:
|
||||
description: System metrics (gauges, counters, uptime)
|
||||
- name: Health
|
||||
description: Health and readiness probes, auth info
|
||||
- name: Discovery
|
||||
description: Certificate discovery — filesystem scanning by agents and network TLS probing
|
||||
- name: Network Scan
|
||||
description: Network scan target management for active TLS certificate discovery
|
||||
|
||||
paths:
|
||||
# ─── Health & Auth ───────────────────────────────────────────────────
|
||||
@@ -1900,7 +1904,7 @@ paths:
|
||||
get:
|
||||
tags: [Metrics]
|
||||
summary: System metrics
|
||||
description: JSON metrics snapshot with gauges, counters, and uptime. Prometheus format deferred to V3.
|
||||
description: JSON metrics snapshot with gauges, counters, and uptime. See also /api/v1/metrics/prometheus for Prometheus exposition format.
|
||||
operationId: getMetrics
|
||||
responses:
|
||||
"200":
|
||||
@@ -1912,6 +1916,384 @@ paths:
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
# ─── Prometheus Metrics (M22) ──────────────────────────────────────
|
||||
/api/v1/metrics/prometheus:
|
||||
get:
|
||||
tags: [Metrics]
|
||||
summary: Prometheus metrics
|
||||
description: |
|
||||
Prometheus exposition format metrics. Compatible with Prometheus, Grafana Agent,
|
||||
Datadog Agent, Victoria Metrics, and any OpenMetrics scraper.
|
||||
Returns 11 metrics with certctl_ prefix (8 gauges, 2 counters, 1 info).
|
||||
operationId: getPrometheusMetrics
|
||||
responses:
|
||||
"200":
|
||||
description: Prometheus text format
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
description: "Prometheus exposition format (text/plain; version=0.0.4)"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
# ─── Certificate Deployments (M20) ─────────────────────────────────
|
||||
/api/v1/certificates/{id}/deployments:
|
||||
get:
|
||||
tags: [Certificates]
|
||||
summary: List certificate deployments
|
||||
description: Returns deployment targets associated with this certificate.
|
||||
operationId: getCertificateDeployments
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
responses:
|
||||
"200":
|
||||
description: Deployment targets for this certificate
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/DeploymentTarget"
|
||||
total:
|
||||
type: integer
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
# ─── Discovery (M18b) ─────────────────────────────────────────────
|
||||
/api/v1/agents/{id}/discoveries:
|
||||
post:
|
||||
tags: [Discovery]
|
||||
summary: Submit discovery report
|
||||
description: |
|
||||
Agent submits a batch of discovered certificates from filesystem scanning.
|
||||
Server deduplicates by (fingerprint, agent_id, source_path) and records scan metadata.
|
||||
operationId: submitDiscoveryReport
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DiscoveryReport"
|
||||
responses:
|
||||
"202":
|
||||
description: Report accepted and processed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DiscoveryScan"
|
||||
"400":
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/discovered-certificates:
|
||||
get:
|
||||
tags: [Discovery]
|
||||
summary: List discovered certificates
|
||||
description: Returns discovered certificates with optional filters by agent and triage status.
|
||||
operationId: listDiscoveredCertificates
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/page"
|
||||
- $ref: "#/components/parameters/per_page"
|
||||
- name: agent_id
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: Filter by discovering agent
|
||||
- name: status
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum: [Unmanaged, Managed, Dismissed]
|
||||
description: Filter by triage status
|
||||
responses:
|
||||
"200":
|
||||
description: Paginated list of discovered certificates
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/PaginationEnvelope"
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/DiscoveredCertificate"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/discovered-certificates/{id}:
|
||||
get:
|
||||
tags: [Discovery]
|
||||
summary: Get discovered certificate
|
||||
description: Returns a single discovered certificate by ID.
|
||||
operationId: getDiscoveredCertificate
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
responses:
|
||||
"200":
|
||||
description: Discovered certificate details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DiscoveredCertificate"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/discovered-certificates/{id}/claim:
|
||||
post:
|
||||
tags: [Discovery]
|
||||
summary: Claim discovered certificate
|
||||
description: Links a discovered certificate to an existing managed certificate. Changes status to Managed.
|
||||
operationId: claimDiscoveredCertificate
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [managed_certificate_id]
|
||||
properties:
|
||||
managed_certificate_id:
|
||||
type: string
|
||||
description: ID of the managed certificate to link to
|
||||
responses:
|
||||
"200":
|
||||
description: Certificate claimed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/StatusMessageResponse"
|
||||
"400":
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/discovered-certificates/{id}/dismiss:
|
||||
post:
|
||||
tags: [Discovery]
|
||||
summary: Dismiss discovered certificate
|
||||
description: Marks a discovered certificate as dismissed (excluded from triage queue).
|
||||
operationId: dismissDiscoveredCertificate
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
responses:
|
||||
"200":
|
||||
description: Certificate dismissed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/StatusMessageResponse"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/discovery-scans:
|
||||
get:
|
||||
tags: [Discovery]
|
||||
summary: List discovery scans
|
||||
description: Returns history of discovery scan executions with optional agent filter.
|
||||
operationId: listDiscoveryScans
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/page"
|
||||
- $ref: "#/components/parameters/per_page"
|
||||
- name: agent_id
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: Filter by agent ID
|
||||
responses:
|
||||
"200":
|
||||
description: Paginated list of discovery scans
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/PaginationEnvelope"
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/DiscoveryScan"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/discovery-summary:
|
||||
get:
|
||||
tags: [Discovery]
|
||||
summary: Discovery status summary
|
||||
description: Returns aggregate counts of discovered certificates by triage status.
|
||||
operationId: getDiscoverySummary
|
||||
responses:
|
||||
"200":
|
||||
description: Status counts
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
Unmanaged:
|
||||
type: integer
|
||||
Managed:
|
||||
type: integer
|
||||
Dismissed:
|
||||
type: integer
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
# ─── Network Scan Targets (M21) ───────────────────────────────────
|
||||
/api/v1/network-scan-targets:
|
||||
get:
|
||||
tags: [Network Scan]
|
||||
summary: List network scan targets
|
||||
description: Returns all configured network scan targets with CIDR ranges and ports.
|
||||
operationId: listNetworkScanTargets
|
||||
responses:
|
||||
"200":
|
||||
description: List of network scan targets
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/PaginationEnvelope"
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/NetworkScanTarget"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
post:
|
||||
tags: [Network Scan]
|
||||
summary: Create network scan target
|
||||
description: |
|
||||
Creates a new network scan target. CIDR ranges are validated and capped at /20
|
||||
(4096 IPs max per CIDR) to prevent accidental huge scans.
|
||||
operationId: createNetworkScanTarget
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/NetworkScanTargetCreate"
|
||||
responses:
|
||||
"201":
|
||||
description: Target created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/NetworkScanTarget"
|
||||
"400":
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/network-scan-targets/{id}:
|
||||
get:
|
||||
tags: [Network Scan]
|
||||
summary: Get network scan target
|
||||
description: Returns a single network scan target by ID.
|
||||
operationId: getNetworkScanTarget
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
responses:
|
||||
"200":
|
||||
description: Network scan target details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/NetworkScanTarget"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
put:
|
||||
tags: [Network Scan]
|
||||
summary: Update network scan target
|
||||
description: Updates an existing network scan target.
|
||||
operationId: updateNetworkScanTarget
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/NetworkScanTargetCreate"
|
||||
responses:
|
||||
"200":
|
||||
description: Target updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/NetworkScanTarget"
|
||||
"400":
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
delete:
|
||||
tags: [Network Scan]
|
||||
summary: Delete network scan target
|
||||
description: Deletes a network scan target.
|
||||
operationId: deleteNetworkScanTarget
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
responses:
|
||||
"204":
|
||||
description: Target deleted
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/api/v1/network-scan-targets/{id}/scan:
|
||||
post:
|
||||
tags: [Network Scan]
|
||||
summary: Trigger network scan
|
||||
description: |
|
||||
Triggers an immediate scan of the specified target. Scans all configured CIDRs and ports
|
||||
concurrently (50 goroutines). Results feed into the discovery pipeline for deduplication.
|
||||
operationId: triggerNetworkScan
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/resourceId"
|
||||
responses:
|
||||
"202":
|
||||
description: Scan completed with certificates found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/DiscoveryScan"
|
||||
"200":
|
||||
description: Scan completed, no certificates found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/StatusMessageResponse"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════
|
||||
components:
|
||||
securitySchemes:
|
||||
@@ -2578,3 +2960,221 @@ components:
|
||||
measured_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
# ─── Discovery (M18b) ────────────────────────────────────────────
|
||||
DiscoveredCertificate:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
fingerprint_sha256:
|
||||
type: string
|
||||
common_name:
|
||||
type: string
|
||||
sans:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
serial_number:
|
||||
type: string
|
||||
issuer_dn:
|
||||
type: string
|
||||
subject_dn:
|
||||
type: string
|
||||
not_before:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
not_after:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
key_algorithm:
|
||||
type: string
|
||||
key_size:
|
||||
type: integer
|
||||
is_ca:
|
||||
type: boolean
|
||||
source_path:
|
||||
type: string
|
||||
source_format:
|
||||
type: string
|
||||
agent_id:
|
||||
type: string
|
||||
discovery_scan_id:
|
||||
type: string
|
||||
nullable: true
|
||||
managed_certificate_id:
|
||||
type: string
|
||||
nullable: true
|
||||
status:
|
||||
type: string
|
||||
enum: [Unmanaged, Managed, Dismissed]
|
||||
first_seen_at:
|
||||
type: string
|
||||
format: date-time
|
||||
last_seen_at:
|
||||
type: string
|
||||
format: date-time
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
DiscoveryScan:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
agent_id:
|
||||
type: string
|
||||
directories:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
certificates_found:
|
||||
type: integer
|
||||
certificates_new:
|
||||
type: integer
|
||||
errors_count:
|
||||
type: integer
|
||||
scan_duration_ms:
|
||||
type: integer
|
||||
started_at:
|
||||
type: string
|
||||
format: date-time
|
||||
completed_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
|
||||
DiscoveryReport:
|
||||
type: object
|
||||
required: [agent_id, directories, certificates]
|
||||
properties:
|
||||
agent_id:
|
||||
type: string
|
||||
directories:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
certificates:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
fingerprint_sha256:
|
||||
type: string
|
||||
common_name:
|
||||
type: string
|
||||
sans:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
serial_number:
|
||||
type: string
|
||||
issuer_dn:
|
||||
type: string
|
||||
subject_dn:
|
||||
type: string
|
||||
not_before:
|
||||
type: string
|
||||
not_after:
|
||||
type: string
|
||||
key_algorithm:
|
||||
type: string
|
||||
key_size:
|
||||
type: integer
|
||||
is_ca:
|
||||
type: boolean
|
||||
pem_data:
|
||||
type: string
|
||||
source_path:
|
||||
type: string
|
||||
source_format:
|
||||
type: string
|
||||
errors:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
scan_duration_ms:
|
||||
type: integer
|
||||
|
||||
StatusMessageResponse:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
|
||||
# ─── Network Scan (M21) ──────────────────────────────────────────
|
||||
NetworkScanTarget:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
cidrs:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: CIDR ranges to scan (max /20 per CIDR)
|
||||
ports:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
description: TCP ports to probe for TLS
|
||||
enabled:
|
||||
type: boolean
|
||||
scan_interval_hours:
|
||||
type: integer
|
||||
description: Hours between scheduled scans
|
||||
timeout_ms:
|
||||
type: integer
|
||||
description: Per-connection timeout in milliseconds
|
||||
last_scan_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
last_scan_duration_ms:
|
||||
type: integer
|
||||
nullable: true
|
||||
last_scan_certs_found:
|
||||
type: integer
|
||||
nullable: true
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
updated_at:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
NetworkScanTargetCreate:
|
||||
type: object
|
||||
required: [name, cidrs]
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
cidrs:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: CIDR ranges (max /20 per CIDR, max 4096 IPs)
|
||||
ports:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
description: TCP ports to probe (default [443])
|
||||
enabled:
|
||||
type: boolean
|
||||
default: true
|
||||
scan_interval_hours:
|
||||
type: integer
|
||||
default: 6
|
||||
timeout_ms:
|
||||
type: integer
|
||||
default: 5000
|
||||
|
||||
@@ -372,6 +372,39 @@ curl -s "$API/api/v1/jobs" | jq '.data[] | select(.certificate_id == "mc-demo-ap
|
||||
|
||||
---
|
||||
|
||||
## Part 4.5: Manage Deployment Targets
|
||||
|
||||
Before deploying, you need targets. The demo seeds 5 targets, but you can also create, update, and delete them via API:
|
||||
|
||||
```bash
|
||||
# List all targets
|
||||
curl -s "$API/api/v1/targets" | jq '.data[] | {id, name, type, agent_id}'
|
||||
|
||||
# Create a new NGINX target
|
||||
curl -s -X POST "$API/api/v1/targets" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"id": "tgt-nginx-api",
|
||||
"name": "API NGINX",
|
||||
"type": "nginx",
|
||||
"agent_id": "ag-web-prod",
|
||||
"config": {"cert_path": "/etc/nginx/certs/api.crt", "key_path": "/etc/nginx/certs/api.key", "reload_command": "systemctl reload nginx"},
|
||||
"enabled": true
|
||||
}' | jq .
|
||||
|
||||
# Update a target
|
||||
curl -s -X PUT "$API/api/v1/targets/tgt-nginx-api" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "API NGINX (updated)", "type": "nginx", "agent_id": "ag-web-prod", "config": {"cert_path": "/etc/nginx/certs/api.crt"}, "enabled": true}' | jq .
|
||||
|
||||
# Delete a target
|
||||
curl -s -X DELETE "$API/api/v1/targets/tgt-nginx-api"
|
||||
```
|
||||
|
||||
Each target type (NGINX, Apache, HAProxy, F5, IIS) accepts different configuration fields. The `config` JSON is validated at deployment time by the target connector.
|
||||
|
||||
---
|
||||
|
||||
## Part 5: Deploy the Certificate
|
||||
|
||||
Trigger deployment to see the deployment workflow:
|
||||
|
||||
+36
-1
@@ -128,6 +128,21 @@ curl -H "$AUTH" "$SERVER/api/v1/certificates?expires_before=2026-04-24T00:00:00Z
|
||||
- Server signs and stores certificate version
|
||||
- Work endpoint enriched with `common_name` and `sans` for agent CSR generation
|
||||
|
||||
### Deployment Trigger
|
||||
Push certificates to targets on demand, outside of the normal scheduler-driven flow:
|
||||
|
||||
```bash
|
||||
# Deploy to all mapped targets
|
||||
curl -X POST -H "$AUTH" $SERVER/api/v1/certificates/mc-api-prod/deploy
|
||||
|
||||
# Deploy to a specific target
|
||||
curl -X POST -H "$AUTH" -H "$CT" $SERVER/api/v1/certificates/mc-api-prod/deploy \
|
||||
-d '{"target_id": "tgt-nginx-prod"}'
|
||||
|
||||
# Check deployment job status
|
||||
curl -H "$AUTH" "$SERVER/api/v1/certificates/mc-api-prod/deployments" | jq '.data[] | {id, name, type}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Revocation Infrastructure
|
||||
@@ -192,6 +207,17 @@ curl -X POST -H "$AUTH" -H "$CT" $SERVER/api/v1/profiles -d '{
|
||||
curl -X PUT -H "$AUTH" -H "$CT" $SERVER/api/v1/certificates/mc-api-prod -d '{
|
||||
"profile_id": "prof-short-lived"
|
||||
}'
|
||||
|
||||
# List all profiles
|
||||
curl -H "$AUTH" "$SERVER/api/v1/profiles" | jq '.data[] | {id, name, max_ttl_hours, allowed_key_algorithms}'
|
||||
|
||||
# Get profile details
|
||||
curl -H "$AUTH" "$SERVER/api/v1/profiles/prof-standard-tls" | jq .
|
||||
|
||||
# Update profile constraints
|
||||
curl -X PUT -H "$AUTH" -H "$CT" $SERVER/api/v1/profiles/prof-standard-tls -d '{
|
||||
"name": "Standard TLS", "max_ttl_hours": 2160, "allowed_key_algorithms": ["RSA", "ECDSA"]
|
||||
}'
|
||||
```
|
||||
|
||||
| Field | Details |
|
||||
@@ -519,6 +545,15 @@ Each discovered certificate is parsed and its metadata extracted:
|
||||
| `/api/v1/discovery-scans` | GET | List scan history with timestamps |
|
||||
| `/api/v1/discovery-summary` | GET | Aggregate status counts (Unmanaged, Managed, Dismissed) |
|
||||
|
||||
```bash
|
||||
# Check triage status at a glance
|
||||
curl -H "$AUTH" "$SERVER/api/v1/discovery-summary" | jq .
|
||||
# → {"Unmanaged": 12, "Managed": 45, "Dismissed": 3}
|
||||
|
||||
# Review scan execution history
|
||||
curl -H "$AUTH" "$SERVER/api/v1/discovery-scans" | jq '.data[] | {agent_id, certificates_found, certificates_new, started_at}'
|
||||
```
|
||||
|
||||
### Use Cases
|
||||
- **Inventory Baseline** — Scan production servers at deployment time to establish baseline of existing certificates
|
||||
- **Compliance Discovery** — Find all TLS certs before renewing certificate policies
|
||||
@@ -889,7 +924,7 @@ The web dashboard is the primary operational interface for certctl. Built with *
|
||||
|
||||
### OpenAPI 3.1 Specification
|
||||
- **File** — `api/openapi.yaml`
|
||||
- **Scope** — 78 documented operations (spec covers core API; discovery and network scan endpoints pending addition)
|
||||
- **Scope** — 93 operations (91 API + /health + /ready), all request/response schemas, enums, pagination
|
||||
- **Schemas** — Complete domain models with examples
|
||||
- **Enums** — Job types, states, policy rule types, notification types
|
||||
- **Pagination** — Standard envelope (data, total, page, per_page)
|
||||
|
||||
Reference in New Issue
Block a user