Skip to content

Merge 1.0.3 to main#10

Open
indrora wants to merge 4 commits into
mainfrom
release-1.0
Open

Merge 1.0.3 to main#10
indrora wants to merge 4 commits into
mainfrom
release-1.0

Conversation

@indrora
Copy link
Copy Markdown
Member

@indrora indrora commented May 19, 2026

Merge release-1.0 to main - Automated PR

bhillkeyfactor and others added 4 commits December 2, 2025 10:28
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>
Copilot AI review requested due to automatic review settings May 19, 2026 16:50
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Enabled CA-connection flag and broader guard clauses/logging refactors across plugin/client code (including the new FlowLogger utility).
  • 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 an AnyCAPluginCertificate with 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 empty CertRequestBodyValidity when period is 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 an ArgumentException for 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" />
Comment thread README.md
|-------------|-------------|---------------------|
| 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
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.

3 participants