Skip to content

81018 adding jea support - #185

Merged
indrora merged 60 commits into
release-4.0from
81018-Adding_JEA_Support
Aug 10, 2026
Merged

81018 adding jea support#185
indrora merged 60 commits into
release-4.0from
81018-Adding_JEA_Support

Conversation

@rcpokorny

Copy link
Copy Markdown
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings May 11, 2026 22:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces JEA (Just Enough Administration) support for WinRM-based remote execution by refactoring the extension’s PowerShell surface into installable modules/role capabilities, wiring a new JEAEndpointName job property through the orchestrator, and updating tests/docs to cover the new behavior.

Changes:

  • Add JEAEndpointName support end-to-end (job properties → PSHelper session creation → integration/unit tests).
  • Replace monolithic WinCertScripts.ps1 script injection with modular PowerShell (Keyfactor.WinCert.Common/IIS/SQL) plus JEA .psrc role capability files and a .pssc session configuration template.
  • Update documentation (README + docsource) and integration tests to reflect JEA setup and connection selection.

Reviewed changes

Copilot reviewed 67 out of 68 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
WindowsCertStore.UnitTests/WindowsCertStore.UnitTests.csproj Adds Moq/Newtonsoft.Json; sets xUnit VS runner PrivateAssets metadata.
WindowsCertStore.UnitTests/PSHelperUnitTests.cs Updates script folder name lookup from PowerShellScripts to PowerShell.
WindowsCertStore.UnitTests/PSHelperConfigTests.cs Adds unit tests for PSHelper constructors, script directory discovery, and LocalMachine+JEA guard behavior.
WindowsCertStore.UnitTests/JobPropertiesTests.cs Adds unit tests validating JobProperties defaulting + legacy field tolerance.
WindowsCertStore.IntegrationTests/WinSQLIntegrationTests.cs Adds Integration trait; passes JEAEndpointName; uses SQL-only connection data source.
WindowsCertStore.IntegrationTests/WinIISIntegrationTests.cs Adds Integration trait; passes JEAEndpointName; uses IIS-only connection data source.
WindowsCertStore.IntegrationTests/WinCertIntegrationTests.cs New WinCert E2E integration tests (Add/Inventory/Remove and renewal flow) with JEA support.
WindowsCertStore.IntegrationTests/servers.json Expands server definitions with StoreType + JEA endpoint name.
WindowsCertStore.IntegrationTests/Factories/ConnectionFactory.cs Refactors connection loading, adds store-type filtering and env/appsettings credential sourcing.
WindowsCertStore.IntegrationTests/ClientConnection.cs Adds StoreType and JEAEndpointName to connection model.
README.md Adds detailed JEA documentation and updates WinRM port references (5985/5986).
docsource/content.md Adds detailed JEA documentation for generated docs; notes module install requirements for JEA.
IISU/WindowsCertStore.csproj Updates packaging to include new PowerShell\ module tree + .pssc and legacy scripts.
IISU/RemoteSettings.cs Adds JEAEndpointName to remote settings model.
IISU/PSHelper.cs Adds JEA endpoint support (WinRM ConfigurationName), blocks LocalMachine+JEA, changes script loading strategy, improves Information stream handling.
IISU/Properties/AssemblyInfo.cs Exposes internals to unit/integration test assemblies.
IISU/PowerShellScripts/WinCertScripts.ps1 Removes legacy monolithic script.
IISU/PowerShell/WinADFSScripts.ps1 Adjusts logging to use Information stream “[VERBOSE] …” convention.
IISU/PowerShell/Keyfactor.WinCert.SQL/RoleCapabilities/Keyfactor.WinCert.SQL.psrc New SQL JEA role capability definition.
IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Remove-KeyfactorSQLCertificate.ps1 New SQL unbind function.
IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1 New SQL bind function wrapper.
IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Get-KeyfactorSQLInventory.ps1 New SQL inventory function.
IISU/PowerShell/Keyfactor.WinCert.SQL/Private/Set-KeyfactorSQLCertificateBinding.ps1 New SQL bind implementation (registry + ACL + optional restart).
IISU/PowerShell/Keyfactor.WinCert.SQL/Private/Get-KeyfactorSQLServiceUser.ps1 New helper to read SQL service user.
IISU/PowerShell/Keyfactor.WinCert.SQL/Private/Get-KeyfactorSQLServiceName.ps1 New helper to compute SQL service name.
IISU/PowerShell/Keyfactor.WinCert.SQL/Keyfactor.WinCert.SQL.psm1 New SQL module entry point with explicit dot-sourcing + exports.
IISU/PowerShell/Keyfactor.WinCert.IIS/RoleCapabilities/Keyfactor.WinCert.IIS.psrc New IIS JEA role capability definition.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISSiteBinding.ps1 New IIS binding removal function with IIS drive autodetect.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISCertificateIfUnused.ps1 New IIS certificate cleanup helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1 New IIS binding creation with SSL flags handling and appcmd fallback.
IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Get-KeyfactorIISBoundCertificates.ps1 New IIS inventory function.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Test-ValidSslFlags.ps1 New SSL flag validation helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Test-IISDrive.ps1 New IIS:\ drive availability helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1 New OS-build-based SSL flag support helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-IISManagementInfo.ps1 New IIS management mode detection helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Add-IISBindingWithSSL.ps1 New IIS binding add + SSL attach helper.
IISU/PowerShell/Keyfactor.WinCert.IIS/Keyfactor.WinCert.IIS.psm1 New IIS module entry point with explicit dot-sourcing + exports.
IISU/PowerShell/Keyfactor.WinCert.Common/RoleCapabilities/Keyfactor.WinCert.Common.psrc New common JEA role capability definition.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1 New common remove-from-store implementation.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/New-KeyfactorResult.ps1 New common structured result helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/New-KeyfactorODKGEnrollment.ps1 New ODKG CSR generation function.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Import-KeyfactorSignedCertificate.ps1 New signed cert import helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Get-KeyfactorCertificates.ps1 New common inventory function.
IISU/PowerShell/Keyfactor.WinCert.Common/Public/Add-KeyfactorCertificate.ps1 New common add-to-store implementation.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Validate-CryptoProvider.ps1 New provider validation helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Test-CryptoServiceProvider.ps1 New provider existence helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Get-CryptoProviders.ps1 New CSP discovery helper using certutil.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Get-CertificateSAN.ps1 New SAN extraction helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Get-CertificateCSP.ps1 New CSP/KSP detection helper (CAPI + CNG).
IISU/PowerShell/Keyfactor.WinCert.Common/Private/Convert-DNSSubject.ps1 New DN subject parsing helper.
IISU/PowerShell/Keyfactor.WinCert.Common/Keyfactor.WinCert.Common.psm1 New Common module entry point with explicit dot-sourcing + exports.
IISU/PowerShell/Build/KeyfactorWinCert.pssc New JEA session configuration template (RestrictedRemoteServer + transcripts + role mapping).
IISU/Models/JobProperties.cs Adds JEAEndpointName job property.
IISU/ImplementedStoreTypes/WinSQL/WinSqlBinding.cs Switches to new SQL module function names.
IISU/ImplementedStoreTypes/WinSQL/Management.cs Wires JEAEndpointName; switches to new module function names.
IISU/ImplementedStoreTypes/WinSQL/Inventory.cs Wires JEAEndpointName; switches to new inventory function name and signature.
IISU/ImplementedStoreTypes/WinIIS/WinIISBinding.cs Switches to new IIS module function names; updates unbind parameter shape and result parsing.
IISU/ImplementedStoreTypes/WinIIS/Management.cs Wires JEAEndpointName; switches to new module function names.
IISU/ImplementedStoreTypes/WinIIS/Inventory.cs Wires JEAEndpointName; switches to new IIS inventory function name.
IISU/ImplementedStoreTypes/WinADFS/Inventory.cs Removes SAN field propagation for ADFS inventory parameters.
IISU/ImplementedStoreTypes/Win/WinInventory.cs Marks unused class obsolete.
IISU/ImplementedStoreTypes/Win/WinCertCertificateInfo.cs Removes SAN field from WinCert cert info model.
IISU/ImplementedStoreTypes/Win/Management.cs Wires JEAEndpointName; switches to new module function names.
IISU/ImplementedStoreTypes/Win/Inventory.cs Wires JEAEndpointName; switches to new inventory function name; removes SAN parameter propagation.
IISU/ClientPSCertStoreReEnrollment.cs Wires JEAEndpointName; switches to new ODKG/import function names; updates log strings.
CHANGELOG.md Adds 4.0.0 entry documenting SAN removal and JEA support.
.vscode/launch.json Adds VS Code launch configuration for PowerShell.
.gitignore Ignores local.runsettings to avoid committing local credentials.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +22 to +29
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true)
.Build();

// 3. Retrieve connection details from configuration
var vault = new VaultHelper(config);
return (vault.GetSecret("Username"), vault.GetSecret("Password"));
}
Comment thread IISU/PSHelper.cs Outdated

try {
Write-Information "Entering PowerShell Script Add-KeyfactorCertificateToStore"
Write-Information "[VERBOSE] Add-KeyfactorCertificateToStore - Received: StoreName: '$StoreName', CryptoServiceProvider: '$CryptoServiceProvider', Base64Cert: '$Base64Cert'"
Comment on lines +77 to +78
Write-Information "[VERBOSE] Running certutil with arguments: $argLine"

Comment on lines +10 to +15
if ($serviceUser) {
return $serviceUser
} else {
Write-Error "SQL Server instance '$SQLInstanceName' not found or no service user associated."
return $null
}
Comment thread CHANGELOG.md
@@ -1,3 +1,7 @@
4.0.0
* As of this version of the extension, SANs will be handled through the ODKG Enrollment page in Command and will no longer use the SAN Entry Parameter. This version, we are removing all support for the SAN Entry Parameter. If you are still using the SAN Entry Parameter, you will need to remove it from your store types and re-run inventory to remove it from your database.
* Adding JEA Support for local PowerShell execution. This will allow for more secure execution of the extension when running in a local PowerShell Runspace. To utilize this feature, you will need to create a JEA endpoint on the target server and specify the endpoint name as a new parameter in the specific Cert Store definition. Refer to the README for more details.
Comment on lines +28 to +34
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

Comment on lines 286 to 301
_results = _psHelper.ExecutePowerShell("Add-KFCertificateToStore", parameters);
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");

Comment on lines +269 to +285
_results = _psHelper.ExecutePowerShell("Add-KFCertificateToStore", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KeyfactorCertificate)");
Comment on lines 149 to 164
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KeyfactorCertificate)");

Copilot AI review requested due to automatic review settings May 12, 2026 16:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 72 out of 145 changed files in this pull request and generated 11 comments.

Comment on lines +4 to +8
[string]$StorePath,

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
)
Comment on lines +31 to +33
Set-Location -Path "Cert:\LocalMachine\$StoreName"

$importResult = Import-Certificate -FilePath $cerFilename
Comment on lines +28 to +36
Write-Information "[VERBOSE] Instance: $instance"
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
Comment on lines +35 to +46
if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Write-Information "Renewal thumbprint matches for instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
} elseif (-not $RenewalThumbprint) {
Write-Information "No renewal thumbprint provided. Binding certificate to instance: $fullInstance"
$result = Set-KeyfactorSQLCertificateBinding -InstanceName $instance -NewThumbprint $NewThumbprint -RestartService:$RestartService
}

if (-not $result) {
Write-Error "Failed to bind certificate for instance: $instance"
$bindingSuccess = $false
}
Comment on lines +11 to +15
return $serviceUser
} else {
Write-Error "SQL Server instance '$SQLInstanceName' not found or no service user associated."
return $null
}
Comment on lines +41 to +44
var (username, password) = GetCredentials();
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
yield break;

Comment on lines +299 to 301
_results = _psHelper.ExecutePowerShell("Add-KeyfactorCertificate", parameters);
_logger.LogTrace("Returned from executing PS function (Add-KFCertificateToStore)");

Comment on lines 164 to 168
case "Skipped":
psResult = OrchestratorJobStatusJobResult.Failure;
failureMessage = ($"PowerShell function New-KFIISSiteBinding failed on step: {step} - message:\n {errorMessage}");
failureMessage = ($"PowerShell function New-KeyfactorIISSiteBinding failed on step: {step} - message:\n {errorMessage}");
_logger.LogDebug(failureMessage);
break;
Comment on lines +4 to 6
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

Comment on lines +1 to +8
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert
Copilot AI review requested due to automatic review settings May 12, 2026 16:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 72 out of 145 changed files in this pull request and generated 12 comments.

Comment on lines +8 to +14
$serviceUser = (Get-CimInstance -ClassName Win32_Service -Filter "Name='$SQLServiceName'").StartName

if ($serviceUser) {
return $serviceUser
} else {
Write-Error "SQL Server instance '$SQLInstanceName' not found or no service user associated."
return $null
Comment on lines +29 to +35
Write-Information "[VERBOSE] Full Instance: $fullInstance"
Write-Information "[VERBOSE] Registry Location: $regLocation"
Write-Information "[VERBOSE] Current Thumbprint: $currentThumbprint"

$currentThumbprint = Get-ItemPropertyValue -Path $regLocation -Name "Certificate" -ErrorAction SilentlyContinue

if ($RenewalThumbprint -and $RenewalThumbprint -contains $currentThumbprint) {
Comment on lines +24 to +26
Write-Information "Entering PowerShell Script: New-KFIISSiteBinding" -InformationAction SilentlyContinue
Write-Information "[VERBOSE] Parameters: $(($PSBoundParameters.GetEnumerator() | ForEach-Object { "$($_.Key): '$($_.Value)'" }) -join ', ')"

Comment on lines +113 to +117
catch {
$errorMessage = "Unexpected error in New-KFIISSiteBinding: $($_.Exception.Message)"
Write-Error $errorMessage
return New-KeyfactorResult -Status Error -Code 999 -Step UnexpectedError -ErrorMessage $errorMessage
}
Comment on lines +12 to +16
if ($build -ge 20348) {
# Windows Server 2022+ (IIS 10.0.20348+)
Write-Information "[VERBOSE] Detected Windows Server 2022 or later (Build: $build)"
return @(1, 4, 8, 16, 32, 64) # Include unknowns for testing
}
Comment on lines +5 to +8

[parameter(ParameterSetName = $false)]
[switch]$IsAlias
)
Comment on lines +31 to +33
Set-Location -Path "Cert:\LocalMachine\$StoreName"

$importResult = Import-Certificate -FilePath $cerFilename
Comment on lines +2 to +6
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "" },
{ "Machine": "192.168.230.139", "StoreType": "WinIIS", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "{SQL-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "" },
{ "Machine": "{SQL-JEA-Server-IP-or-Hostname}", "StoreType": "WinSQL", "JEAEndpointName": "keyfactor.wincert" },
{ "Machine": "192.168.230.139", "StoreType": "WinCert", "JEAEndpointName": "" },
Comment on lines +1 to +8
#!/bin/bash
# Store Type creation script using kfutil
# Generated by Doctool

# Creates all 4 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.
set -e

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi
echo "Creating store type: WinCert"
kfutil store-types create WinCert
Comment on lines +1 to +8
# Store Type creation script using kfutil
# Generated by Doctool

# Uncomment if kfutil is not in your PATH
# Set-Alias -Name kfutil -Value 'C:\Program Files\Keyfactor\kfutil\kfutil.exe'
Write-Host "Creating store type: WinCert"
kfutil store-types create WinCert

if ($null -eq (Get-Command "kfutil" -ErrorAction SilentlyContinue)) {
Write-Host "kfutil could not be found. Please install kfutil"
Write-Host "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
}
Write-Host "Creating store type: IISU"
kfutil store-types create IISU
Copilot AI review requested due to automatic review settings July 24, 2026 19:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (11)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:32

  • $currentThumbprint is logged before it is assigned, and the renewal-thumbprint comparison uses -contains against a string (which won’t behave as intended). Also, when a renewal thumbprint is provided but doesn’t match, $result is never set, causing the bind to be treated as a failure.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Import-KeyfactorSignedCertificate.ps1:34
  • Import-Certificate requires a -CertStoreLocation (and changing location via Set-Location is a side effect that can leak outside the function). This currently risks importing to the wrong store or failing outright.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:7
  • [Parameter(ParameterSetName = $false)] is not a valid use of ParameterSetName and can cause confusing parameter binding behavior. This switch should just be a normal optional parameter.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:22
  • $store.Remove($cert) expects a single X509Certificate2, but $cert here is the result of a pipeline filter and can be a collection. That will either throw or remove unpredictably when multiple matches exist (e.g., alias collisions).
    IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1:24
  • The log message still references the old function name New-KFIISSiteBinding, which makes troubleshooting harder now that the function is New-KeyfactorIISSiteBinding.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1:116
  • The thrown/captured error message still references New-KFIISSiteBinding, which no longer matches the function name and will mislead operators when diagnosing failures.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1:16
  • For Windows Server 2022+ this returns flag bits marked as "Include unknowns for testing" (16/32/64). That causes Test-ValidSslFlags to accept unsupported flags in production. The valid-bit list should only include IIS-documented sslFlags bits for the target OS/IIS version (or be discovered dynamically).
    WindowsCertStore.IntegrationTests/servers.json:6
  • This integration-test config currently hardcodes a specific private IP (192.168.230.139). That makes the repo environment-specific and risks accidentally leaking internal infrastructure details. Prefer placeholders/example values only.
    scripts/store_types/bash/kfutil_create_store_types.sh:5
  • The script now assumes kfutil is installed and available, so failures will be a generic "command not found". Adding an explicit availability check improves usability and makes CI failures clearer. Also, using /usr/bin/env bash is more portable than hardcoding /bin/bash.
    scripts/store_types/powershell/kfutil_create_store_types.ps1:5
  • The script assumes kfutil is installed/available; when it isn’t, users get a less actionable error. Add an explicit Get-Command check to fail fast with guidance.
    WindowsCertStore.UnitTests/SANsUnitTests.cs:86
  • This test can be simplified: both null and "" are expected to yield an empty result, and the commented-out assert should be removed to avoid confusion.

Copilot AI review requested due to automatic review settings July 24, 2026 19:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:35

  • $currentThumbprint is logged before it’s assigned, and the renewal check uses -contains (collection membership) which won’t work for comparing thumbprint strings. When $RenewalThumbprint is provided but doesn’t match, $result is never set, so the function will report failure even though it should simply skip binding for that instance.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:8
  • [parameter(ParameterSetName = $false)] is not a valid use of ParameterSetName and can create an unintended parameter set named False. If there’s only one parameter set here, the attribute line should be removed (or replaced with a normal [Parameter()]).
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:29
  • $store.Remove($cert) will fail when $cert is a collection (e.g., multiple matches from Where-Object). Iterate and remove each certificate explicitly (and keep behavior consistent for single/multiple matches).
    IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1:16
  • The Server 2022+ branch advertises unsupported/unknown flag bits (16, 32, 64) as valid (per the comment), while the validator also treats bit 0x2 (CentralCertStore) as a known flag (see Test-ValidSslFlags), but 0x2 is not included in the 2022+ valid list. This makes validation inconsistent and can allow invalid flags through (or incorrectly reject CentralCertStore).
    WindowsCertStore.UnitTests/SANsUnitTests.cs:96
  • This theory contains a commented-out assert and redundant branching (legacySan == null and legacySan == string.Empty both expect the same result). This makes the test harder to read and maintain without changing behavior.

Copilot AI review requested due to automatic review settings July 24, 2026 20:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (9)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:33

  • $currentThumbprint is logged before it is assigned, so the verbose output will always be empty/incorrect. Assign the value first, then log it.
    IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:41
  • Renewal thumbprint matching uses -contains against a string and has no branch when a non-matching renewal thumbprint is provided. This can cause bindings to be skipped silently and $result to be uninitialized (treated as failure). Split the renewal thumbprint list and explicitly handle the non-match case.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1:16
  • This function claims to return valid SslFlags bits, but the WS2022+ branch explicitly includes "unknowns for testing" and also omits bit 0x2 (CentralCertStore) even though Test-ValidSslFlags checks for it. This will incorrectly reject legitimate flag combinations and/or accept unsupported bits.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1:24
  • The informational log line still references the old function name New-KFIISSiteBinding, which makes troubleshooting confusing.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1:117
  • The catch block error message still references the old function name New-KFIISSiteBinding, which can mislead during incident triage.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:8
  • [Parameter(ParameterSetName = $false)] is not a meaningful parameter set name and will be coerced to the literal string "False". If you don't intend to use parameter sets here, remove this attribute to avoid confusing parameter metadata.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:35
  • $cert can be an array (multiple matches), but X509Store.Remove() expects a single X509Certificate2. Also, throwing when the certificate isn't found forces the caller into exception handling for a common "not found" outcome. Iterate over matches and return $false when nothing is found.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:42
  • The catch block rethrows (throw $_), which will fail the remote PowerShell invocation with an exception rather than returning a simple success/failure signal. Since this function already tracks $isSuccessful, prefer returning $false from the catch block.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Import-KeyfactorSignedCertificate.ps1:33
  • Set-Location changes the caller's current location and isn't restored, which can have surprising side effects in long-lived runspaces. Import-Certificate supports importing directly to a certificate store location, so you can avoid changing location entirely.

Comment on lines 38 to +39
var json = File.ReadAllText("servers.json");
var machines = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
var connections = JsonConvert.DeserializeObject<List<ClientConnection>>(json) ?? new();
Copilot AI review requested due to automatic review settings July 24, 2026 20:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (8)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:35

  • $currentThumbprint is logged before it’s assigned, and the renewal-thumbprint check uses -contains on a string (which will never match). This can cause renewal matching to fail even when the thumbprints are identical.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:7
  • ParameterSetName = $false is not a valid value for the [Parameter()] attribute and can cause parameter binding/parse errors. If this switch isn’t part of a parameter set, omit ParameterSetName entirely.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1:16
  • This returns flag values explicitly marked as “unknowns for testing”. That makes Test-ValidSslFlags accept unsupported SslFlags bits in production, defeating the validation.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Import-KeyfactorSignedCertificate.ps1:33
  • Using Set-Location to change the session’s current provider path is a side effect that can break subsequent operations in the same runspace. Import-Certificate supports importing directly to a target store via -CertStoreLocation.
    IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Get-KeyfactorSQLInventory.ps1:51
  • $cert.PrivateKey.CspKeyContainerInfo.ProviderName can throw or be $null for CNG/ECC keys. The Common module already has Get-CertificateCSP to safely resolve provider/KSP names; using it here avoids inventory failures on non-CSP certificates.
    WindowsCertStore.IntegrationTests/servers.json:3
  • This integration-test config file now contains a concrete private IP address (192.168.230.139). Committing environment-specific addresses makes the tests/docs harder to reuse and can leak internal network details; prefer placeholders like the existing {SQL-...} entries.
    integration-manifest.json:352
  • This PR is titled as adding JEA support, but this change flips WinSql SupportedOperations.Enrollment from false to true, which is a functional capability change for the store type. Please confirm this is intentional and update the PR description/release notes accordingly (or revert if accidental).
    scripts/store_types/bash/kfutil_create_store_types.sh:1
  • Using a hardcoded #!/bin/bash shebang reduces portability (e.g., systems where bash is not at /bin/bash). #!/usr/bin/env bash is more robust and matches the previous version.

Comment on lines +44 to +50
Add-Type -Path "$env:windir\System32\inetsrv\Microsoft.Web.Administration.dll"
$iis = New-Object Microsoft.Web.Administration.ServerManager
$site = $iis.Sites[$SiteName]

$httpsBindings = $site.Bindings | Where-Object {
$_.BindingInformation -eq $BindingInfo -and $_.Protocol -eq "https"
}
Copilot AI review requested due to automatic review settings July 24, 2026 21:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (5)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:41

  • $currentThumbprint is logged before it’s assigned, and -contains is the wrong operator for checking whether a (comma-separated) renewal thumbprint string matches the currently bound thumbprint. This can cause false mismatches (or always-fail) renewals and also makes $result potentially uninitialized when a renewal thumbprint is provided but doesn’t match.
    IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Get-KeyfactorSQLInventory.ps1:51
  • Provider name extraction uses $cert.PrivateKey.CspKeyContainerInfo.ProviderName, which breaks for CNG-backed keys (e.g., RSACng/ECDsa) because CspKeyContainerInfo isn’t available. The Common module already provides Get-CertificateCSP which handles both legacy CSP and CNG keys.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:6
  • [parameter(ParameterSetName = $false)] is invalid/misleading here (ParameterSetName expects a string). As written it coerces to the literal set name "False", which can cause confusing parameter binding behavior.
    WindowsCertStore.IntegrationTests/servers.json:7
  • This committed servers.json includes a specific private IP (192.168.230.139). This makes the repo’s default integration-test config non-portable and risks leaking internal environment details. Prefer placeholders only (or document that users should copy to a local, untracked file).
    IISU/ImplementedStoreTypes/WinAdfs/AdfsCertificateRotationManager.cs:559
  • The catch (Exception) { throw; } block is redundant and adds noise without changing behavior. Removing it keeps the control flow clearer.
            catch (Exception)
            {
                throw;
            }

Copilot AI review requested due to automatic review settings July 27, 2026 16:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (6)

IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:36

  • $currentThumbprint is logged before it is assigned, and the renewal check uses -contains against a string (which is not the right operator for string equality / thumbprint matching). This can cause misleading logs and may prevent the renewal path from ever triggering.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:7
  • [parameter(ParameterSetName = $false)] is not a valid attribute usage (ParameterSetName expects a string). This will fail to parse when the function is loaded.
    WindowsCertStore.IntegrationTests/Factories/ConnectionFactory.cs:43
  • LoadConnections() reads servers.json unconditionally. If the file is missing (common in CI or local unit-only runs), this throws before the method can yield break, causing the integration theories to error rather than simply producing no test cases.
    WindowsCertStore.IntegrationTests/servers.json:7
  • This file now includes environment-specific private IP addresses. This makes the repo less portable (and can cause accidental connection attempts) for anyone running integration tests without your lab environment. Consider keeping only placeholders (or moving concrete values to an untracked/local file).
    IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Get-KeyfactorSQLInventory.ps1:51
  • $cert.PrivateKey.CspKeyContainerInfo.ProviderName is not safe for CNG keys (and PrivateKey is deprecated); it can throw or return null depending on key type. Since the Common module already provides Get-CertificateCSP, use it here to avoid inventory failures on non-CSP certificates.
    scripts/store_types/bash/kfutil_create_store_types.sh:1
  • Using #!/bin/bash is less portable than #!/usr/bin/env bash (e.g., systems where bash is not at /bin/bash). The previous shebang was more robust for cross-platform environments.

Copilot AI review requested due to automatic review settings July 27, 2026 16:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 83 out of 163 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (11)

IISU/PowerShell/Keyfactor.WinCert.Common/Public/Remove-KeyfactorCertificate.ps1:7

  • [parameter(ParameterSetName = $false)] is not a valid value for ParameterSetName (it must be a string). This will throw during parameter binding and prevent the function from running.
    IISU/PowerShell/Keyfactor.WinCert.SQL/Public/New-KeyfactorSQLBinding.ps1:32
  • $currentThumbprint is logged before it’s assigned, and the renewal check uses -contains against a string. As written, a non-matching renewal thumbprint leaves $result unset ($null) and the function reports a failure without an actionable reason.
    IISU/PowerShell/Keyfactor.WinCert.SQL/Public/Get-KeyfactorSQLInventory.ps1:51
  • $cert.PrivateKey.CspKeyContainerInfo.ProviderName can throw (or be null) for certificates without a private key and for CNG-backed keys. The Common module already provides Get-CertificateCSP to safely resolve the provider.
    IISU/PowerShell/Keyfactor.WinCert.Common/Public/Import-KeyfactorSignedCertificate.ps1:33
  • Changing the process location with Set-Location and never restoring it can break subsequent commands executed in the same runspace. Import-Certificate supports importing directly to a store location, so no location change is needed.
    IISU/PowerShell/Keyfactor.WinCert.IIS/Private/Get-ValidSslFlagsForSystem.ps1:16
  • Get-ValidSslFlagsForSystem currently returns extra bits (32, 64) explicitly labeled “unknowns for testing”. This makes Test-ValidSslFlags accept unsupported flags on Server 2022+ and defeats the purpose of validation.
    WindowsCertStore.IntegrationTests/Factories/ConnectionFactory.cs:43
  • When credentials aren’t available, LoadConnections() yield breaks, which results in [MemberData] providing no data and xUnit failing the theory with “No data found…”. Prefer explicitly skipping integration tests when not configured.
    WindowsCertStore.IntegrationTests/servers.json:7
  • servers.json includes a hard-coded internal IP address (192.168.230.139). Committing environment-specific hostnames/IPs can leak infrastructure details and makes the repo less portable; prefer placeholders like the SQL entries already use.
    scripts/store_types/bash/kfutil_create_store_types.sh:6
  • The script now hard-codes /bin/bash and assumes kfutil is installed. Using #!/usr/bin/env bash is more portable, and a quick command -v check produces a clearer failure mode.
    scripts/store_types/powershell/kfutil_create_store_types.ps1:6
  • The script now assumes kfutil is available and authenticated; if it isn’t, users get a confusing command-not-found or auth error mid-script. A small upfront check makes failures clearer.
    integration-manifest.json:213
  • Display name has an inconsistent spelling: "JEA End Point Name" → "JEA Endpoint Name".
    integration-manifest.json:420
  • Display name has an inconsistent spelling: "JEA End Point Name" → "JEA Endpoint Name".

Comment thread integration-manifest.json
},
{
"Name": "JEAEndpointName",
"DisplayName": "JEA End Point Name",
@indrora
indrora merged commit f8d73eb into release-4.0 Aug 10, 2026
1 check passed
indrora added a commit that referenced this pull request Aug 11, 2026
* 81018 adding jea support (#185)

* Initial JEA for WinCert

* Update generated docs

* Helper updates

* Updated spelling of PowerShell script and fixed Information Messages from PW

* Added JEA support for IIS

* Fixed and updated IIS Components

* Completed SQL Module and updated test projects

* Testing

* Removed WinCertScripts from extension.

* changed way LocalHost and JEA are configured.

* Fixed ODKG missing file error

* Updated KF Import of Signed Certificates PowerShell Script

* Fixed missing PowerShell script not being found.

* Fix missing path

* Updated documentation to include JEA information.

* Update generated docs

* chore(ci): Update build workflow to v5

* docs: auto-generate README and documentation [skip ci]

* Update generated docs

* docs: auto-generate README and documentation [skip ci]

* docs: auto-generate README and documentation [skip ci]

* Adding dotnet 10 support

* modified:   IISU/PowerShell/Build/KeyfactorWinCert.pssc
	modified:   docsource/content.md

* docs: auto-generate README and documentation [skip ci]

* Updated packages to support dotnet 10

* Updating Unit Tests

* Fixed timeout issue when migrating to dotnet 10

* modified:   IISU/PSHelper.cs

* Remove .net6 libraries and support

* docs: auto-generate README and documentation [skip ci]

* #86137 Cleaned up messages returned to Command

* Updated language for WinSQL binding concerns

* docs: auto-generate README and documentation [skip ci]

* Updated JEA Documentation
Fixed SQL Restart issue

* docs: auto-generate README and documentation [skip ci]

* Added diagnostic cmdlet

* Updated the JEA documentation.  Added the get-keyfactordiagnostics cmdlet for troubleshooting.

* docs: auto-generate README and documentation [skip ci]

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Updated error reporting when bad CSP

* Updated PS scripts to get CSPs from registry not certutil.

* docs: auto-generate README and documentation [skip ci]

* Fixed formatting issue in CHANGELOG

* Updated the Get-KeyfactorIISBoundCertificates.ps1 script to include support for JEA (Just Enough Administration) environments. Added a new documentation file for setting up an SSH development environment.

* docs: auto-generate README and documentation [skip ci]

* Changes to be committed:
	modified:   IISU/ImplementedStoreTypes/WinIIS/Management.cs
	modified:   IISU/PowerShell/Keyfactor.WinCert.Common/Keyfactor.WinCert.Common.psm1
	new file:   IISU/PowerShell/Keyfactor.WinCert.Common/Private/Test-KeyfactorAdminRights.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.Common/Public/New-KeyfactorResult.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.Common/RoleCapabilities/Keyfactor.WinCert.Common.psrc
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Get-KeyfactorIISBoundCertificates.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/New-KeyfactorIISSiteBinding.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISCertificateIfUnused.ps1
	modified:   IISU/PowerShell/Keyfactor.WinCert.IIS/Public/Remove-KeyfactorIISSiteBinding.ps1

* Updated PowerShell initialization to check for appropriate permissions when running IIS jobs.

* Fixed null error when testing for admin
Fixed tempfile left behind when using ssh

* added more logging to chase Ssh issue when running in docker containers.

* Updating logging

* logging

* chasing issue with ssh

* Moved try/catch

* Fixed issue with test-admin check function not being found in IIS/SQL

* docs: auto-generate README and documentation [skip ci]

---------

Co-authored-by: Bob Pokorny <bpokorny@keyfactor.com>
Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io>
Co-authored-by: spbsoluble <1661003+spbsoluble@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update integration-manifest.json (#190)

---------

Co-authored-by: Bob Pokorny <55611381+rcpokorny@users.noreply.github.com>
Co-authored-by: Bob Pokorny <bpokorny@keyfactor.com>
Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io>
Co-authored-by: spbsoluble <1661003+spbsoluble@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@rcpokorny
rcpokorny deleted the 81018-Adding_JEA_Support branch August 12, 2026 21:08
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.

4 participants