feat(M44): Google CAS issuer connector

Google Cloud Certificate Authority Service integration via REST API
with OAuth2 service account auth (JWT→access token). Synchronous
issuance model, CA pool selection, mutex-guarded token caching,
revocation with RFC 5280 reason mapping. No Google SDK dependency —
all stdlib. 19 tests with httptest mock OAuth2 + CAS API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shankar0123
2026-04-03 21:25:34 -04:00
parent cb72292b83
commit 5a53b648b1
12 changed files with 1608 additions and 7 deletions
+18
View File
@@ -22,6 +22,7 @@ import (
digicertissuer "github.com/shankar0123/certctl/internal/connector/issuer/digicert"
opensslissuer "github.com/shankar0123/certctl/internal/connector/issuer/openssl"
stepcaissuer "github.com/shankar0123/certctl/internal/connector/issuer/stepca"
googlecasissuer "github.com/shankar0123/certctl/internal/connector/issuer/googlecas"
sectigoissuer "github.com/shankar0123/certctl/internal/connector/issuer/sectigo"
vaultissuer "github.com/shankar0123/certctl/internal/connector/issuer/vault"
notifyemail "github.com/shankar0123/certctl/internal/connector/notifier/email"
@@ -172,6 +173,17 @@ func main() {
}, logger)
logger.Info("initialized Sectigo SCM issuer connector")
// Initialize Google CAS issuer connector (for GCP private CA).
// Uses the Google CAS REST API with OAuth2 service account auth.
googlecasConnector := googlecasissuer.New(&googlecasissuer.Config{
Project: cfg.GoogleCAS.Project,
Location: cfg.GoogleCAS.Location,
CAPool: cfg.GoogleCAS.CAPool,
Credentials: cfg.GoogleCAS.Credentials,
TTL: cfg.GoogleCAS.TTL,
}, logger)
logger.Info("initialized Google CAS issuer connector")
// Build issuer registry: maps issuer IDs (from database) to connector implementations.
// "iss-local" matches the seed data issuer ID for the Local CA.
// "iss-acme-staging" and "iss-acme-prod" are conventional IDs for ACME issuers.
@@ -203,6 +215,12 @@ func main() {
logger.Info("Sectigo SCM issuer registered", "id", "iss-sectigo")
}
// Conditionally register Google CAS (only if project and credentials are set)
if cfg.GoogleCAS.Project != "" && cfg.GoogleCAS.Credentials != "" {
issuerRegistry["iss-googlecas"] = service.NewIssuerConnectorAdapter(googlecasConnector)
logger.Info("Google CAS issuer registered", "id", "iss-googlecas")
}
logger.Info("issuer registry configured", "issuers", len(issuerRegistry))
// Initialize revocation repository