Skip to content

feat(dcv): DNS domain control validation via IDomainValidatorFactory#5

Merged
spbsoluble merged 15 commits into
feat/v1.0-release-notesfrom
fix/p1-p3-improvements
May 6, 2026
Merged

feat(dcv): DNS domain control validation via IDomainValidatorFactory#5
spbsoluble merged 15 commits into
feat/v1.0-release-notesfrom
fix/p1-p3-improvements

Conversation

@spbsoluble

Copy link
Copy Markdown
Collaborator

Summary

  • Add DNS-based Domain Control Validation (DCV) support via IDomainValidatorFactory constructor injection, enabling the gateway's installed DNS provider plugins (e.g. azure-azuredns-dnsplugin, aws-route53-dnsplugin) to handle TXT record publishing during enrollment
  • Add GetDcv / VerifyDcv API client methods and corresponding request/response DTOs
  • Add DcvEnabled, DcvTxtRecordTemplate, and DcvPropagationDelaySeconds connector config fields (opt-in; default off)
  • Bump Keyfactor.AnyGateway.IAnyCAPlugin to 3.3.0-PRERELEASE-78770-979f582005 (required for IDomainValidatorFactory)

Changes

Commit Description
4181e4b feat(constants)Constants.Dcv (method codes, status codes, default TXT template) and Config DCV key names
94bc2d7 feat(api)GetDcvRequest, VerifyDcvRequest, GetDcvResponse, VerifyDcvResponse, TrackOrderDomainVerification DTOs
ea1fdd2 feat(client)GetDcvAsync and VerifyDcvAsync in ICERTInextClient / CERTInextClient
b2ea1c3 feat(config)DcvEnabled, DcvTxtRecordTemplate, DcvPropagationDelaySeconds in CERTInextConfig and CA connector annotations
ef4c728 feat(enroll)IDomainValidatorFactory constructor injection; PerformDcvIfNeededAsync; EnrollNewAsync DCV path
ef692b2 test(client) — 7 WireMock unit tests for GetDcvAsync / VerifyDcvAsync
1251258 chore(scripts)scripts/get-dcv.sh, scripts/verify-dcv.sh, make get-dcv / make verify-dcv targets

DCV flow

PlaceOrder
  └─ TrackOrder → read domainVerification entries
       └─ for each domain where dcvStatus=0 and dcvMethod=1:
            ├─ GetDcv          → fetch TXT token from CERTInext
            ├─ ResolveDomainValidator(domain, "dns-01")
            ├─ StageValidation(hostname, token)
            └─ [propagation delay]
                 ├─ VerifyDcv  → ask CERTInext to check the record
                 └─ CleanupValidation(hostname)  ← always, in finally
  └─ GetCertificate → return post-DCV result

Key invariant: DCV is skipped entirely when the order is already in a terminal (issued/revoked) state. A completed order never triggers DNS validation.

Test plan

  • dotnet build — 0 errors, 0 warnings on both CERTInext and CERTInext.Tests
  • dotnet test — 111/111 passing (7 new DCV tests)
  • SOX/SOC2 compliance audit completed; 7 of 8 findings remediated (shell injection prevention, CancellationToken threading, FQDN input validation, audit log completeness)
  • Manual DV SSL order smoke test against sandbox (blocked — no live DV order available; DCV path exercised via WireMock)

🤖 Generated with Claude Code

spbsoluble and others added 15 commits April 24, 2026 08:26
…ed check, renewal window, retry logic, IDisposable, GroupNumber config, nested product response model
… add lifecycle test, make empty-account resilient
… generate-order-149-fresh, probe-endpoints, get-field-details targets
…ctory

Adds 21 make targets covering every CERTInext V2 operation (ssl-certificates,
private-pki-certificates, catalog, groups, orgs, domains, reports). Each target
delegates to a corresponding script under scripts/v2/ which sources the new
scripts/lib/certinext-v2-auth.sh for CERTInext-native SHA256 token exchange.
Adds analysis/ to .gitignore so scratch docs and support emails are never committed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Constants.Dcv subclass with dcvMethod codes (1=DNS TXT, 2=HTTP,
3=Email), dcvStatus values (0=Pending, 1=Validated, 2=Rejected), and
the default TXT record hostname template. Add DcvEnabled,
DcvTxtRecordTemplate, and DcvPropagationDelaySeconds to Constants.Config.
Add GetDcvRequest, DcvRequestDetails, and VerifyDcvRequest for the
GetDcv/VerifyDcv endpoints. Add GetDcvResponse, DcvResponseDetails,
VerifyDcvResponse, TrackOrderDomainVerification (with JsonExtensionData
for heterogeneous per-domain entries), and DomainVerificationDetail.
Wire DomainVerification onto TrackOrderResponseDetails.
GetDcvAsync posts to GetDcv and returns the token (and file/email
fields) for a domain on an existing order. VerifyDcvAsync posts to
VerifyDcv to ask CERTInext to check the published DNS TXT record.
Both methods follow the existing pattern: BuildMetaAsync, retry,
auth-failure detection, DeserializeOrThrow, meta.status check,
structured logging with OrderNumber and Domain context.
…aySeconds

Add three DCV-related fields to CERTInextConfig with documented defaults
(false, _emsign-validation.{0}, 30 s) and corresponding UI annotations
in GetCAConnectorAnnotations. Guards the DNS DCV path so operators must
explicitly opt in before any DNS plugin interaction occurs.
Bump IAnyCAPlugin to 3.3.0-PRERELEASE-78770-979f582005 to gain access
to IDomainValidatorFactory, IDomainValidator, and IDomainValidatorConfigProvider.

Add a primary constructor accepting IDomainValidatorFactory (gateway
injects this at startup) alongside the existing parameterless fallback.
Add DomainValidatorConfigProvider inner class.

Add PerformDcvIfNeededAsync: reads pending-DCV domains from TrackOrder,
skips if the order is already issued, validates domain FQDNs, calls
GetDcvAsync per domain, resolves the DNS plugin via
ResolveDomainValidator(domain, 'dns-01'), stages the TXT record, waits
for propagation, triggers VerifyDcv, then cleans up in a finally block.
EnrollNewAsync calls this when DcvEnabled=true and the factory is present,
then re-fetches the post-DCV certificate status before returning.
Add GetDcvSuccessJson, GetDcvFailureJson, VerifyDcvSuccessJson, and
VerifyDcvFailureJson helpers to MockCertificateData. Add seven tests
covering: successful token retrieval, meta-failure response, 401
authentication failure, successful verification, meta-failure on verify,
401 on verify, and 500 on verify.
…gets

Add scripts/get-dcv.sh and scripts/verify-dcv.sh mirroring the
track-order.sh pattern. Both scripts source ~/.env_certinext and
certinext-auth.sh, accept ORDER_NUMBER, DOMAIN_NAME, and optional
DCV_METHOD (default 1=DNS TXT), and use jq --arg for safe JSON
construction to prevent injection via user-supplied values.

Add get-dcv and verify-dcv Makefile targets with DCV_METHOD variable
and register both in .PHONY.
Keep DCV config keys, DCV Makefile targets, and V2 API targets from
fix/p1-p3-improvements; take PRIVATE_PKI_CSR filename from feat branch.
Keep DCV tests from HEAD; auto-merged README and integration-manifest
changes from feat/v1.0-release-notes.
@spbsoluble spbsoluble merged commit fd6c432 into feat/v1.0-release-notes May 6, 2026
25 of 28 checks passed
@spbsoluble spbsoluble deleted the fix/p1-p3-improvements branch May 6, 2026 16:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant