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
+248Lines changed: 248 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -291,6 +291,254 @@ To retrieve the full list of product codes available to your account, call the `
291
291
292
292
> Note: SSL/TLS products (codes 838–846) are supported on standard accounts. Private PKI (100, 104), S/MIME (894), and document-signing products (819–827) require special provisioning by eMudhra and are not available on standard SSL/TLS accounts — ordering them returns EMS-1162.
293
293
294
+
## Architecture
295
+
296
+
## Architecture
297
+
298
+
This document describes how the CERTInext AnyCA Gateway REST plugin integrates with Keyfactor Command and the CERTInext certificate authority. It covers the three primary certificate lifecycle operations — synchronization, enrollment, and revocation — and how the plugin routes each through the CERTInext API.
A unique transaction ID is generated for each request. The timestamp and transaction ID travel alongside the signature so the CERTInext server can reproduce and verify the hash. The plugin handles this automatically; no manual signing is required during normal operation.
339
+
340
+
An OAuth client-credentials mode is also available as an alternative. When OAuth is configured, the plugin exchanges a client ID and secret for a short-lived bearer token and automatically refreshes it before expiry.
341
+
342
+
## Certificate Identifiers
343
+
344
+
CERTInext assigns two different reference numbers to each order. Understanding the difference matters when tracing certificates across systems:
345
+
346
+
| Identifier | When it is assigned | What it is used for|
347
+
|---|---|---|
348
+
|**Request Number**| Immediately when an order is created | Tracking a draft order before it is formally submitted; attaching a CSR to a pending order |
349
+
|**Order Number**| After the order is formally submitted and accepted | All post-issuance operations: checking status, downloading the certificate, revoking — **this is the identifier stored in Keyfactor Command**|
350
+
351
+
---
352
+
353
+
## Gateway Startup
354
+
355
+
When the AnyCA Gateway process starts, it loads each configured CA connector. For CERTInext, this step reads the connector settings, establishes the API client, and confirms that the credentials are structurally valid.
Plugin->>Plugin: Initialize API client\nwith configured auth mode
366
+
Plugin->>Plugin: Record which credential fields are populated\n(values are never logged)
367
+
GW->>Plugin: Test connection
368
+
Plugin->>API: Verify credentials
369
+
API-->>Plugin: Credentials accepted
370
+
Plugin-->>GW: Connector ready
371
+
```
372
+
373
+
---
374
+
375
+
## Synchronization
376
+
377
+
Keyfactor Command periodically synchronizes its certificate inventory with CERTInext. The plugin retrieves all orders page by page and feeds them into Command's database. Synchronization can be a full refresh or incremental (only orders placed since the last successful sync).
378
+
379
+
```mermaid
380
+
sequenceDiagram
381
+
participant CMD as Keyfactor Command
382
+
participant Plugin as CERTInext Plugin
383
+
participant API as CERTInext API
384
+
385
+
CMD->>Plugin: Start synchronization\n(full refresh or incremental since last sync)
386
+
Plugin->>Plugin: Determine date filter\n(none for full sync, last sync date for incremental)
387
+
388
+
loop Retrieve one page at a time
389
+
Plugin->>API: Request next page of orders\n(filtered by date if incremental)
390
+
API-->>Plugin: Page of order records
391
+
392
+
loop For each order on the page
393
+
alt Certificate is expired and ignore-expired is enabled
**Full vs. incremental sync:** A full sync imports every order in the account regardless of age. An incremental sync requests only orders placed after the previous sync timestamp, which is faster for accounts with large order histories.
408
+
409
+
**Expired certificates:** The `IgnoreExpired` connector setting controls whether expired certificates are included in synchronization. When enabled, expired certificates are silently skipped and will not appear in the Keyfactor Command inventory.
410
+
411
+
---
412
+
413
+
## Certificate Enrollment
414
+
415
+
When a requester submits a certificate request through Keyfactor Command, the plugin translates the request into a CERTInext order and returns the result. The plugin handles three enrollment scenarios: new issuance, renewal (within a configured window before expiry), and reissuance (new keys, same profile).
416
+
417
+
### New Certificate or Reissuance
418
+
419
+
```mermaid
420
+
sequenceDiagram
421
+
participant CMD as Keyfactor Command
422
+
participant Plugin as CERTInext Plugin
423
+
participant API as CERTInext API
424
+
425
+
CMD->>Plugin: Request new certificate\n(CSR, subject, SANs, product code, requester details)
426
+
Plugin->>Plugin: Validate product code is present
427
+
Plugin->>Plugin: Record enrollment intent in audit log\n(subject, SANs, product, requester — before any API call)
428
+
429
+
Plugin->>API: Place certificate order\n(CSR, domain, organization details,\nsubscriber agreement, requestor info)
430
+
API-->>Plugin: Order accepted — order number assigned
431
+
432
+
Plugin->>API: Check order status
433
+
API-->>Plugin: Order status and certificate details
434
+
435
+
alt Certificate issued immediately
436
+
Plugin-->>CMD: Certificate ready — PEM returned
437
+
else Certificate pending approval
438
+
Plugin-->>CMD: Pending — Command will pick it up\nduring the next synchronization
439
+
else Order rejected by CERTInext
440
+
Plugin-->>CMD: Enrollment failed — see gateway logs
441
+
end
442
+
443
+
Plugin->>Plugin: Record enrollment outcome in audit log\n(order number, serial number, status)
444
+
```
445
+
446
+
### Renewal
447
+
448
+
When Command initiates a renewal, the plugin checks whether the existing certificate is within the configured renewal window. If it is, the prior order record is used as context for the new request. If it is outside the window (or the prior certificate cannot be located), the plugin falls back to issuing a new certificate.
449
+
450
+
> **Note:** CERTInext does not have a dedicated certificate renewal endpoint. Both renewal and reissuance paths submit a new `GenerateOrderSSL` order. The distinction affects how Keyfactor Command tracks the certificate record, not what is sent to CERTInext.
B -- Yes --> D[Look up prior order\nin Command database]
457
+
D --> E{Prior order\nfound?}
458
+
E -- No --> C
459
+
E -- Yes --> F[Check certificate\nexpiry date]
460
+
F --> G{Within renewal\nwindow?}
461
+
G -- Yes\nwithin window --> H[Submit new order\nlinked to prior record]
462
+
G -- No\noutside window --> C
463
+
H --> I([Certificate issued or pending])
464
+
C --> I
465
+
```
466
+
467
+
---
468
+
469
+
## Revocation
470
+
471
+
When a certificate is revoked in Keyfactor Command, the plugin verifies the certificate's current state before calling the CERTInext revocation endpoint. This prevents unnecessary API calls forcertificates that are already revoked orin a non-revocable state.
472
+
473
+
```mermaid
474
+
sequenceDiagram
475
+
participant CMD as Keyfactor Command
476
+
participant Plugin as CERTInext Plugin
477
+
participant API as CERTInext API
478
+
479
+
CMD->>Plugin: Revoke certificate\n(order number, serial number, reason code)
480
+
Plugin->>Plugin: Record revocation intent in audit log\n(order number, serial, reason — before any API call)
481
+
482
+
Plugin->>API: Retrieve current certificate status
483
+
API-->>Plugin: Current status and details
484
+
485
+
alt Certificate is already revoked
486
+
Plugin->>Plugin: Log warning — already revoked
487
+
Plugin-->>CMD: Confirmed revoked (no action needed)
488
+
else Certificate is not in an issued state
489
+
Plugin->>Plugin: Log error — cannot revoke
490
+
Plugin-->>CMD: Error — certificate is not revocable
Plugin->>Plugin: Record revocation outcome in audit log\n(order number, serial, subject, reason)
496
+
Plugin-->>CMD: Certificate revoked
497
+
end
498
+
```
499
+
500
+
**Idempotency:** If Command retries a revocation request (for example, after a timeout), the plugin detects that the certificate is already revoked and returns success without submitting a duplicate request to CERTInext.
501
+
502
+
**Audit trail:** The revocation intent is written to the gateway log *before* the API call is made. This ensures that the intent is captured even if the API call subsequently fails, satisfying SOX audit requirements.
503
+
504
+
---
505
+
506
+
## Connector Validation
507
+
508
+
When an administrator saves or edits a CERTInext CA connector in the Keyfactor Command Management Portal, the gateway validates the configuration and performs a live connectivity check.
509
+
510
+
```mermaid
511
+
flowchart TD
512
+
A([Save connector configuration]) --> B{Connector\nmarked as disabled?}
513
+
B -- Yes --> C([Saved without validation\nConnector will not process requests])
514
+
B -- No --> D{Required fields\npresent and valid?\nAPI URL · Account Number · Credentials}
515
+
D -- Missing or invalid --> E([Validation error shown to administrator])
516
+
D -- Valid --> F[Build temporary API client\nfrom supplied settings]
517
+
F --> G[Send test request\nto CERTInext]
518
+
G --> H{API accepted\nthe credentials?}
519
+
H -- No --> I([Connection test failed\nCheck credentials and API URL])
520
+
H -- Yes --> J([Connector saved and active])
521
+
```
522
+
523
+
**Disabled connectors:** Setting `Enabled` to `false` allows the connector record to be created and saved before credentials are available. The live connectivity test is skipped, so no credentials are required at save time.
524
+
525
+
---
526
+
527
+
## API Endpoint Reference
528
+
529
+
The table below maps each Keyfactor Command operation to the CERTInext API endpoint it calls.
530
+
531
+
| Operation | CERTInext API endpoint |
532
+
|---|---|
533
+
| Test connection / verify credentials |`POST ValidateCredentials`|
534
+
| Issue new certificate |`POST GenerateOrderSSL`then`POST TrackOrder`|
0 commit comments