Merge 1.0.3 to main#10
Open
indrora wants to merge 4 commits into
Open
Conversation
The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities:
* **CA Sync**:
* Download all certificates issued by the HydrantId CA
* Support for incremental and full synchronization
* Automatic extraction of end-entity certificates from PEM chains
* **Certificate Enrollment**:
* Support certificate enrollment with new key pairs
* Dynamic policy (profile) discovery from the CA
* Intelligent renewal vs. re-issue logic based on certificate expiration
* Support for PKCS#10 CSR format
* Configurable certificate validity periods
* **Certificate Revocation**:
* Request revocation of previously issued certificates
* Support for standard CRL revocation reasons
---------
Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io>
* feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.1 to main (#4) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Hydrant Failed Status Issues and Logging * fixed changelog * Add .NET 10 target framework support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Change FlowLogger from LogTrace to LogDebug/LogWarning The Keyfactor gateway framework sets the Microsoft.Extensions.Logging minimum level above Trace, causing all LogTrace calls to be silently dropped before reaching NLog. Flow diagram and step logging now uses LogDebug (visible), and failure steps use LogWarning for visibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Revert FlowLogger back to LogTrace LogTrace works in the CSC Global plugin with the same gateway framework, so the MEL minimum level is not the issue. Reverting to match the established pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fixed package vulns --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Morgan Gangwere <470584+indrora@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.1 to main (#4) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.2 to main (#7) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 * release 1.0.2 * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Merge 1.0.1 to main (#4) * feat: release 1.0 (#1) The HID Global HydrantId AnyCA Gateway REST plugin extends the capabilities of HydrantId Certificate Authority Service to Keyfactor Command via the Keyfactor AnyCA Gateway. This plugin leverages the HydrantId REST API with Hawk authentication to provide comprehensive certificate lifecycle management. The plugin represents a fully featured AnyCA Plugin with the following capabilities: * **CA Sync**: * Download all certificates issued by the HydrantId CA * Support for incremental and full synchronization * Automatic extraction of end-entity certificates from PEM chains * **Certificate Enrollment**: * Support certificate enrollment with new key pairs * Dynamic policy (profile) discovery from the CA * Intelligent renewal vs. re-issue logic based on certificate expiration * Support for PKCS#10 CSR format * Configurable certificate validity periods * **Certificate Revocation**: * Request revocation of previously issued certificates * Support for standard CRL revocation reasons --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * release: 1.0.1 --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> * Hydrant Failed Status Issues and Logging * fixed changelog * Add .NET 10 target framework support Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Change FlowLogger from LogTrace to LogDebug/LogWarning The Keyfactor gateway framework sets the Microsoft.Extensions.Logging minimum level above Trace, causing all LogTrace calls to be silently dropped before reaching NLog. Flow diagram and step logging now uses LogDebug (visible), and failure steps use LogWarning for visibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Revert FlowLogger back to LogTrace LogTrace works in the CSC Global plugin with the same gateway framework, so the MEL minimum level is not the issue. Reverting to match the established pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fixed package vulns --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Morgan Gangwere <470584+indrora@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Brian Hill <76450501+bhillkeyfactor@users.noreply.github.com> Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fixed revoke reason * Revert "Fixed revoke reason" This reverts commit 2569ae1. * ADO 86120: Add support for revocation reason 0 (Unspecified) HydrantID now supports CRL revocation reason 0 (Unspecified) following the CAB change. The plugin previously rejected this reason in RequestManager.GetMapRevokeReasons with RevokeReasonNotSupportedException. - Add Unspecified = 0 to the RevocationReasons enum - Map keyfactorRevokeReason == 0 to RevocationReasons.Unspecified - Update the unsupported-reason error message to list reason 0 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Restore missing closing brace for switch in GetMapRevokeReasons The release-1.0 merge dropped the closing } of the switch block. * masked senstive config data * change log --------- Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io> Co-authored-by: Morgan Gangwere <470584+indrora@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This automated merge brings the release-1.0 changes (tagged as 1.0.3 in the changelog) into main, including documentation updates, new configuration options, and substantial refactoring around logging/error handling for the HydrantId AnyCA Gateway REST plugin.
Changes:
- Expanded documentation (README + docsource) to describe prerequisites, configuration, and supported behaviors.
- Added an
EnabledCA-connection flag and broader guard clauses/logging refactors across plugin/client code (including the newFlowLoggerutility). - Updated revocation reason support to include reason code
0(Unspecified) and adjusted project build outputs (multi-targeting).
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Rebrands/updates links and significantly expands usage/config docs (currently includes duplicated “Installation” section and revocation reason mismatch). |
| integration-manifest.json | Updates release output location metadata and adds Enabled to CA connection config manifest. |
| HydrantCAProxy/RequestManager.cs | Refactors mapping/validation/logging; adds revoke reason 0 mapping but still omits reason 2. |
| HydrantCAProxy/HydrantIdCAPluginConfig.cs | Introduces Enabled config property and exposes it via annotations. |
| HydrantCAProxy/HydrantIdCAPlugin.csproj | Switches to multi-targeting and adds new package references. |
| HydrantCAProxy/HydrantIdCAPlugin.cs | Adds config masking, FlowLogger instrumentation, and many new guards; Ping() logic is currently incomplete. |
| HydrantCAProxy/FlowLogger.cs | New helper to emit structured “flow” trace logs. |
| HydrantCAProxy/Client/Models/Enums/RevocationReasons.cs | Adds Unspecified = 0 enum member. |
| HydrantCAProxy/Client/HydrantIdClient.cs | Adds extensive structured logging/guards and changes HTTP error handling behavior (still creates per-call HttpClient instances). |
| docsource/configuration.md | Major rewrite/expansion of configuration documentation (includes revocation reason mismatch). |
| CHANGELOG.md | Replaces prior content with HydrantId-focused version history entries. |
| .gitignore | Adds ignores for .claude settings and an unusual sample change.txt entry. |
Comments suppressed due to low confidence (2)
HydrantCAProxy/HydrantIdCAPlugin.cs:929
GetSingleRecord()now throws on most exceptions. This is a behavioral change from returning anAnyCAPluginCertificatewith a FAILED status and may cause status checks/sync callers to fail hard. Consider returning a FAILED result object instead of throwing (or only throwing for truly unrecoverable errors), to match the method’s return-type contract.
catch (AggregateException ae)
{
var inner = ae.Flatten().InnerException;
flow.Fail("UNHANDLED", inner?.Message ?? ae.Message);
_logger.LogError(inner ?? ae, "GetSingleRecord: AggregateException for caRequestID='{CaRequestId}': {Message}",
caRequestID ?? "(null)", inner?.Message ?? ae.Message);
throw new Exception($"Error occurred getting single cert for '{caRequestID}': {inner?.Message ?? ae.Message}", inner ?? ae);
}
catch (Exception ex)
{
flow.Fail("UNHANDLED", ex.Message);
_logger.LogError(ex, "GetSingleRecord: exception for caRequestID='{CaRequestId}': {Message}",
caRequestID ?? "(null)", ex.Message);
throw new Exception($"Error occurred getting single cert for '{caRequestID}': {ex.Message}", ex);
}
HydrantCAProxy/RequestManager.cs:239
GetValidity()logs a warning and returns an emptyCertRequestBodyValiditywhenperiodis unrecognized. That will produce an enrollment request with no validity set, which is likely to be rejected by the API or lead to unintended defaults. Consider throwing anArgumentExceptionfor unsupported period values instead of silently continuing.
CertRequestBodyValidity validity = new CertRequestBodyValidity();
switch (period)
{
case "Years":
validity.Years = units;
break;
case "Months":
validity.Months = units;
break;
case "Days":
validity.Days = units;
break;
default:
Log.LogWarning("GetValidity: unrecognized period '{Period}', no validity set", period);
break;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| flow.Step("PingCA"); | ||
| _logger.LogDebug("Pinging HydrantId to validate connection"); |
| public string HydrantIdBaseUrl { get; set; } | ||
| public string HydrantIdAuthId { get; set; } | ||
| public string HydrantIdAuthKey { get; set; } | ||
| public bool Enabled { get; set; } |
Comment on lines
+799
to
813
| catch (AggregateException ae) | ||
| { | ||
| var inner = ae.Flatten().InnerException; | ||
| flow.Fail("UNHANDLED", inner?.Message ?? ae.Message); | ||
| _logger.LogError(inner ?? ae, "Revoke: AggregateException for caRequestID='{CaRequestId}': {Message}", | ||
| caRequestID ?? "(null)", inner?.Message ?? ae.Message); | ||
| throw new Exception($"Revoke failed for '{caRequestID}' with message {inner?.Message ?? ae.Message}", inner ?? ae); | ||
| } | ||
| catch (Exception e) | ||
| { | ||
| _logger.LogError($"Error during revoke process: {e.Message}"); | ||
| return (int)EndEntityStatus.FAILED; | ||
| flow.Fail("UNHANDLED", e.Message); | ||
| _logger.LogError(e, "Revoke: unhandled exception for caRequestID='{CaRequestId}': {Message}", | ||
| caRequestID ?? "(null)", e.Message); | ||
| throw new Exception($"Revoke failed for '{caRequestID}' with message {e.Message}", e); | ||
| } |
| NullValueHandling = NullValueHandling.Ignore, | ||
| TraceWriter = traceWriter | ||
| }; | ||
| var restClient = ConfigureRestClient("post", fullUrl); |
Comment on lines
+79
to
99
| switch (keyfactorRevokeReason) | ||
| { | ||
| case 0: | ||
| returnStatus = RevocationReasons.Unspecified; | ||
| break; | ||
| case 1: | ||
| returnStatus = RevocationReasons.KeyCompromise; | ||
| break; | ||
| case 3: | ||
| returnStatus = RevocationReasons.AffiliationChanged; | ||
| break; | ||
| case 4: | ||
| returnStatus = RevocationReasons.Superseded; | ||
| break; | ||
| case 5: | ||
| returnStatus = RevocationReasons.CessationOfOperation; | ||
| break; | ||
| default: | ||
| Log.LogError("GetMapRevokeReasons: unsupported revoke reason {Reason}", keyfactorRevokeReason); | ||
| throw new RevokeReasonNotSupportedException($"Revoke reason {keyfactorRevokeReason} is not supported. Supported values: 0 (Unspecified), 1 (KeyCompromise), 3 (AffiliationChanged), 4 (Superseded), 5 (CessationOfOperation)."); | ||
| } |
Comment on lines
+118
to
+125
| | Reason Code | Reason Name | HydrantId API Value | | ||
| |-------------|-------------|---------------------| | ||
| | 0 | Unspecified | `Unspecified` | | ||
| | 1 | Key Compromise | `KeyCompromise` | | ||
| | 2 | CA Compromise | `CaCompromise` | | ||
| | 3 | Affiliation Changed | `AffiliationChanged` | | ||
| | 4 | Superseded | `Superseded` | | ||
| | 5 | Cessation of Operation | `CessationOfOperation` | |
| <PackageReference Include="Keyfactor.PKI" Version="5.5.0" /> | ||
| <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||
| <PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" /> | ||
| <PackageReference Include="System.Drawing.Common" Version="8.0.25" /> |
| |-------------|-------------|---------------------| | ||
| | 0 | Unspecified | `Unspecified` | | ||
| | 1 | Key Compromise | `KeyCompromise` | | ||
| | 2 | CA Compromise | `CaCompromise` | |
Comment on lines
260
to
+270
| public async Task Synchronize(BlockingCollection<AnyCAPluginCertificate> blockingBuffer, DateTime? lastSync, bool fullSync, CancellationToken cancelToken) | ||
| { | ||
| using var flow = new FlowLogger(_logger, $"Synchronize(fullSync={fullSync})"); | ||
| _logger.MethodEntry(); | ||
| _logger.LogTrace("Synchronize: lastSync={LastSync}, fullSync={FullSync}", lastSync?.ToString() ?? "(null)", fullSync); | ||
| _requestManager = new RequestManager(); | ||
|
|
||
| var certs = new BlockingCollection<ICertificatesResponseItem>(100); | ||
| var client = new HydrantIdClient(Config); | ||
| var processedCount = 0; | ||
| var skippedCount = 0; |
| // required by applicable law or agreed to in writing, software distributed | ||
| // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES | ||
| // OR CONDITIONS OF ANY KIND, either express or implied. See the License for | ||
| // thespecific language governing permissions and limitations under the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge release-1.0 to main - Automated PR