mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 13:51:36 +00:00
feat(V2.2): bulk revocation — filter-based fleet-wide certificate revocation
Add POST /api/v1/certificates/bulk-revoke with filter criteria (profile_id, owner_id, agent_id, issuer_id, team_id, certificate_ids), partial-failure tolerance, and audit trail. Includes MCP tool, CLI command (certs bulk-revoke), server-side bulk modal in GUI replacing client-side sequential loop, OpenAPI spec, compliance mapping updates, and 21 new tests (12 service, 7 handler, 1 CLI, 1 frontend). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -182,6 +182,38 @@ func registerCertificateTools(s *gomcp.Server, c *Client) {
|
||||
}
|
||||
return textResult(data)
|
||||
})
|
||||
|
||||
gomcp.AddTool(s, &gomcp.Tool{
|
||||
Name: "certctl_bulk_revoke_certificates",
|
||||
Description: "Bulk revoke certificates matching filter criteria. At least one criterion (profile_id, owner_id, agent_id, issuer_id, team_id, or certificate_ids) is required. Returns counts of matched, revoked, skipped, and failed certificates.",
|
||||
}, func(ctx context.Context, req *gomcp.CallToolRequest, input BulkRevokeCertificatesInput) (*gomcp.CallToolResult, any, error) {
|
||||
body := map[string]interface{}{
|
||||
"reason": input.Reason,
|
||||
}
|
||||
if input.ProfileID != "" {
|
||||
body["profile_id"] = input.ProfileID
|
||||
}
|
||||
if input.OwnerID != "" {
|
||||
body["owner_id"] = input.OwnerID
|
||||
}
|
||||
if input.AgentID != "" {
|
||||
body["agent_id"] = input.AgentID
|
||||
}
|
||||
if input.IssuerID != "" {
|
||||
body["issuer_id"] = input.IssuerID
|
||||
}
|
||||
if input.TeamID != "" {
|
||||
body["team_id"] = input.TeamID
|
||||
}
|
||||
if len(input.CertificateIDs) > 0 {
|
||||
body["certificate_ids"] = input.CertificateIDs
|
||||
}
|
||||
data, err := c.Post("/api/v1/certificates/bulk-revoke", body)
|
||||
if err != nil {
|
||||
return errorResult(err)
|
||||
}
|
||||
return textResult(data)
|
||||
})
|
||||
}
|
||||
|
||||
// ── CRL & OCSP ──────────────────────────────────────────────────────
|
||||
|
||||
@@ -62,6 +62,16 @@ type RevokeCertificateInput struct {
|
||||
Reason string `json:"reason,omitempty" jsonschema:"RFC 5280 reason: unspecified, keyCompromise, caCompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, privilegeWithdrawn"`
|
||||
}
|
||||
|
||||
type BulkRevokeCertificatesInput struct {
|
||||
Reason string `json:"reason" jsonschema:"RFC 5280 reason: unspecified, keyCompromise, caCompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, privilegeWithdrawn"`
|
||||
ProfileID string `json:"profile_id,omitempty" jsonschema:"Revoke all certs matching this profile ID"`
|
||||
OwnerID string `json:"owner_id,omitempty" jsonschema:"Revoke all certs owned by this owner"`
|
||||
AgentID string `json:"agent_id,omitempty" jsonschema:"Revoke all certs deployed via this agent"`
|
||||
IssuerID string `json:"issuer_id,omitempty" jsonschema:"Revoke all certs issued by this issuer"`
|
||||
TeamID string `json:"team_id,omitempty" jsonschema:"Revoke all certs owned by members of this team"`
|
||||
CertificateIDs []string `json:"certificate_ids,omitempty" jsonschema:"Explicit list of certificate IDs to revoke"`
|
||||
}
|
||||
|
||||
type ListVersionsInput struct {
|
||||
ID string `json:"id" jsonschema:"Certificate ID"`
|
||||
ListParams
|
||||
|
||||
Reference in New Issue
Block a user