You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+110-1Lines changed: 110 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -86,8 +86,9 @@ This integration is tested and confirmed as working for Anygateway REST 24.2 and
86
86
***ApiKey** - CSCGlobal API Key
87
87
***BearerToken** - CSCGlobal Bearer Token
88
88
***DefaultPageSize** - Default page size for use with the API. Default is 100
89
-
***TemplateSync** - Enable template sync.
90
89
***SyncFilterDays** - Number of days from today to filter certificates by expiration date during incremental sync.
90
+
***RenewalWindowDays** - Number of days before the annual order expiry within which a RenewOrReissue triggers a paid Renewal rather than a free Reissue. Default is 30.
91
+
***DcvPollTimeoutSeconds** - Max seconds to synchronously poll CSC for issuance after submitting an order (and publishing CNAME DCV). 0 disables polling (enrollment returns pending immediately; cert arrives on next sync). When >0, fast-validating orders can return the cert directly. Keep small to avoid long-blocking enrollment requests.
91
92
92
93
2. PLEASE NOTE, AT THIS TIME THE RAPID_SSL TEMPLATE IS NOT SUPPORTED BY THE CSC API AND WILL NOT WORK WITH THIS INTEGRATION
93
94
@@ -311,6 +312,114 @@ This integration is tested and confirmed as working for Anygateway REST 24.2 and
311
312
***Addtl Sans Comma Separated DCV Emails** - OPTIONAL: Additional SANs DCV Emails, comma separated
312
313
313
314
315
+
## CA Connection Configuration
316
+
317
+
When defining the Certificate Authority in the AnyCA Gateway REST portal, configure the following fields on the **CA Connection** tab:
318
+
319
+
CONFIG ELEMENT | DESCRIPTION | DEFAULT
320
+
---------------|-------------|--------
321
+
CscGlobalUrl | The base URL for the CSCGlobal API (e.g. `https://apis.cscglobal.com`) | (required)
322
+
ApiKey | Your CSCGlobal API key | (required)
323
+
BearerToken | Your CSCGlobal Bearer token for authentication | (required)
324
+
DefaultPageSize | Page size for API list requests | 100
325
+
SyncFilterDays | Number of days from today used to filter certificates by expiration date during **incremental** sync. Only certificates expiring within this window are returned. Does not apply to full sync. | 5
326
+
RenewalWindowDays | Number of days before the annual order expiry date within which a **RenewOrReissue** request triggers a paid **Renewal** rather than a free **Reissue**. See [Renewal vs. Reissue Logic](#renewal-vs-reissue-logic) below. | 30
327
+
DcvPollTimeoutSeconds | Max seconds to synchronously poll CSC forcertificate issuance after submitting an order. `0` disables polling (enrollment returns pending immediately; cert arrives on the next sync). When `>0`, fast-validating orders can return the issued cert directlyin the enrollment response. See [Synchronous Issuance Polling](#synchronous-issuance-polling) below. | 0
328
+
329
+
>**Note:** DNS auto-publishing forCNAME DCV is handled by the AnyCA Gateway REST framework's Domain Validation system (gateway 3.3+). It's configuredin the gateway UI under **Domain Validation Configurations**, not on the CA Connection tab. See [DNS Auto-Publishing (CNAME DCV)](#dns-auto-publishing-cname-dcv).
330
+
331
+
## Renewal vs. Reissue Logic
332
+
333
+
CSC Global subscriptions are annual orders. When Keyfactor Command sends a **RenewOrReissue** request, the plugin must decide whether to submit a **Renewal** (a new paid order) or a **Reissue** (a free re-key under the existing active order).
334
+
335
+
The decision is based on the **RenewalWindowDays** setting and works as follows:
336
+
337
+
1. The plugin fetches the original certificate from CSC and reads its `orderDate`.
338
+
2. It computes the **order expiry** as `orderDate + 1 year`.
339
+
3. It calculates **days remaining**until the order expires.
340
+
4. If `days remaining <= RenewalWindowDays`, the request is treated as a **Renewal** (new paid order).
341
+
5. If `days remaining > RenewalWindowDays`, the request is treated as a **Reissue** (free under the active order).
342
+
343
+
**Example with default RenewalWindowDays = 30:**
344
+
345
+
```
346
+
Order Date: 2025-04-08
347
+
Order Expiry: 2026-04-08
348
+
Today: 2026-03-15
349
+
Days Left: 24
350
+
351
+
24 <= 30 --> RENEWAL (new paid order)
352
+
```
353
+
354
+
```
355
+
Order Date: 2025-04-08
356
+
Order Expiry: 2026-04-08
357
+
Today: 2025-09-01
358
+
Days Left: 219
359
+
360
+
219 > 30 --> REISSUE (free under active order)
361
+
```
362
+
363
+
**Fallback behavior:** If the plugin cannot retrieve the `orderDate` from CSC (e.g., API error or missing field), it falls back to checking the certificate's expiration date. If the certificate is already expired, it treats the request as a Renewal.
364
+
365
+
**Note:** Both Renewal and Reissue submissions are asynchronous at CSC. The plugin returns a "pending" status and the issued certificate will appear in Keyfactor after the next sync cycle.
366
+
367
+
## DNS Auto-Publishing (CNAME DCV)
368
+
369
+
CSC supports two Domain Control Validation (DCV) methods: **EMAIL** and **CNAME**. With CNAME validation, CSC returns a CNAME record (name → target) that must exist in DNS before they will validate the order.
370
+
371
+
By default this plugin returns the CNAME details to Keyfactor Command for **manual publishing**. To fully automate enrollment, the plugin uses the **AnyCA Gateway REST framework's built-in DNS provider system** (available in framework 3.3 and later). The framework discovers DNS provider plugins deployed alongside the CA plugin and routes each CNAME to whichever provider claims the matching DNS zone.
372
+
373
+
### Requirements
374
+
375
+
* AnyCA Gateway REST framework **3.3 or later** (the `IDomainValidatorFactory` interface ships in`Keyfactor.AnyGateway.IAnyCAPlugin` 3.3+).
376
+
* At least one DNS provider DLL (e.g. GoDaddy, Cloudflare, Route 53, Azure) deployed in the gateway `Extensions` folder.
377
+
* A Domain Validation Configuration registered in the gateway UI that maps your domain(s) to the deployed provider (for example, `*.example.com` → GoDaddy).
378
+
379
+
### How It Works
380
+
381
+
1. CSC returns the CNAME `name → target` details in the enrollment response.
382
+
2. For each CNAME entry, the plugin calls `IDomainValidatorFactory.ResolveDomainValidator(recordName, "cname")`.
383
+
3. The framework returns the `IDomainValidator` whose Domain Validation Configuration matches the record's zone (or `null` if no match).
384
+
4. The plugin calls `validator.StageValidation(recordName, cnameTarget, ct)` to publish the record.
385
+
5. CSC asynchronously validates the CNAME; the issued certificate appears on the next sync.
386
+
387
+
### Behavior
388
+
389
+
* **Resolution is per record, not per CA.** One CA can drive multiple DNS providers (GoDaddy for some domains, Route 53 for others) with no per-CA configuration.
390
+
* **Only invoked for CNAME DCV.** Templates configured with EMAIL validation are unaffected — no DNS publishing occurs.
391
+
* **Best-effort.** If no provider claims the zone, the publish call fails, or the factory wasn't injected (gateway pre-3.3), the enrollment still succeeds and the CNAME details remain in the Keyfactor request so a human can publish manually as a fallback.
392
+
***Trace-logged.** Every resolution (matched/unresolved) and publish attempt (success/failure) is logged at Info/Trace level.
393
+
***Validation type string.** The plugin passes `"cname"` to `ResolveDomainValidator`. CSC's DCV requires a **CNAME** record, which is different from ACME's `"dns-01"` challenge (a TXT record). A single DNS provider DLL can ship multiple validator classes — one advertising `"dns-01"` (publishes TXT, for ACME) and one advertising `"cname"` (publishes CNAME, for CSC). You must deploy and configure a validator that advertises `"cname"` or no provider will match.
394
+
***Trailing dots normalized.** CSC returns FQDN-canonical names with a trailing dot (e.g. `_token.example.com.`). The plugin strips the trailing dot before resolution and publishing, because Domain Validation Configurations and DNS provider APIs expect names without it.
395
+
396
+
### Configuration in the Gateway UI
397
+
398
+
In the AnyCA Gateway REST portal, under **Domain Validation Configurations**:
399
+
400
+
1. **Add** a new configuration.
401
+
2. Pick a **Domain Validator Type** that publishes **CNAME** records and advertises validation type`cname`. For GoDaddy this is `GoDaddyCnameDomainValidator` (the `GoDaddyDomainValidator` variant publishes TXT for ACME and will **not** work for CSC).
402
+
3. Add one or more **domain patterns** (e.g. `*.example.com`).
403
+
4. Fill out the provider-specific **Configuration Settings** (API keys, base URL, etc.).
404
+
5. Save.
405
+
406
+
Once configured, any CSC enrollment for a domain matching one of those patterns will have its CNAME auto-published.
407
+
408
+
>**Common pitfall:** If you configure the TXT/`dns-01` validator (e.g. `GoDaddyDomainValidator`) for a CSC domain, the record will publish as a **TXT** and CSC's CNAME validation will never succeed. Make sure you select the **CNAME** validator variant.
409
+
410
+
## Synchronous Issuance Polling
411
+
412
+
CSC validates domain control asynchronously — after an order is submitted (and the CNAME DCV record published), CSC/Sectigo polls public DNS on its own schedule and issues the certificate once validation passes. By default this plugin returns a **pending** (`EXTERNALVALIDATION`) result immediately and the issued certificate is picked up on the next gateway **sync** cycle.
413
+
414
+
For environments where DNS is published automatically (see [DNS Auto-Publishing](#dns-auto-publishing-cname-dcv)) and validation tends to complete quickly, you can have the plugin **poll CSC synchronously** at the end of enrollment and return the issued certificate directly — avoiding the wait for the next sync.
415
+
416
+
* Set **`DcvPollTimeoutSeconds`** to the maximum number of seconds to poll (e.g. `60`). `0` (default) disables polling entirely.
417
+
* The plugin polls CSC every 10 seconds until the order is issued or the timeout is reached.
418
+
* If the certificate issues within the window, the enrollment returns it immediately with a success status.
419
+
* If the window expires, the plugin falls back to the **pending** result and the certificate arrives on the next sync — exactly as it would with polling disabled.
420
+
421
+
**Tradeoff:** Polling blocks the enrollment request for up to `DcvPollTimeoutSeconds`. CSC validation frequently takes minutes to hours, so most orders will still fall through to pending — keep the timeout small (30–90s) to catch only the fast cases without hanging callers. This applies to New enrollments, Renewals, and Reissues.
0 commit comments