Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
19a46f9
added back slnx
bhillkeyfactor Mar 23, 2026
53548b4
removed old file
bhillkeyfactor Mar 23, 2026
7e27ab6
Update integration-manifest.json
bhillkeyfactor Mar 27, 2026
fe5b7e1
Update generated docs
Mar 27, 2026
8a13feb
fixed default status
bhillkeyfactor Mar 30, 2026
9be985e
fixed reissue issue
bhillkeyfactor Mar 31, 2026
fe3d445
undo fix
bhillkeyfactor Mar 31, 2026
9133420
fixe custom order id
bhillkeyfactor Mar 31, 2026
0bbe7e9
fixed order id
bhillkeyfactor Mar 31, 2026
306f460
dnsplugin updates
bhillkeyfactor Jul 14, 2026
7cb96d2
Update generated docs
Jul 14, 2026
e668f8d
Update keyfactor-starter-workflow.yml
bhillkeyfactor Jul 14, 2026
ff4d32b
docs: auto-generate README and documentation [skip ci]
github-actions[bot] Jul 14, 2026
a5d7873
Update integration-manifest.json
bhillkeyfactor Jul 14, 2026
f70fbf9
docs: auto-generate README and documentation [skip ci]
github-actions[bot] Jul 14, 2026
a88984d
Merge branch 'release-2.0' into dnsplugins
bhillkeyfactor Jul 14, 2026
409f807
fixed cname validator
bhillkeyfactor Jul 15, 2026
3492b91
docs: auto-generate README and documentation [skip ci]
github-actions[bot] Jul 15, 2026
424e8ab
added more comprehensive logging
bhillkeyfactor Jul 15, 2026
98b9646
Merge branch 'dnsplugins' of https://github.com/Keyfactor/sslstore-ca…
bhillkeyfactor Jul 15, 2026
49bb24a
fixed issues
bhillkeyfactor Jul 15, 2026
346e1e9
fixed validation methods
bhillkeyfactor Jul 15, 2026
f6c4625
poll for issuance
bhillkeyfactor Jul 15, 2026
c421b25
docs: auto-generate README and documentation [skip ci]
github-actions[bot] Jul 15, 2026
c7514f2
harden code
bhillkeyfactor Jul 15, 2026
12fa874
fixed postman collection
bhillkeyfactor Jul 15, 2026
cdd7ecb
fixed bool values
bhillkeyfactor Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/keyfactor-starter-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ on:

jobs:
call-starter-workflow:
uses: keyfactor/actions/.github/workflows/starter.yml@port-update-catalog-to-v5

uses: keyfactor/actions/.github/workflows/starter.yml@v5
with:
command_token_url: ${{ vars.COMMAND_TOKEN_URL }}
command_hostname: ${{ vars.COMMAND_HOSTNAME }}
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# v2.1.0
* Added support for the generic DNS provider plugin framework (Keyfactor.AnyGateway.IAnyCAPlugin 3.3.0)
* Automated DNS (CNAME) domain control validation: when enabled, the plugin requests CNAME-based
validation from SSL Store and publishes the returned record via the DNS provider plugin resolved
by the AnyCA Gateway (Azure, Route53, Cloudflare, Google, NS1, Infoblox, RFC2136, etc.)
* Verifies public DNS propagation of the validation record before returning (configurable attempts/delay)
* After publishing the CNAME, polls SSL Store for issuance up to `DcvPollTimeoutSeconds` and returns the
issued certificate directly from the enrollment call when it issues in time (ACME-style); otherwise
returns pending and the certificate is retrieved on the next CA sync
* Best-effort cleanup of DNS validation records once an order is issued (GetSingleRecord/Synchronize)
* New CA-connection settings: `DnsValidationEnabled`, `DnsVerificationServer`, `DnsPropagationMaxAttempts`, `DnsPropagationDelaySeconds`
* CNAME is the intrinsic DCV method for SSL Store; the DNS record type is determined by the CNAME
validator you map to each domain in the gateway's Domain Validation configuration (no CA-connection knob)
* Email approver validation remains the default when DNS validation is disabled
* Revoked (Cancelled) orders now download and store the actual certificate; orders with no
downloadable certificate are skipped instead of storing empty cert bytes (which previously
crashed the gateway certificate search with "m_safeCertContext is an invalid handle")
* Added FlowLogger step tracing and expanded operational logging across all plugin operations

# v2.0.0
* Converted from AnyCA Gateway (DB) to AnyCA Gateway REST plugin architecture
* Migrated from CAProxy.AnyGateway (BaseCAConnector) to IAnyCAPlugin interface
Expand Down
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ The SSL Store AnyCA Gateway REST plugin extends the capabilities of the SSL Stor
* Support for DV, OV, and EV certificate products
* Multi-domain (MDC/SAN) and wildcard certificate support
* Automatic domain validation with approver email verification
* Automated DNS (CNAME) domain control validation via the AnyCA Gateway DNS provider plugin framework
* 80+ pre-configured certificate products across DigiCert and Sectigo families
* **Certificate Revocation**:
* Request revocation of previously issued certificates via SSL Store refund request API

## Compatibility

The SSL Store AnyCA Gateway REST plugin is compatible with the Keyfactor AnyCA Gateway REST 25.5 and later.
The SSL Store AnyCA Gateway REST plugin is compatible with the Keyfactor AnyCA Gateway REST 26.2 and later.

## Support
The SSL Store AnyCA Gateway REST plugin is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com.
Expand Down Expand Up @@ -273,6 +274,11 @@ The plugin uses a configurable **Renewal Window** (default: 30 days) to determin
| **PageSize** | Number of records per page during synchronization | No | `100` |
| **Enabled** | Flag to Enable or Disable the CA connector | No | `true` |
| **RenewalWindow** | Days before order expiry to trigger renewal vs. reissue | No | `30` |
| **DnsValidationEnabled** | Enable automated DNS (CNAME) domain control validation instead of email approvers | No | `false` |
| **DnsVerificationServer** | Optional authoritative/internal DNS server IP used to verify record propagation | No | (empty) |
| **DnsPropagationMaxAttempts** | Times to poll DNS for the validation record before giving up during enrollment | No | `3` |
| **DnsPropagationDelaySeconds** | Seconds between DNS propagation polling attempts (enrollment blocks for this) | No | `10` |
| **DcvPollTimeoutSeconds** | Seconds to poll SSL Store for issuance after publishing the CNAME; returns the cert inline if issued in time (`0` disables) | No | `90` |

### Gateway Registration Notes

Expand Down Expand Up @@ -305,6 +311,45 @@ The plugin uses a configurable **Renewal Window** (default: 30 days) to determin
* **PageSize** - Number of records to retrieve per page during certificate synchronization. Default is 100.
* **Enabled** - Flag to enable or disable the CA connector. Set to `true` to enable.
* **RenewalWindow** - Number of days before an order's expiration date to trigger a renewal (new order) instead of a reissue (same order). Default is 30 days.
* **DnsValidationEnabled** - When `true`, the plugin requests CNAME-based domain control validation from SSL Store and automatically publishes the returned validation record using the DNS provider plugin resolved by the AnyCA Gateway. When `false` (default), the email approver validation flow is used.
* **DnsVerificationServer** - Optional. IP address of an authoritative or internal DNS server used to confirm record propagation. Leave empty to verify against public resolvers (Google, Cloudflare, OpenDNS, Quad9).
* **DnsPropagationMaxAttempts** - Number of times to poll DNS for the validation record before giving up during enrollment. Total wait is roughly `(attempts - 1) × delay` seconds. Default is 3.
* **DnsPropagationDelaySeconds** - Seconds to wait between DNS propagation polling attempts. Enrollment blocks for this duration, so keep the combined wait reasonable — propagation is best-effort and SSL Store re-checks on its own schedule. Default is 10.
* **DcvPollTimeoutSeconds** - After a DNS-validated enrollment publishes its CNAME record, the plugin polls SSL Store for up to this many seconds for the certificate to be issued and, if issued in time, returns it directly from the enrollment call (like ACME). If the window expires, enrollment returns pending and the certificate is retrieved on the next CA sync. Enrollment blocks for up to this duration; SSL Store DCV is asynchronous and may take longer. Set to `0` to disable polling. Default is 90.

### Automated DNS (CNAME) Domain Validation

The plugin integrates with the AnyCA Gateway **generic DNS provider plugin framework**
(`Keyfactor.AnyGateway.IAnyCAPlugin` 3.3.0+). DNS provider plugins (Azure DNS, AWS Route53,
Cloudflare, Google Cloud DNS, NS1, Infoblox, RFC2136, etc.) are deployed and configured
**separately** on the gateway; this CA plugin does not bundle any DNS provider SDKs. The
gateway injects an `IDomainValidatorFactory` that resolves the correct provider for each
domain at enrollment time.

SSL Store domain control validation is always **CNAME-based**, so the plugin always requests
the `cname` validation type from the framework — this is intrinsic to the CA and is **not** a
configurable setting. What you configure is the **domain-to-validator mapping** in the
gateway's **Domain Validation** section: for each domain (e.g. `*.example.com`) you select a
**CNAME** validator (e.g. `Ns1CnameDomainValidator`, `CloudflareCnameDomainValidator`) that
publishes a CNAME record. Do **not** select the `dns-01`/TXT variant (e.g. `Ns1DomainValidator`) —
it publishes a TXT record, which SSL Store's CNAME DCV will never satisfy.

When `DnsValidationEnabled` is set (or the `CName Auth Domain Validation` template parameter
is `True`), enrollment proceeds as follows:

1. The order is submitted to SSL Store with the CNAME DCV indicator set.
2. SSL Store returns the CNAME validation record (`CNAMEAuthName` → `CNAMEAuthValue`).
3. The plugin resolves the CNAME validator mapped to the domain and publishes the CNAME record.
4. The plugin verifies the record has propagated to public (or the configured) DNS resolvers.
5. The plugin polls SSL Store for issuance for up to `DcvPollTimeoutSeconds`. If the certificate
is issued within that window, it is downloaded and returned directly from the enrollment call.
6. Otherwise enrollment returns as pending external validation; SSL Store completes validation on
its own schedule and the certificate is retrieved on the next sync / status check.
7. Once the order is issued, the plugin makes a best-effort attempt to remove the CNAME record.

A CNAME DNS validator for the relevant zone must be deployed and mapped to the domain in the
gateway's Domain Validation configuration; otherwise enrollment fails with a "no DNS provider
plugin resolved" error.

* **CA Connection**

Expand All @@ -316,6 +361,11 @@ The plugin uses a configurable **Renewal Window** (default: 30 days) to determin
* **PageSize** - The number of records to return per page during synchronization.
* **Enabled** - Flag to Enable or Disable the CA connector.
* **RenewalWindow** - Number of days before order expiry to trigger a renewal instead of a reissue.
* **DnsValidationEnabled** - Enable automated DNS (CNAME) domain control validation. When enabled, the plugin requests CNAME-based validation from SSL Store and publishes the returned record via the DNS provider plugin resolved by the AnyCA Gateway. Requires a DNS provider plugin (e.g. Azure, Route53, Cloudflare) to be deployed and configured on the gateway. When disabled, email approver validation is used.
* **DnsVerificationServer** - Optional. IP address of an authoritative/internal DNS server to use when verifying record propagation. Leave empty to verify against public DNS resolvers (Google, Cloudflare, OpenDNS, Quad9).
* **DnsPropagationMaxAttempts** - Number of times to poll DNS for the validation record before giving up during enrollment. Total wait is roughly (attempts - 1) x delay seconds. Increase this (and/or the delay) if records routinely need longer to propagate. Defaults to 3.
* **DnsPropagationDelaySeconds** - Seconds to wait between DNS propagation polling attempts during enrollment. Total wait is roughly (attempts - 1) x delay seconds. Defaults to 10. Note: enrollment blocks for this duration, so keep the combined wait reasonable — propagation is best-effort and SSL Store re-checks on its own schedule.
* **DcvPollTimeoutSeconds** - After a DNS-validated enrollment publishes its CNAME record, the plugin polls SSL Store for up to this many seconds for the certificate to be issued and, if issued in time, returns it directly from the enrollment call (like ACME). If the window expires the enrollment returns pending and the certificate is retrieved on the next CA sync. Enrollment blocks for up to this duration. Set to 0 to disable polling. Defaults to 90.

2. ### Template (Product) Configuration

Expand Down Expand Up @@ -406,6 +456,11 @@ The plugin validates approver emails against SSL Store's approved list for each
- **Sectigo/Comodo products**: At least one approver email must be from the approved list
- Emails are validated per-domain for multi-domain certificates

> **Note:** Approver email validation is skipped when DNS (CNAME) domain control validation is
> enabled — see [Automated DNS (CNAME) Domain Validation](#automated-dns-cname-domain-validation).
> DNS validation can be enabled globally via the `DnsValidationEnabled` CA-connection field or
> per-template via the `CName Auth Domain Validation` parameter.

### Important Notes

- Product IDs are automatically registered from the plugin's built-in product registry
Expand Down
Loading
Loading