mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 17:31:30 +00:00
54033aa3aa
Closes Rank 5 (AWS half) of the 2026-05-03 Infisical deep-research
deliverable (cowork/infisical-deep-research-results.md Part 5).
Pre-fix, certctl had no path to deploy certs to AWS-managed TLS-
termination endpoints (ALB / CloudFront / API Gateway / App Runner)
— operators terminating TLS at AWS had to use Infisical secret-sync,
manual aws-cli imports, or external automation. This commit lands
the SDK-driven AWS Certificate Manager target connector that closes
the gap end-to-end.
Architecture:
- internal/connector/target/awsacm/awsacm.go — Connector wraps
*acm.Client behind the ACMClient interface seam (mirrors
awsacmpca's ACMPCAClient pattern from the issuer side).
LoadDefaultConfig handles the standard AWS credential chain
(IRSA / EC2 instance profile / SSO / env vars); no embedded
creds in connector Config.
- Pre-deploy snapshot via DescribeCertificate + GetCertificate so
on-import-failure rollback restores the previous cert. Mirrors
the Bundle 5 IIS pattern + the Bundle 7/8 WinCertStore /
JavaKeystore patterns. Surfaces rollback success/failure via
the existing certctl_deploy_rollback_total Prometheus counter
label set.
- Provenance tags: certctl-managed-by=certctl + certctl-
certificate-id=<mc-id> set automatically on every import. ACM
strips tags on re-import, so the connector calls
AddTagsToCertificate post-import to keep the provenance pair
fresh. Operators looking up a cert ARN by managed-cert ID
(Terraform data source, CloudFormation output) match against
these tags.
- DeploymentRequest.KeyPEM held in agent memory only — never
written to disk. Aligns with the pull-only deployment model
documented in CLAUDE.md.
Tests:
- awsacm_test.go: 15-subtest happy-path + validation matrix
covering ValidateConfig (success / missing-region / malformed-
region / malformed-ARN / reserved-tag rejection),
DeployCertificate (fresh import / rotate-in-place / rollback-
on-serial-mismatch / rollback-also-fails / empty-key-rejected /
no-client-rejected), ValidateOnly (returns sentinel),
ValidateDeployment (serial match / mismatch / no-ARN-yet).
- awsacm_failure_test.go: 5 per-error-class contract tests
mirroring the awsacmpca_failure_test.go shape (commit
60dce0b) — AccessDeniedException (smithy.GenericAPIError),
ResourceNotFoundException (typed), ThrottlingException
(smithy.GenericAPIError, FaultServer preserved),
InvalidArgsException (typed, terminal), RequestInProgress
Exception (typed). All assert errors.As against the SDK type +
operator-actionable substring + connector-side wrap framing.
- Coverage on awsacm.go: 54.9% of statements (matches the K8s-
Secret + IIS connectors' 50-65% range; rollback-failure paths
contribute most of the un-covered surface — those exercise
only when the rollback's SDK call also returns an error).
- go test -race -count=10 green; no goroutine leaks.
Wiring:
- internal/domain/connector.go: TargetTypeAWSACM = "AWSACM".
- internal/service/target.go: validTargetTypes set extended.
- cmd/agent/main.go::createTargetConnector: AWSACM case arm
mirroring the KubernetesSecrets shape exactly. Calls
awsacm.New(context.Background(), &cfg, a.logger) — the
SDK-loading happens here, not lazily, so config errors
surface at agent boot.
- cmd/agent/agent_test.go::TestCreateTargetConnector_AllSupported
Types: AWSACM added to the type matrix + the InvalidJSON
matrix.
go.mod / go.sum:
- github.com/aws/aws-sdk-go-v2/service/acm v1.38.3 (direct).
aws-sdk-go-v2 + service/acmpca + smithy-go were already direct
from the awsacmpca issuer; this is the distribution-side
companion package.
Documentation:
- docs/connectors.md "AWS Certificate Manager (ACM)" section:
config table, IAM policy JSON (5 actions on
arn:aws:acm:*:*:certificate/*), IRSA / EC2 instance-profile /
SSO auth recipes, atomic-rollback contract, Terraform ALB-
attachment snippet, threat model carve-outs (no disk writes,
mandatory provenance tags, no long-lived creds in Config),
procurement checklist crib (5 bullets paste-able into a
security review).
Out of scope (intentional, flagged in V3-Pro forward path):
- CloudFront / ALB auto-attach (UpdateDistribution requires a
different IAM scope than ACM ImportCertificate).
- Cross-region ACM replication (ACM is regional; CloudFront
forces us-east-1).
- Tag-filtered ARN discovery (V2 uses operator-pinned
Config.CertificateArn after first deploy; tag-scan path
requires acm:ListTagsForCertificate which we deliberately
keep off the minimum-IAM-policy surface).
- Azure Key Vault (separate cloud, separate connector — Azure
half of Rank 5 ships in a follow-on commit).
Verified locally:
- gofmt clean.
- go vet ./internal/connector/target/awsacm/...
./internal/domain/... ./internal/service/...
./cmd/agent/... clean.
- go test -short -count=1 ./internal/connector/target/awsacm/...
./internal/domain/... ./cmd/agent/... green (15 + 5 awsacm
subtests; all 15 supported target types instantiate via the
agent factory).
- go test -race -count=10 ./internal/connector/target/awsacm/...
green.
Reference: cowork/infisical-deep-research-results.md Part 5 Rank 5.
Acquisition prompt:
cowork/rank-5-aws-acm-azure-kv-target-adapters-prompt.md.
109 lines
5.0 KiB
Modula-2
109 lines
5.0 KiB
Modula-2
module github.com/shankar0123/certctl
|
|
|
|
go 1.25.9
|
|
|
|
require (
|
|
github.com/google/uuid v1.6.0
|
|
github.com/lib/pq v1.10.9
|
|
github.com/modelcontextprotocol/go-sdk v1.4.1
|
|
github.com/testcontainers/testcontainers-go v0.35.0
|
|
)
|
|
|
|
require (
|
|
github.com/aws/aws-sdk-go-v2 v1.41.7
|
|
github.com/aws/aws-sdk-go-v2/config v1.32.17
|
|
github.com/aws/aws-sdk-go-v2/service/acm v1.38.3
|
|
github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.14
|
|
github.com/aws/smithy-go v1.25.1
|
|
github.com/go-jose/go-jose/v4 v4.1.4
|
|
github.com/leanovate/gopter v0.2.11
|
|
github.com/masterzen/winrm v0.0.0-20250927112105-5f8e6c707321
|
|
github.com/pkg/sftp v1.13.10
|
|
golang.org/x/crypto v0.45.0
|
|
golang.org/x/sync v0.18.0
|
|
software.sslmate.com/src/go-pkcs12 v0.7.0
|
|
)
|
|
|
|
require (
|
|
dario.cat/mergo v1.0.0 // indirect
|
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
|
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
|
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect
|
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.16 // indirect
|
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 // indirect
|
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 // indirect
|
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 // indirect
|
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect
|
|
github.com/bodgit/ntlmssp v0.0.0-20240506230425-31973bb52d9b // indirect
|
|
github.com/bodgit/windows v1.0.1 // indirect
|
|
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
|
github.com/containerd/containerd v1.7.18 // indirect
|
|
github.com/containerd/log v0.1.0 // indirect
|
|
github.com/containerd/platforms v0.2.1 // indirect
|
|
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
github.com/distribution/reference v0.6.0 // indirect
|
|
github.com/docker/docker v27.1.1+incompatible // indirect
|
|
github.com/docker/go-connections v0.5.0 // indirect
|
|
github.com/docker/go-units v0.5.0 // indirect
|
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
|
github.com/go-logr/logr v1.4.1 // indirect
|
|
github.com/go-logr/stdr v1.2.2 // indirect
|
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
|
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
|
github.com/gogo/protobuf v1.3.2 // indirect
|
|
github.com/google/jsonschema-go v0.4.2 // indirect
|
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
|
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
|
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
|
github.com/jcmturner/gofork v1.7.6 // indirect
|
|
github.com/jcmturner/goidentity/v6 v6.0.1 // indirect
|
|
github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect
|
|
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
|
github.com/klauspost/compress v1.17.4 // indirect
|
|
github.com/kr/fs v0.1.0 // indirect
|
|
github.com/kr/text v0.2.0 // indirect
|
|
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
|
github.com/magiconair/properties v1.8.7 // indirect
|
|
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect
|
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
|
github.com/moby/patternmatcher v0.6.0 // indirect
|
|
github.com/moby/sys/sequential v0.5.0 // indirect
|
|
github.com/moby/sys/user v0.1.0 // indirect
|
|
github.com/moby/term v0.5.0 // indirect
|
|
github.com/morikuni/aec v1.0.0 // indirect
|
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
|
github.com/opencontainers/image-spec v1.1.0 // indirect
|
|
github.com/pkg/errors v0.9.1 // indirect
|
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
|
github.com/segmentio/asm v1.1.3 // indirect
|
|
github.com/segmentio/encoding v0.5.4 // indirect
|
|
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
|
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
|
github.com/stretchr/testify v1.10.0 // indirect
|
|
github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde // indirect
|
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
|
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
|
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
|
golang.org/x/net v0.47.0 // indirect
|
|
golang.org/x/oauth2 v0.34.0 // indirect
|
|
golang.org/x/sys v0.40.0 // indirect
|
|
golang.org/x/text v0.31.0 // indirect
|
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
)
|