mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-11 10:49:05 +00:00
Revert "chore: drop 'Infisical' label from internal references"
This reverts commit 19706e56b3.
This commit is contained in:
@@ -947,7 +947,7 @@ func TestCreateTargetConnector_AllSupportedTypes(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable.
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
// Region must be a valid AWS region; the connector lazy-loads
|
// Region must be a valid AWS region; the connector lazy-loads
|
||||||
// the SDK client during ValidateConfig but New() with a populated
|
// the SDK client during ValidateConfig but New() with a populated
|
||||||
// region should succeed against the SDK credential chain
|
// region should succeed against the SDK credential chain
|
||||||
|
|||||||
+2
-2
@@ -907,7 +907,7 @@ func (a *Agent) createTargetConnector(ctx context.Context, targetType string, co
|
|||||||
return k8s.New(&cfg, a.logger)
|
return k8s.New(&cfg, a.logger)
|
||||||
|
|
||||||
case "AWSACM":
|
case "AWSACM":
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable.
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
// AWS Certificate Manager target — SDK-driven (no file I/O).
|
// AWS Certificate Manager target — SDK-driven (no file I/O).
|
||||||
// LoadDefaultConfig handles the standard AWS credential chain
|
// LoadDefaultConfig handles the standard AWS credential chain
|
||||||
// (IRSA / EC2 instance profile / SSO / env vars) without any
|
// (IRSA / EC2 instance profile / SSO / env vars) without any
|
||||||
@@ -921,7 +921,7 @@ func (a *Agent) createTargetConnector(ctx context.Context, targetType string, co
|
|||||||
return awsacm.New(ctx, &cfg, a.logger)
|
return awsacm.New(ctx, &cfg, a.logger)
|
||||||
|
|
||||||
case "AzureKeyVault":
|
case "AzureKeyVault":
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable.
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
// Azure Key Vault target — SDK-driven (no file I/O).
|
// Azure Key Vault target — SDK-driven (no file I/O).
|
||||||
// DefaultAzureCredential handles the standard Azure credential
|
// DefaultAzureCredential handles the standard Azure credential
|
||||||
// chain (managed identity / workload identity / env vars / az
|
// chain (managed identity / workload identity / env vars / az
|
||||||
|
|||||||
+5
-5
@@ -268,7 +268,7 @@ func main() {
|
|||||||
transactor := postgres.NewTransactor(db)
|
transactor := postgres.NewTransactor(db)
|
||||||
certificateService.SetTransactor(transactor)
|
certificateService.SetTransactor(transactor)
|
||||||
|
|
||||||
// Rank 7 of the 2026-05-03 deep-research deliverable —
|
// Rank 7 of the 2026-05-03 Infisical deep-research deliverable —
|
||||||
// issuance approval-workflow primitive. ApprovalRepository +
|
// issuance approval-workflow primitive. ApprovalRepository +
|
||||||
// ApprovalMetrics + ApprovalService construct here; the gate is
|
// ApprovalMetrics + ApprovalService construct here; the gate is
|
||||||
// activated on CertificateService via SetApprovalService +
|
// activated on CertificateService via SetApprovalService +
|
||||||
@@ -344,8 +344,8 @@ func main() {
|
|||||||
notificationService := service.NewNotificationService(notificationRepo, notifierRegistry)
|
notificationService := service.NewNotificationService(notificationRepo, notifierRegistry)
|
||||||
notificationService.SetOwnerRepo(ownerRepo)
|
notificationService.SetOwnerRepo(ownerRepo)
|
||||||
|
|
||||||
// Rank 4 of the 2026-05-03 deep-research deliverable
|
// Rank 4 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Per-policy
|
// (cowork/infisical-deep-research-results.md Part 5). Per-policy
|
||||||
// multi-channel expiry-alert metrics. Same instance is wired into
|
// multi-channel expiry-alert metrics. Same instance is wired into
|
||||||
// the notification service (recording side, every
|
// the notification service (recording side, every
|
||||||
// SendThresholdAlertOnChannel call reports its outcome) AND into
|
// SendThresholdAlertOnChannel call reports its outcome) AND into
|
||||||
@@ -626,7 +626,7 @@ func main() {
|
|||||||
// Top-10 fix #5 (2026-05-03 audit): Vault PKI token-renewal counter.
|
// Top-10 fix #5 (2026-05-03 audit): Vault PKI token-renewal counter.
|
||||||
// Same instance the registry uses to record per-tick results.
|
// Same instance the registry uses to record per-tick results.
|
||||||
metricsHandler.SetVaultRenewals(vaultRenewalMetrics)
|
metricsHandler.SetVaultRenewals(vaultRenewalMetrics)
|
||||||
// Rank 4 of the 2026-05-03 deep-research deliverable:
|
// Rank 4 of the 2026-05-03 Infisical deep-research deliverable:
|
||||||
// per-policy multi-channel expiry-alert counter. Same instance the
|
// per-policy multi-channel expiry-alert counter. Same instance the
|
||||||
// notification service uses to record per-(channel, threshold,
|
// notification service uses to record per-(channel, threshold,
|
||||||
// result) outcomes.
|
// result) outcomes.
|
||||||
@@ -927,7 +927,7 @@ func main() {
|
|||||||
// docs/acme-server.md for the operator-facing reference.
|
// docs/acme-server.md for the operator-facing reference.
|
||||||
ACME: acmeHandler,
|
ACME: acmeHandler,
|
||||||
// Approvals — issuance approval-workflow primitive. Rank 7 of
|
// Approvals — issuance approval-workflow primitive. Rank 7 of
|
||||||
// the 2026-05-03 deep-research deliverable. See
|
// the 2026-05-03 Infisical deep-research deliverable. See
|
||||||
// docs/approval-workflow.md.
|
// docs/approval-workflow.md.
|
||||||
Approvals: approvalHandler,
|
Approvals: approvalHandler,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
certctl can gate certificate issuance + renewal on a per-profile, two-person-integrity check. Compliance customers (PCI-DSS Level 1, FedRAMP Moderate / High, SOC 2 Type II, HIPAA) configure this on production-tier `CertificateProfile` rows so every renewal-loop tick or manual `POST /api/v1/certificates/{id}/renew` blocks at `JobStatusAwaitingApproval` until a different actor approves.
|
certctl can gate certificate issuance + renewal on a per-profile, two-person-integrity check. Compliance customers (PCI-DSS Level 1, FedRAMP Moderate / High, SOC 2 Type II, HIPAA) configure this on production-tier `CertificateProfile` rows so every renewal-loop tick or manual `POST /api/v1/certificates/{id}/renew` blocks at `JobStatusAwaitingApproval` until a different actor approves.
|
||||||
|
|
||||||
Rank 7 of the 2026-05-03 deep-research deliverable. Closes the procurement-checklist question "How do you enforce two-person integrity on cert issuance?" — pre-Rank-7 the answer was "we don't"; post-Rank-7 the answer is "set `requires_approval=true` on the profile + here's the audit query that proves bypass mode is off in production."
|
Rank 7 of the 2026-05-03 Infisical deep-research deliverable. Closes the procurement-checklist question "How do you enforce two-person integrity on cert issuance?" — pre-Rank-7 the answer was "we don't"; post-Rank-7 the answer is "set `requires_approval=true` on the profile + here's the audit query that proves bypass mode is off in production."
|
||||||
|
|
||||||
## End-to-end flow
|
## End-to-end flow
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1411,7 +1411,7 @@ Location: `internal/connector/target/k8ssecret/k8ssecret.go`
|
|||||||
|
|
||||||
### AWS Certificate Manager (ACM)
|
### AWS Certificate Manager (ACM)
|
||||||
|
|
||||||
The AWS ACM target connector deploys certificates into AWS Certificate Manager — the public AWS service that ALB / CloudFront / API Gateway / App Runner consume by ARN. Closes the "we terminate TLS at AWS, how do we get certctl-issued certs to ALB?" question for cloud-first deployments. Rank 5 of the 2026-05-03 deep-research deliverable.
|
The AWS ACM target connector deploys certificates into AWS Certificate Manager — the public AWS service that ALB / CloudFront / API Gateway / App Runner consume by ARN. Closes the "we terminate TLS at AWS, how do we get certctl-issued certs to ALB?" question for cloud-first deployments. Rank 5 of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -1506,7 +1506,7 @@ Location: `internal/connector/target/awsacm/awsacm.go` + `internal/connector/tar
|
|||||||
|
|
||||||
### Azure Key Vault
|
### Azure Key Vault
|
||||||
|
|
||||||
The Azure Key Vault target connector deploys certificates into Azure Key Vault — the Azure-managed cert/secret store that Application Gateway / Front Door / App Service / Container Apps consume by KID URI. Rank 5 (Azure half) of the 2026-05-03 deep-research deliverable.
|
The Azure Key Vault target connector deploys certificates into Azure Key Vault — the Azure-managed cert/secret store that Application Gateway / Front Door / App Service / Container Apps consume by KID URI. Rank 5 (Azure half) of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -1619,7 +1619,7 @@ Built-in notifiers: **Email** (SMTP), **Webhook** (HTTP POST), **Slack** (incomi
|
|||||||
|
|
||||||
### Routing expiry alerts across channels
|
### Routing expiry alerts across channels
|
||||||
|
|
||||||
certctl-server runs a daily renewal-check loop that scans for managed certificates approaching expiry. For each cert that has crossed a configured threshold (default `[30, 14, 7, 0]` days), an `ExpirationWarning` notification is dispatched. **Pre-2026-05-03**, dispatch went exclusively via the `Email` channel — operators with PagerDuty / Slack / Teams / OpsGenie wired up received nothing at any threshold unless SMTP was also configured. Rank 4 of the 2026-05-03 deep-research deliverable closed that gap with a per-policy channel-matrix.
|
certctl-server runs a daily renewal-check loop that scans for managed certificates approaching expiry. For each cert that has crossed a configured threshold (default `[30, 14, 7, 0]` days), an `ExpirationWarning` notification is dispatched. **Pre-2026-05-03**, dispatch went exclusively via the `Email` channel — operators with PagerDuty / Slack / Teams / OpsGenie wired up received nothing at any threshold unless SMTP was also configured. Rank 4 of the 2026-05-03 Infisical deep-research deliverable closed that gap with a per-policy channel-matrix.
|
||||||
|
|
||||||
**The matrix lives on `RenewalPolicy`:**
|
**The matrix lives on `RenewalPolicy`:**
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Runbook: cloud-target deployment connectors (AWS ACM + Azure Key Vault)
|
# Runbook: cloud-target deployment connectors (AWS ACM + Azure Key Vault)
|
||||||
|
|
||||||
This runbook covers the SDK-driven cloud target connectors that ship in
|
This runbook covers the SDK-driven cloud target connectors that ship in
|
||||||
certctl post-2026-05-03 (Rank 5 of the deep-research
|
certctl post-2026-05-03 (Rank 5 of the Infisical deep-research
|
||||||
deliverable). It complements the operator-facing
|
deliverable). It complements the operator-facing
|
||||||
[AWS Certificate Manager](connectors.md#aws-certificate-manager-acm) and
|
[AWS Certificate Manager](connectors.md#aws-certificate-manager-acm) and
|
||||||
[Azure Key Vault](connectors.md#azure-key-vault) sections in
|
[Azure Key Vault](connectors.md#azure-key-vault) sections in
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Runbook: certificate-expiry alerts (multi-channel)
|
# Runbook: certificate-expiry alerts (multi-channel)
|
||||||
|
|
||||||
This runbook covers the per-policy multi-channel expiry-alert dispatch
|
This runbook covers the per-policy multi-channel expiry-alert dispatch
|
||||||
path that ships in certctl post-2026-05-03 (Rank 4 of the deep-research
|
path that ships in certctl post-2026-05-03 (Rank 4 of the Infisical
|
||||||
deep-research deliverable). It complements the operator-facing
|
deep-research deliverable). It complements the operator-facing
|
||||||
[Routing expiry alerts across channels](connectors.md#routing-expiry-alerts-across-channels)
|
[Routing expiry alerts across channels](connectors.md#routing-expiry-alerts-across-channels)
|
||||||
section in `docs/connectors.md`.
|
section in `docs/connectors.md`.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
// inversion) so the handler stays decoupled from the concrete
|
// inversion) so the handler stays decoupled from the concrete
|
||||||
// *service.ApprovalService.
|
// *service.ApprovalService.
|
||||||
//
|
//
|
||||||
// Rank 7 of the 2026-05-03 deep-research deliverable, commit 3
|
// Rank 7 of the 2026-05-03 Infisical deep-research deliverable, commit 3
|
||||||
// of 4 — the API + RBAC layer.
|
// of 4 — the API + RBAC layer.
|
||||||
type ApprovalServicer interface {
|
type ApprovalServicer interface {
|
||||||
Approve(ctx context.Context, requestID, decidedBy, note string) error
|
Approve(ctx context.Context, requestID, decidedBy, note string) error
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ type VaultRenewalSnapshotter interface {
|
|||||||
// (via NotificationService.SetExpiryAlertMetrics) and exposing
|
// (via NotificationService.SetExpiryAlertMetrics) and exposing
|
||||||
// (here).
|
// (here).
|
||||||
//
|
//
|
||||||
// Rank 4 of the 2026-05-03 deep-research deliverable
|
// Rank 4 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5).
|
// (cowork/infisical-deep-research-results.md Part 5).
|
||||||
type ExpiryAlertSnapshotter interface {
|
type ExpiryAlertSnapshotter interface {
|
||||||
// SnapshotExpiryAlerts returns one entry per non-zero counter,
|
// SnapshotExpiryAlerts returns one entry per non-zero counter,
|
||||||
// pre-sorted by (channel, threshold, result) so the Prometheus
|
// pre-sorted by (channel, threshold, result) so the Prometheus
|
||||||
@@ -123,7 +123,7 @@ type MetricsHandler struct {
|
|||||||
// certctl_vault_token_renewals_total{result=...}.
|
// certctl_vault_token_renewals_total{result=...}.
|
||||||
vaultRenewals VaultRenewalSnapshotter
|
vaultRenewals VaultRenewalSnapshotter
|
||||||
// Per-policy multi-channel expiry alert counters. Rank 4 of the
|
// Per-policy multi-channel expiry alert counters. Rank 4 of the
|
||||||
// 2026-05-03 deep-research deliverable. nil disables
|
// 2026-05-03 Infisical deep-research deliverable. nil disables
|
||||||
// emission of certctl_expiry_alerts_total{channel,threshold,result}.
|
// emission of certctl_expiry_alerts_total{channel,threshold,result}.
|
||||||
expiryAlerts ExpiryAlertSnapshotter
|
expiryAlerts ExpiryAlertSnapshotter
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ func (h *MetricsHandler) SetVaultRenewals(c VaultRenewalSnapshotter) {
|
|||||||
|
|
||||||
// SetExpiryAlerts wires the per-policy multi-channel expiry-alert
|
// SetExpiryAlerts wires the per-policy multi-channel expiry-alert
|
||||||
// counter table for the Prometheus exposition. nil disables the
|
// counter table for the Prometheus exposition. nil disables the
|
||||||
// block. Closes Rank 4 of the 2026-05-03 deep-research
|
// block. Closes Rank 4 of the 2026-05-03 Infisical deep-research
|
||||||
// deliverable.
|
// deliverable.
|
||||||
func (h *MetricsHandler) SetExpiryAlerts(c ExpiryAlertSnapshotter) {
|
func (h *MetricsHandler) SetExpiryAlerts(c ExpiryAlertSnapshotter) {
|
||||||
h.expiryAlerts = c
|
h.expiryAlerts = c
|
||||||
@@ -502,7 +502,7 @@ func (h MetricsHandler) GetPrometheusMetrics(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Per-policy multi-channel expiry-alert counters. Rank 4 of the
|
// Per-policy multi-channel expiry-alert counters. Rank 4 of the
|
||||||
// 2026-05-03 deep-research deliverable. Operators alert
|
// 2026-05-03 Infisical deep-research deliverable. Operators alert
|
||||||
// on certctl_expiry_alerts_total{result="failure"} > 0 to catch
|
// on certctl_expiry_alerts_total{result="failure"} > 0 to catch
|
||||||
// when a notifier connector (PagerDuty / Slack / etc.) is
|
// when a notifier connector (PagerDuty / Slack / etc.) is
|
||||||
// rejecting our sends. Cardinality: 6 channels × N thresholds × 3
|
// rejecting our sends. Cardinality: 6 channels × N thresholds × 3
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ type HandlerRegistry struct {
|
|||||||
ACME handler.ACMEHandler
|
ACME handler.ACMEHandler
|
||||||
|
|
||||||
// Approvals handles the issuance approval-workflow endpoints under
|
// Approvals handles the issuance approval-workflow endpoints under
|
||||||
// /api/v1/approvals/*. Rank 7 of the 2026-05-03 deep-research deliverable — closes the two-person integrity / four-eyes
|
// /api/v1/approvals/*. Rank 7 of the 2026-05-03 Infisical deep-
|
||||||
|
// research deliverable — closes the two-person integrity / four-eyes
|
||||||
// principle procurement gap. Routes:
|
// principle procurement gap. Routes:
|
||||||
// GET /api/v1/approvals
|
// GET /api/v1/approvals
|
||||||
// GET /api/v1/approvals/{id}
|
// GET /api/v1/approvals/{id}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ type Config struct {
|
|||||||
Verification VerificationConfig
|
Verification VerificationConfig
|
||||||
ACME ACMEConfig
|
ACME ACMEConfig
|
||||||
// Approval is the issuance approval-workflow primitive's runtime
|
// Approval is the issuance approval-workflow primitive's runtime
|
||||||
// config. Rank 7 of the 2026-05-03 deep-research
|
// config. Rank 7 of the 2026-05-03 Infisical deep-research
|
||||||
// deliverable. The single field — BypassEnabled — short-circuits
|
// deliverable. The single field — BypassEnabled — short-circuits
|
||||||
// the workflow for dev/CI; production deploys MUST leave it false.
|
// the workflow for dev/CI; production deploys MUST leave it false.
|
||||||
Approval ApprovalConfig
|
Approval ApprovalConfig
|
||||||
@@ -1431,7 +1431,7 @@ type SchedulerConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ApprovalConfig contains issuance approval-workflow runtime configuration.
|
// ApprovalConfig contains issuance approval-workflow runtime configuration.
|
||||||
// Rank 7 of the 2026-05-03 deep-research deliverable.
|
// Rank 7 of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
type ApprovalConfig struct {
|
type ApprovalConfig struct {
|
||||||
// BypassEnabled short-circuits the approval workflow — every
|
// BypassEnabled short-circuits the approval workflow — every
|
||||||
// RequestApproval call auto-approves with decidedBy="system-bypass"
|
// RequestApproval call auto-approves with decidedBy="system-bypass"
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
// on mismatch (or any post-verify failure) the connector re-imports the
|
// on mismatch (or any post-verify failure) the connector re-imports the
|
||||||
// snapshot bytes to restore the previous cert. Mirrors the Bundle 5+
|
// snapshot bytes to restore the previous cert. Mirrors the Bundle 5+
|
||||||
// pre-deploy-snapshot + on-failure-restore pattern from IIS / WinCertStore /
|
// pre-deploy-snapshot + on-failure-restore pattern from IIS / WinCertStore /
|
||||||
// JavaKeystore. Rank 5 of the 2026-05-03 deep-research
|
// JavaKeystore. Rank 5 of the 2026-05-03 Infisical deep-research
|
||||||
// deliverable (cowork/deep-research-results-2026-05-03.md Part 5).
|
// deliverable (cowork/infisical-deep-research-results.md Part 5).
|
||||||
//
|
//
|
||||||
// IAM permissions required:
|
// IAM permissions required:
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package awsacm_test
|
package awsacm_test
|
||||||
|
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Per-error-class
|
// (cowork/infisical-deep-research-results.md Part 5). Per-error-class
|
||||||
// failure tests for the AWS ACM target connector — mirrors the
|
// failure tests for the AWS ACM target connector — mirrors the
|
||||||
// awsacmpca_failure_test.go shape (commit 60dce0b) on the issuer side.
|
// awsacmpca_failure_test.go shape (commit 60dce0b) on the issuer side.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package awsacm_test
|
package awsacm_test
|
||||||
|
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Happy-path table-
|
// (cowork/infisical-deep-research-results.md Part 5). Happy-path table-
|
||||||
// driven tests for the AWS ACM target connector. Mirrors the
|
// driven tests for the AWS ACM target connector. Mirrors the
|
||||||
// k8ssecret_test.go ergonomics + the Bundle 5+ atomic-rollback
|
// k8ssecret_test.go ergonomics + the Bundle 5+ atomic-rollback
|
||||||
// assertions from IIS / WinCertStore / JavaKeystore.
|
// assertions from IIS / WinCertStore / JavaKeystore.
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
// is the safe default — recovery requires acm:RecoverDeletedCertificate
|
// is the safe default — recovery requires acm:RecoverDeletedCertificate
|
||||||
// permission which we deliberately keep off the minimum-RBAC surface.
|
// permission which we deliberately keep off the minimum-RBAC surface.
|
||||||
//
|
//
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5).
|
// (cowork/infisical-deep-research-results.md Part 5).
|
||||||
//
|
//
|
||||||
// Required Azure RBAC (minimum):
|
// Required Azure RBAC (minimum):
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package azurekv_test
|
package azurekv_test
|
||||||
|
|
||||||
// Rank 5 of the 2026-05-03 deep-research deliverable
|
// Rank 5 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Happy-path tests
|
// (cowork/infisical-deep-research-results.md Part 5). Happy-path tests
|
||||||
// for the Azure Key Vault target connector. Mirrors the awsacm_test.go
|
// for the Azure Key Vault target connector. Mirrors the awsacm_test.go
|
||||||
// shape so cross-cloud regressions are bisectable side-by-side.
|
// shape so cross-cloud regressions are bisectable side-by-side.
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import "time"
|
|||||||
// Once terminal, the row is immutable; the audit_events table is the
|
// Once terminal, the row is immutable; the audit_events table is the
|
||||||
// durable record of who approved + why.
|
// durable record of who approved + why.
|
||||||
//
|
//
|
||||||
// Rank 7 of the 2026-05-03 deep-research deliverable
|
// Rank 7 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Closes the
|
// (cowork/infisical-deep-research-results.md Part 5). Closes the
|
||||||
// "two-person integrity / four-eyes principle" procurement gap for
|
// "two-person integrity / four-eyes principle" procurement gap for
|
||||||
// PCI-DSS Level 1, FedRAMP Moderate / High, and SOC 2 Type II
|
// PCI-DSS Level 1, FedRAMP Moderate / High, and SOC 2 Type II
|
||||||
// customers.
|
// customers.
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ type RenewalPolicy struct {
|
|||||||
// the dispatch site (closed-enum discipline; we do NOT dynamically
|
// the dispatch site (closed-enum discipline; we do NOT dynamically
|
||||||
// grow Prometheus cardinality on a typo).
|
// grow Prometheus cardinality on a typo).
|
||||||
//
|
//
|
||||||
// Rank 4 of the 2026-05-03 deep-research deliverable
|
// Rank 4 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5).
|
// (cowork/infisical-deep-research-results.md Part 5).
|
||||||
AlertChannels map[string][]string `json:"alert_channels,omitempty"`
|
AlertChannels map[string][]string `json:"alert_channels,omitempty"`
|
||||||
|
|
||||||
// AlertSeverityMap maps each threshold-day value to its severity
|
// AlertSeverityMap maps each threshold-day value to its severity
|
||||||
|
|||||||
@@ -215,8 +215,8 @@ const (
|
|||||||
// TargetTypeAWSACM deploys certificates to AWS Certificate Manager
|
// TargetTypeAWSACM deploys certificates to AWS Certificate Manager
|
||||||
// (ACM) — the public AWS service that ALB / CloudFront / API
|
// (ACM) — the public AWS service that ALB / CloudFront / API
|
||||||
// Gateway / App Runner consume by ARN. Rank 5 of the 2026-05-03
|
// Gateway / App Runner consume by ARN. Rank 5 of the 2026-05-03
|
||||||
// deep-research deliverable
|
// Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). See
|
// (cowork/infisical-deep-research-results.md Part 5). See
|
||||||
// docs/connectors.md "AWS Certificate Manager" section for the
|
// docs/connectors.md "AWS Certificate Manager" section for the
|
||||||
// operator playbook including minimum IAM policy + atomic-rollback
|
// operator playbook including minimum IAM policy + atomic-rollback
|
||||||
// contract.
|
// contract.
|
||||||
@@ -224,7 +224,7 @@ const (
|
|||||||
// TargetTypeAzureKeyVault deploys certificates to Azure Key Vault —
|
// TargetTypeAzureKeyVault deploys certificates to Azure Key Vault —
|
||||||
// the Azure-managed cert store that Application Gateway / Front
|
// the Azure-managed cert store that Application Gateway / Front
|
||||||
// Door / App Service / Container Apps consume by KID URI. Rank 5
|
// Door / App Service / Container Apps consume by KID URI. Rank 5
|
||||||
// of the 2026-05-03 deep-research deliverable. See
|
// of the 2026-05-03 Infisical deep-research deliverable. See
|
||||||
// docs/connectors.md "Azure Key Vault" for the operator playbook
|
// docs/connectors.md "Azure Key Vault" for the operator playbook
|
||||||
// including minimum RBAC role + atomic-rollback + Azure-version
|
// including minimum RBAC role + atomic-rollback + Azure-version
|
||||||
// semantics.
|
// semantics.
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ type CertificateProfile struct {
|
|||||||
//
|
//
|
||||||
// Backed by certificate_profiles.requires_approval added in
|
// Backed by certificate_profiles.requires_approval added in
|
||||||
// migration 000027_approval_workflow. Rank 7 of the 2026-05-03
|
// migration 000027_approval_workflow. Rank 7 of the 2026-05-03
|
||||||
// deep-research deliverable.
|
// Infisical deep-research deliverable.
|
||||||
RequiresApproval bool `json:"requires_approval,omitempty"`
|
RequiresApproval bool `json:"requires_approval,omitempty"`
|
||||||
|
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
|
|||||||
@@ -715,7 +715,7 @@ type HealthCheckFilter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ApprovalRepository defines operations for managing issuance approval requests.
|
// ApprovalRepository defines operations for managing issuance approval requests.
|
||||||
// Rank 7 of the 2026-05-03 deep-research deliverable — closes the
|
// Rank 7 of the 2026-05-03 Infisical deep-research deliverable — closes the
|
||||||
// two-person integrity / four-eyes principle procurement gap for PCI-DSS
|
// two-person integrity / four-eyes principle procurement gap for PCI-DSS
|
||||||
// Level 1, FedRAMP Moderate / High, SOC 2 Type II, HIPAA-regulated PHI.
|
// Level 1, FedRAMP Moderate / High, SOC 2 Type II, HIPAA-regulated PHI.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ApprovalRepository is the postgres implementation of
|
// ApprovalRepository is the postgres implementation of
|
||||||
// repository.ApprovalRepository. Rank 7 of the 2026-05-03 deep-research
|
// repository.ApprovalRepository. Rank 7 of the 2026-05-03 Infisical
|
||||||
// deep-research deliverable.
|
// deep-research deliverable.
|
||||||
type ApprovalRepository struct {
|
type ApprovalRepository struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func NewRenewalPolicyRepository(db *sql.DB) *RenewalPolicyRepository {
|
|||||||
//
|
//
|
||||||
// alert_channels / alert_severity_map (migration 000026) ARE read here —
|
// alert_channels / alert_severity_map (migration 000026) ARE read here —
|
||||||
// they're the per-policy channel matrix that drives multi-channel expiry
|
// they're the per-policy channel matrix that drives multi-channel expiry
|
||||||
// alert routing (Rank 4 of the 2026-05-03 deep-research
|
// alert routing (Rank 4 of the 2026-05-03 Infisical deep-research
|
||||||
// deliverable). Both default to '{}' at the DB level; scanRenewalPolicy
|
// deliverable). Both default to '{}' at the DB level; scanRenewalPolicy
|
||||||
// unmarshals an empty map into nil so domain.EffectiveAlertChannels /
|
// unmarshals an empty map into nil so domain.EffectiveAlertChannels /
|
||||||
// EffectiveAlertSeverityMap fall through to the back-compat defaults.
|
// EffectiveAlertSeverityMap fall through to the back-compat defaults.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ApprovalService manages the issuance approval-workflow primitive.
|
// ApprovalService manages the issuance approval-workflow primitive.
|
||||||
// Rank 7 of the 2026-05-03 deep-research deliverable.
|
// Rank 7 of the 2026-05-03 Infisical deep-research deliverable.
|
||||||
//
|
//
|
||||||
// Lifecycle: a profile with RequiresApproval=true causes the renewal
|
// Lifecycle: a profile with RequiresApproval=true causes the renewal
|
||||||
// entry points (TriggerRenewal + CheckExpiringCertificates) to call
|
// entry points (TriggerRenewal + CheckExpiringCertificates) to call
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ApprovalMetrics is a thread-safe counter table for the issuance
|
// ApprovalMetrics is a thread-safe counter table for the issuance
|
||||||
// approval-workflow dispatch path. Rank 7 of the 2026-05-03 deep-research
|
// approval-workflow dispatch path. Rank 7 of the 2026-05-03 Infisical
|
||||||
// deep-research deliverable. Mirrors the ExpiryAlertMetrics +
|
// deep-research deliverable. Mirrors the ExpiryAlertMetrics +
|
||||||
// VaultRenewalMetrics shape: cmd/server/main.go constructs ONE instance,
|
// VaultRenewalMetrics shape: cmd/server/main.go constructs ONE instance,
|
||||||
// passes it to ApprovalService (recording side) AND metricsHandler
|
// passes it to ApprovalService (recording side) AND metricsHandler
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type CertificateService struct {
|
|||||||
// a parallel ApprovalRequest row is created via approvalSvc. The
|
// a parallel ApprovalRequest row is created via approvalSvc. The
|
||||||
// scheduler does NOT dispatch until ApprovalService.Approve
|
// scheduler does NOT dispatch until ApprovalService.Approve
|
||||||
// transitions the job to Pending. Rank 7 of the 2026-05-03
|
// transitions the job to Pending. Rank 7 of the 2026-05-03
|
||||||
// deep-research deliverable. Both setters are optional —
|
// Infisical deep-research deliverable. Both setters are optional —
|
||||||
// when either is nil, gating is skipped and TriggerRenewal falls
|
// when either is nil, gating is skipped and TriggerRenewal falls
|
||||||
// back to the historical unattended path.
|
// back to the historical unattended path.
|
||||||
approvalSvc *ApprovalService
|
approvalSvc *ApprovalService
|
||||||
@@ -107,7 +107,7 @@ func (s *CertificateService) SetKeygenMode(mode string) {
|
|||||||
|
|
||||||
// SetApprovalService wires the approval-workflow service. When both this
|
// SetApprovalService wires the approval-workflow service. When both this
|
||||||
// and SetProfileRepo are wired, TriggerRenewal gates on
|
// and SetProfileRepo are wired, TriggerRenewal gates on
|
||||||
// CertificateProfile.RequiresApproval. Rank 7 of the 2026-05-03 deep-research
|
// CertificateProfile.RequiresApproval. Rank 7 of the 2026-05-03 Infisical
|
||||||
// deep-research deliverable.
|
// deep-research deliverable.
|
||||||
func (s *CertificateService) SetApprovalService(svc *ApprovalService) {
|
func (s *CertificateService) SetApprovalService(svc *ApprovalService) {
|
||||||
s.approvalSvc = svc
|
s.approvalSvc = svc
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
// ExpiryAlertMetrics is a thread-safe counter table for the per-policy
|
// ExpiryAlertMetrics is a thread-safe counter table for the per-policy
|
||||||
// multi-channel expiry-alert dispatch path. Rank 4 of the 2026-05-03
|
// multi-channel expiry-alert dispatch path. Rank 4 of the 2026-05-03
|
||||||
// deep-research deliverable
|
// Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Closes the
|
// (cowork/infisical-deep-research-results.md Part 5). Closes the
|
||||||
// procurement-checklist gap where a customer who configured PagerDuty
|
// procurement-checklist gap where a customer who configured PagerDuty
|
||||||
// for cert-expiry pages got silent nothing — ExpirationWarning shipped
|
// for cert-expiry pages got silent nothing — ExpirationWarning shipped
|
||||||
// only to Email pre-fix.
|
// only to Email pre-fix.
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ type NotificationService struct {
|
|||||||
// to SendThresholdAlertOnChannel reports its outcome (success / failure)
|
// to SendThresholdAlertOnChannel reports its outcome (success / failure)
|
||||||
// to the metric sink so the Prometheus exposer surfaces
|
// to the metric sink so the Prometheus exposer surfaces
|
||||||
// certctl_expiry_alerts_total{channel,threshold,result}. Rank 4 of the
|
// certctl_expiry_alerts_total{channel,threshold,result}. Rank 4 of the
|
||||||
// 2026-05-03 deep-research deliverable. Nil leaves the
|
// 2026-05-03 Infisical deep-research deliverable. Nil leaves the
|
||||||
// dispatch path unchanged (no metric emission, but alerts still fire).
|
// dispatch path unchanged (no metric emission, but alerts still fire).
|
||||||
expiryAlertMetrics ExpiryAlertRecorder
|
expiryAlertMetrics ExpiryAlertRecorder
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ func (s *NotificationService) SendExpirationWarning(ctx context.Context, cert *d
|
|||||||
//
|
//
|
||||||
// Policy-driven dispatch in RenewalService.sendThresholdAlerts uses
|
// Policy-driven dispatch in RenewalService.sendThresholdAlerts uses
|
||||||
// SendThresholdAlertOnChannel directly with the channel resolved from the
|
// SendThresholdAlertOnChannel directly with the channel resolved from the
|
||||||
// per-policy AlertChannels matrix. Rank 4 of the 2026-05-03 deep-research
|
// per-policy AlertChannels matrix. Rank 4 of the 2026-05-03 Infisical
|
||||||
// deep-research deliverable.
|
// deep-research deliverable.
|
||||||
func (s *NotificationService) SendThresholdAlert(ctx context.Context, cert *domain.ManagedCertificate, daysUntilExpiry int, threshold int) error {
|
func (s *NotificationService) SendThresholdAlert(ctx context.Context, cert *domain.ManagedCertificate, daysUntilExpiry int, threshold int) error {
|
||||||
return s.SendThresholdAlertOnChannel(ctx, cert, daysUntilExpiry, threshold, domain.NotificationChannelEmail)
|
return s.SendThresholdAlertOnChannel(ctx, cert, daysUntilExpiry, threshold, domain.NotificationChannelEmail)
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ func (s *RenewalService) CheckExpiringCertificates(ctx context.Context) error {
|
|||||||
// policy pointer (nil-safe) drives the per-(threshold) channel
|
// policy pointer (nil-safe) drives the per-(threshold) channel
|
||||||
// matrix; nil policy or empty AlertChannels falls through to the
|
// matrix; nil policy or empty AlertChannels falls through to the
|
||||||
// back-compat Email-only default. Rank 4 of the 2026-05-03
|
// back-compat Email-only default. Rank 4 of the 2026-05-03
|
||||||
// deep-research deliverable.
|
// Infisical deep-research deliverable.
|
||||||
var policyPtr *domain.RenewalPolicy
|
var policyPtr *domain.RenewalPolicy
|
||||||
if cert.RenewalPolicyID != "" {
|
if cert.RenewalPolicyID != "" {
|
||||||
policyPtr = policyCache[cert.RenewalPolicyID]
|
policyPtr = policyCache[cert.RenewalPolicyID]
|
||||||
@@ -323,8 +323,8 @@ func (s *RenewalService) CheckExpiringCertificates(ctx context.Context) error {
|
|||||||
// AND metadata->>'channel' = 'PagerDuty' to answer "did the on-call
|
// AND metadata->>'channel' = 'PagerDuty' to answer "did the on-call
|
||||||
// team get paged?".
|
// team get paged?".
|
||||||
//
|
//
|
||||||
// Rank 4 of the 2026-05-03 deep-research deliverable
|
// Rank 4 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). The policy
|
// (cowork/infisical-deep-research-results.md Part 5). The policy
|
||||||
// argument is nil-safe — a cert with no RenewalPolicy attached gets the
|
// argument is nil-safe — a cert with no RenewalPolicy attached gets the
|
||||||
// back-compat Email-only default matrix.
|
// back-compat Email-only default matrix.
|
||||||
func (s *RenewalService) sendThresholdAlerts(
|
func (s *RenewalService) sendThresholdAlerts(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
// Rank 4 of the 2026-05-03 deep-research deliverable
|
// Rank 4 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
// (cowork/deep-research-results-2026-05-03.md Part 5). Pins every leg of
|
// (cowork/infisical-deep-research-results.md Part 5). Pins every leg of
|
||||||
// the per-policy multi-channel expiry-alert fan-out matrix:
|
// the per-policy multi-channel expiry-alert fan-out matrix:
|
||||||
//
|
//
|
||||||
// 1. Default matrix → Email-only at every tier (back-compat).
|
// 1. Default matrix → Email-only at every tier (back-compat).
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ func (m *mockNotifRepo) List(ctx context.Context, filter *repository.Notificatio
|
|||||||
// Apply each non-zero filter field. Mirror the postgres notification
|
// Apply each non-zero filter field. Mirror the postgres notification
|
||||||
// repo's WHERE-clause shape (CertificateID, Type, Status, Channel,
|
// repo's WHERE-clause shape (CertificateID, Type, Status, Channel,
|
||||||
// MessageLike) so the multi-channel expiry-alert tests
|
// MessageLike) so the multi-channel expiry-alert tests
|
||||||
// (renewal_expiry_alerts_test.go, Rank 4 of the 2026-05-03 deep-research
|
// (renewal_expiry_alerts_test.go, Rank 4 of the 2026-05-03 Infisical
|
||||||
// deep-research deliverable) get the same per-(cert, threshold,
|
// deep-research deliverable) get the same per-(cert, threshold,
|
||||||
// channel) dedup behaviour they'd see in production. Pre-Rank 4 the
|
// channel) dedup behaviour they'd see in production. Pre-Rank 4 the
|
||||||
// mock returned all rows regardless of filter; legacy callers
|
// mock returned all rows regardless of filter; legacy callers
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
-- Rank 4 of the 2026-05-03 deep-research deliverable
|
-- Rank 4 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
-- (cowork/deep-research-results-2026-05-03.md Part 5). Adds the
|
-- (cowork/infisical-deep-research-results.md Part 5). Adds the
|
||||||
-- per-policy channel matrix that the multi-channel expiry-alert
|
-- per-policy channel matrix that the multi-channel expiry-alert
|
||||||
-- routing reads from. Two JSONB columns:
|
-- routing reads from. Two JSONB columns:
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
-- 000027_approval_workflow.up.sql
|
-- 000027_approval_workflow.up.sql
|
||||||
-- Rank 7 of the 2026-05-03 deep-research deliverable
|
-- Rank 7 of the 2026-05-03 Infisical deep-research deliverable
|
||||||
-- (cowork/deep-research-results-2026-05-03.md Part 5). Two-person
|
-- (cowork/infisical-deep-research-results.md Part 5). Two-person
|
||||||
-- integrity / four-eyes principle for compliance-tier certificate
|
-- integrity / four-eyes principle for compliance-tier certificate
|
||||||
-- issuance. CertificateProfile.RequiresApproval gates the renewal-
|
-- issuance. CertificateProfile.RequiresApproval gates the renewal-
|
||||||
-- loop entry; issuance_approval_requests captures the per-job
|
-- loop entry; issuance_approval_requests captures the per-job
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ INSERT INTO deployment_targets (id, name, type, agent_id, config, enabled, creat
|
|||||||
('tgt-traefik-prod', 'Traefik Production', 'Traefik', 'ag-k8s-prod', '{"watch_dir": "/etc/traefik/dynamic/certs"}', true, NOW() - INTERVAL '30 days', NOW()),
|
('tgt-traefik-prod', 'Traefik Production', 'Traefik', 'ag-k8s-prod', '{"watch_dir": "/etc/traefik/dynamic/certs"}', true, NOW() - INTERVAL '30 days', NOW()),
|
||||||
('tgt-caddy-prod', 'Caddy Production', 'Caddy', 'ag-edge-01', '{"mode": "api", "admin_url": "http://localhost:2019"}', true, NOW() - INTERVAL '45 days', NOW()),
|
('tgt-caddy-prod', 'Caddy Production', 'Caddy', 'ag-edge-01', '{"mode": "api", "admin_url": "http://localhost:2019"}', true, NOW() - INTERVAL '45 days', NOW()),
|
||||||
('tgt-nginx-data', 'NGINX Data Services', 'NGINX', 'ag-data-prod', '{"cert_path": "/etc/nginx/ssl/cert.pem", "key_path": "/etc/nginx/ssl/key.pem", "reload_command": "nginx -s reload"}', true, NOW() - INTERVAL '90 days', NOW()),
|
('tgt-nginx-data', 'NGINX Data Services', 'NGINX', 'ag-data-prod', '{"cert_path": "/etc/nginx/ssl/cert.pem", "key_path": "/etc/nginx/ssl/key.pem", "reload_command": "nginx -s reload"}', true, NOW() - INTERVAL '90 days', NOW()),
|
||||||
-- Rank 5 cloud target seed rows (2026-05-03 deep-research deliverable).
|
-- Rank 5 cloud target seed rows (2026-05-03 Infisical deep-research deliverable).
|
||||||
-- AWS ACM and Azure Key Vault demo targets so QA can exercise the wiring
|
-- AWS ACM and Azure Key Vault demo targets so QA can exercise the wiring
|
||||||
-- end-to-end without standing up a real cloud account.
|
-- end-to-end without standing up a real cloud account.
|
||||||
('tgt-aws-acm-prod', 'AWS ACM Production', 'AWSACM', 'ag-server', '{"region": "us-east-1", "tags": {"env": "production", "app": "api-gateway"}}', true, NOW() - INTERVAL '7 days', NOW()),
|
('tgt-aws-acm-prod', 'AWS ACM Production', 'AWSACM', 'ag-server', '{"region": "us-east-1", "tags": {"env": "production", "app": "api-gateway"}}', true, NOW() - INTERVAL '7 days', NOW()),
|
||||||
|
|||||||
Reference in New Issue
Block a user