mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 15:41:41 +00:00
feat: M18b Filesystem Certificate Discovery — agent scanning, server dedup, triage API
Agent-side:
- Filesystem scanner walks configured directories (CERTCTL_DISCOVERY_DIRS)
- Parses PEM (.pem, .crt, .cer, .cert) and DER (.der) certificate files
- Extracts CN, SANs, serial, issuer/subject DN, validity, key info, SHA-256 fingerprint
- Reports discoveries to control plane on startup + every 6 hours
- Skips files >1MB and private key files
Server-side:
- Migration 000006: discovered_certificates + discovery_scans tables
- Domain model: DiscoveredCertificate, DiscoveryScan, DiscoveryReport
- Three triage states: Unmanaged, Managed (claimed), Dismissed
- Repository with upsert dedup (fingerprint + agent + path)
- Service layer: process reports, claim, dismiss, list, summary
- 7 new API endpoints (84 total):
POST /agents/{id}/discoveries, GET /discovered-certificates,
GET /discovered-certificates/{id}, POST .../claim, POST .../dismiss,
GET /discovery-scans, GET /discovery-summary
- Audit trail: scan_completed, cert_claimed, cert_dismissed events
Tests: 28 new test functions (domain, handler, service layers)
Docs: README, quickstart, demo-guide, demo-advanced, architecture,
concepts, connectors, features.md all updated
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -205,6 +205,39 @@ type AgentGroupRepository interface {
|
||||
RemoveMember(ctx context.Context, groupID, agentID string) error
|
||||
}
|
||||
|
||||
// DiscoveryRepository defines operations for managing certificate discovery.
|
||||
type DiscoveryRepository interface {
|
||||
// CreateScan stores a new discovery scan record.
|
||||
CreateScan(ctx context.Context, scan *domain.DiscoveryScan) error
|
||||
// GetScan retrieves a discovery scan by ID.
|
||||
GetScan(ctx context.Context, id string) (*domain.DiscoveryScan, error)
|
||||
// ListScans returns discovery scans, optionally filtered by agent ID.
|
||||
ListScans(ctx context.Context, agentID string, page, perPage int) ([]*domain.DiscoveryScan, int, error)
|
||||
// CreateDiscovered stores a new discovered certificate (upserts by fingerprint+agent+path).
|
||||
// Returns true if the certificate was newly inserted (not just updated).
|
||||
CreateDiscovered(ctx context.Context, cert *domain.DiscoveredCertificate) (bool, error)
|
||||
// GetDiscovered retrieves a discovered certificate by ID.
|
||||
GetDiscovered(ctx context.Context, id string) (*domain.DiscoveredCertificate, error)
|
||||
// ListDiscovered returns discovered certificates matching the filter.
|
||||
ListDiscovered(ctx context.Context, filter *DiscoveryFilter) ([]*domain.DiscoveredCertificate, int, error)
|
||||
// UpdateDiscoveredStatus updates the status and optional managed certificate link.
|
||||
UpdateDiscoveredStatus(ctx context.Context, id string, status domain.DiscoveryStatus, managedCertID string) error
|
||||
// GetByFingerprint retrieves discovered certificates by SHA-256 fingerprint.
|
||||
GetByFingerprint(ctx context.Context, fingerprint string) ([]*domain.DiscoveredCertificate, error)
|
||||
// CountByStatus returns counts of discovered certificates grouped by status.
|
||||
CountByStatus(ctx context.Context) (map[string]int, error)
|
||||
}
|
||||
|
||||
// DiscoveryFilter defines filters for listing discovered certificates.
|
||||
type DiscoveryFilter struct {
|
||||
AgentID string
|
||||
Status string
|
||||
IsExpired bool
|
||||
IsCA bool
|
||||
Page int
|
||||
PerPage int
|
||||
}
|
||||
|
||||
// OwnerRepository defines operations for managing certificate owners.
|
||||
type OwnerRepository interface {
|
||||
// List returns all owners.
|
||||
|
||||
Reference in New Issue
Block a user