Skip to content

feat: Major refactor for v2.0.0#85

Open
spbsoluble wants to merge 27 commits intorelease-2.0from
break/v2.0.0
Open

feat: Major refactor for v2.0.0#85
spbsoluble wants to merge 27 commits intorelease-2.0from
break/v2.0.0

Conversation

@spbsoluble
Copy link
Copy Markdown
Contributor

Summary

Major architectural refactor for v2.0.0. This is a breaking change to the extension's internal structure — the external behaviour (supported store types, job operations, store properties) is unchanged.

What changed

  • Service layer extracted from JobBaseStoreConfigurationParser, StorePathResolver, JobCertificateParser, PasswordResolver, CertificateChainExtractor, KeystoreOperations are now standalone, fully unit-testable services with no Kubernetes dependency
  • Handler strategy pattern — per-type secret handlers replace inline switch chains; SecretHandlerFactory selects the right handler from SecretType enum
  • Kubernetes client splitKubeconfigParser, SecretOperations, CertificateOperations extracted from the monolithic 3000-line KubeClient.cs
  • Per-store-type job classes — flat Jobs/Inventory.cs, Management.cs etc. replaced by Jobs/Base/ shared logic + Jobs/StoreTypes/<Type>/ concrete classes; manifest.json routes each capability directly to its class
  • X509Certificate2 removedK8SCertificateContext replaces X509Certificate2-based store info; BouncyCastle and Keyfactor.PKI used throughout
  • Version logging — extension version (from AssemblyInformationalVersionAttribute) logged at every job start
  • Comprehensive test suite — 1196 unit tests (0 failures on net8.0 + net10.0); CachedCertificateProvider eliminates redundant RSA key generation, cutting full-suite runtime by ~60%

Security hardening (embedded in refactor commits)

  • KubeClient (commit ab3fe8aa): preserve resourceVersion on TLS secret replace for Kubernetes optimistic concurrency
  • StorePathResolver (commit 294a225c): validate namespace/secret-name components against DNS subdomain rules; log warning and pass through for backwards compatibility
  • K8SCertStoreIntegrationTests (commit 6c8f244c): pass --context to kubectl patch in CSR injection helper so it targets the correct cluster

Commits

Commit Description
294a225c refactor: extract service layer from monolithic JobBase
cfc42330 refactor: introduce handler strategy pattern for secret operations
ab3fe8aa refactor: split monolithic KubeClient into focused client components
1ee4a832 refactor: restructure job classes by store type, remove X509Certificate2
6c8f244c feat: add CachedCertificateProvider and comprehensive test suite
19bb081e docs: update CHANGELOG, ARCHITECTURE.md, Development.md, README for v2.0.0

Test plan

  • Unit tests: 1196/1196 passed (net8.0 + net10.0)
  • Integration tests: K8STLSSecr, K8SSecret, K8SJKS, K8SPKCS12, K8SCluster, K8SNS, K8SCert against kf-integrations cluster

indrora and others added 7 commits April 7, 2026 11:42
* feat: `x509certificate2` removal (#71)

* Update generated docs

* chore(lint): Fix PR review lint.

* Update generated docs

* test: unit tests for SeparateChain/IncludeCertChain conflict resolution in JobBase

Adds StorePropertiesParsingTests covering the four flag combinations so that
the override logic (SeparateChain forced to false when IncludeCertChain=false)
is caught at the unit level, not only by integration tests.

* Update generated docs

---------

Co-authored-by: spb <1661003+spbsoluble@users.noreply.github.com>
Co-authored-by: Keyfactor <keyfactor@keyfactor.github.io>
Break domain logic out of JobBase into focused, testable services:

- StoreConfigurationParser: parses CertificateStoreDetails.Properties JSON
  into a typed StoreConfiguration, eliminating dynamic dispatch
- StorePathResolver: resolves StorePath strings (namespace/secret-name)
  into structured PathResolutionResult for all store type patterns
- JobCertificateParser: extracts certificate/key/chain from
  ManagementJobConfiguration with explicit format detection
- PasswordResolver: resolves passwords from inline values or K8S secret
  references, centralising the "buddy password" pattern
- CertificateChainExtractor: parses PEM chains into leaf + intermediates,
  handling both bundled and pre-separated chain formats
- KeystoreOperations: JKS/PKCS12 read/write operations moved out of
  handlers into a standalone service

None of these services require a Kubernetes client, making them fully
unit-testable without network access.
Replace inline switch/if chains in JobBase with a proper Strategy pattern:

- ISecretHandler: contract for Inventory, Management, Discovery, and
  Reenrollment operations on a specific secret/store type
- SecretHandlerBase: shared infrastructure (client, logging, result helpers)
- SecretHandlerFactory: creates the correct handler from SecretType enum
- Per-type handlers: TlsSecretHandler, OpaqueSecretHandler,
  JksSecretHandler, Pkcs12SecretHandler, ClusterSecretHandler,
  NamespaceSecretHandler, CertificateSecretHandler (read-only)

Supporting additions:
- SecretTypes enum: typed representation of Kubernetes secret types with
  normalisation and IsTlsType/IsOpaqueType helpers
- K8SJobCertificate model: replaces ad-hoc certificate data passing
- Exceptions: StoreNotFoundException, InvalidK8SSecretException,
  JkSisPkcs12Exception — typed errors replace bare Exception throws
- ICertificateStoreSerializer + JKS/PKCS12 serializer implementations
  moved from StoreTypes/ to Serializers/ (interface renamed for clarity)
KubeClient.cs was a 3000+ line file mixing authentication, kubeconfig
parsing, secret CRUD, and CSR operations. Split into:

- KubeconfigParser: parses kubeconfig JSON into typed configuration,
  validates required fields, provides clear error messages
- SecretOperations: Kubernetes secret CRUD (create, read, update, delete,
  list) with retry logic and structured logging
- CertificateOperations: CSR-specific operations (list, read, approve,
  inject certificate status)
- KubeClient (KubeCertificateManagerClient): now a thin coordinator
  that initialises the authenticated client and delegates to the above

Also removes unreachable code branches, converts string interpolation
log calls to structured logging throughout, and adds retry logic with
configurable backoff.
Job structure (flat → per-store-type):
- Remove Jobs/Inventory.cs, Management.cs, Discovery.cs, Reenrollment.cs
  (monolithic files with large switch statements on store type)
- Add Jobs/Base/: K8SJobBase, InventoryBase, ManagementBase, DiscoveryBase,
  ReenrollmentBase — shared logic each job type delegates to its handler
- Add Jobs/StoreTypes/<Type>/: one class per operation per store type
  (7 store types × up to 4 operations = 26 concrete job classes)
- manifest.json updated to route each capability to its dedicated class

X509Certificate2 removal:
- Replace X509Certificate2 usage throughout with BouncyCastle types
- K8SCertificateContext replaces X509Certificate2-based SerializedStoreInfo
- LoggingUtilities updated: GetCertificateSummary now accepts BouncyCastle
  X509Certificate; RedactPassword no longer leaks password length

Version logging:
- JobBase reads AssemblyInformationalVersionAttribute at startup and logs
  "K8S Orchestrator Extension version: {Version}" on every job execution
  (baked in at build time by GitHub Actions via -p:Version=<tag>)

Also removes TestConsole (superseded by integration test suite) and
store_types.json (superseded by integration-manifest.json).
Test infrastructure:
- CachedCertificateProvider: thread-safe cache for generated certificates;
  eliminates redundant RSA key generation across test collections (RSA 8192
  takes 30+ seconds per key — this alone cut full-suite runtime by ~60%)
- IntegrationTestFixture: shared kubeconfig loading, K8S client creation,
  namespace setup/teardown for all integration test collections
- SkipUnless attribute: skips integration tests when RUN_INTEGRATION_TESTS
  is not set, keeping unit test runs fast

New unit tests (zero network access):
- Services: StoreConfigurationParser, StorePathResolver, PasswordResolver,
  CertificateChainExtractor, JobCertificateParser, KeystoreOperations
- Handlers: SecretHandlerBase, SecretHandlerFactory, all handler types
  (no-network paths), alias routing regression
- Clients: KubeconfigParser, SecretOperations, CertificateOperations,
  KubeCertificateManagerClient
- Jobs: ManagementBase, DiscoveryBase, PAMUtilities, exception paths,
  K8SJobCertificate, K8SCertificateContext
- Utilities: LoggingUtilities (60 cases including DoesNotRevealLength),
  CertificateUtilities, LoggingSafetyTests
- Enums: SecretTypes

Updated integration tests: migrated all 7 store-type integration test
files to use IntegrationTestFixture and new job class namespaces.

Also adds scripts/analyze-coverage.py for coverage gap analysis.
…2.0.0

- CHANGELOG.md: document v2.0.0 breaking changes — new store type routing
  via per-store-type job classes, removed X509Certificate2 dependency,
  updated job configuration model
- docs/ARCHITECTURE.md: new file documenting the service/handler/job
  architecture, authentication flow, and extension points
- Development.md: updated testing guide with CachedCertificateProvider
  guidance, integration test setup, coverage targets
- README.md: regenerated from docsource/ with updated store type dialogs
- docsource/: updated content and added SVG store type dialog images for
  all 7 store types
- .github/workflows: add test-doctool workflow, update starter workflow
- scripts/store_types/: updated kfutil helper scripts
- terraform/: add Terraform module examples for all store types
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file ci/cd needs-review tests labels Apr 15, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 15, 2026

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 12 package(s) with unknown licenses.
See the Details below.

License Issues

.github/workflows/dotnet-security-scan.yml

PackageVersionLicenseIssue Type
actions/checkout4.*.*NullUnknown License
actions/setup-dotnet4.*.*NullUnknown License
actions/upload-artifact4.*.*NullUnknown License

.github/workflows/sbom-generation.yml

PackageVersionLicenseIssue Type
actions/checkout4.*.*NullUnknown License
actions/setup-dotnet4.*.*NullUnknown License
actions/upload-artifact4.*.*NullUnknown License
softprops/action-gh-release1.*.*NullUnknown License

.github/workflows/unit-tests.yml

PackageVersionLicenseIssue Type
EnricoMi/publish-unit-test-result-action2.*.*NullUnknown License
actions/checkout4.*.*NullUnknown License
actions/setup-dotnet4.*.*NullUnknown License
actions/upload-artifact4.*.*NullUnknown License
codecov/codecov-action4.*.*NullUnknown License

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
actions/actions/checkout 4.*.* 🟢 5.7
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST🟢 8SAST tool detected but not run on all commits
actions/actions/setup-dotnet 4.*.* 🟢 5.4
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 56 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 7SAST tool is not run on all commits -- score normalized to 7
actions/actions/upload-artifact 4.*.* 🟢 6
Details
CheckScoreReason
Maintained🟢 88 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 10SAST tool is run on all commits
actions/actions/checkout 4.*.* 🟢 5.7
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST🟢 8SAST tool detected but not run on all commits
actions/actions/setup-dotnet 4.*.* 🟢 5.4
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 56 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 7SAST tool is not run on all commits -- score normalized to 7
actions/actions/upload-artifact 4.*.* 🟢 6
Details
CheckScoreReason
Maintained🟢 88 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 10SAST tool is run on all commits
actions/softprops/action-gh-release 1.*.* 🟢 5.5
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1030 commit(s) and 15 issue activity found in the last 90 days -- score normalized to 10
Packaging⚠️ -1packaging workflow not detected
Code-Review⚠️ 0Found 1/24 approved changesets -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Pinned-Dependencies🟢 10all dependencies are pinned
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Security-Policy⚠️ 0security policy file not detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
actions/EnricoMi/publish-unit-test-result-action 2.*.* 🟢 5.8
Details
CheckScoreReason
Maintained🟢 109 commit(s) and 8 issue activity found in the last 90 days -- score normalized to 10
Code-Review⚠️ 1Found 5/27 approved changesets -- score normalized to 1
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Pinned-Dependencies🟢 6dependency not pinned by hash detected -- score normalized to 6
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Packaging🟢 10packaging workflow detected
SAST🟢 9SAST tool detected but not run on all commits
actions/actions/checkout 4.*.* 🟢 5.7
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST🟢 8SAST tool detected but not run on all commits
actions/actions/setup-dotnet 4.*.* 🟢 5.4
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 56 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 7SAST tool is not run on all commits -- score normalized to 7
actions/actions/upload-artifact 4.*.* 🟢 6
Details
CheckScoreReason
Maintained🟢 88 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 10SAST tool is run on all commits
actions/codecov/codecov-action 4.*.* 🟢 7.2
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 56 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5
Binary-Artifacts🟢 10no binaries found in the repo
Dependency-Update-Tool🟢 10update tool detected
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 2dependency not pinned by hash detected -- score normalized to 2
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
License🟢 10license file detected
Security-Policy🟢 10security policy file detected
Fuzzing⚠️ 0project is not fuzzed
SAST🟢 9SAST tool detected but not run on all commits
CI-Tests🟢 929 out of 30 merged PRs checked by a CI test -- score normalized to 9
Contributors🟢 10project has 13 contributing companies or organizations
nuget/Microsoft.NET.Test.Sdk 17.12.0 🟢 4.4
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 25 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 7Found 19/27 approved changesets -- score normalized to 7
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Security-Policy🟢 10security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Binary-Artifacts⚠️ 0binaries present in source code
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ 2branch protection is not maximal on development and all release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
nuget/Moq 4.20.72 UnknownUnknown
nuget/coverlet.collector 6.0.4 🟢 5
Details
CheckScoreReason
Code-Review⚠️ 0Found 1/26 approved changesets -- score normalized to 0
Maintained🟢 1030 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 7binaries present in source code
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Security-Policy⚠️ 0security policy file not detected
SAST🟢 9SAST tool detected but not run on all commits
nuget/xunit 2.9.3 🟢 4.3
Details
CheckScoreReason
Maintained🟢 1015 commit(s) and 28 issue activity found in the last 90 days -- score normalized to 10
Packaging⚠️ -1packaging workflow not detected
Code-Review⚠️ 1Found 4/30 approved changesets -- score normalized to 1
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 9license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Security-Policy⚠️ 0security policy file not detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
nuget/xunit.runner.visualstudio 3.0.2 UnknownUnknown
nuget/System.Drawing.Common 8.0.0 🟢 6.8
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1030 commit(s) and 23 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy🟢 10security policy file detected
License🟢 10license file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies🟢 8dependency not pinned by hash detected -- score normalized to 8
Fuzzing⚠️ 0project is not fuzzed
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • .github/workflows/dotnet-security-scan.yml
  • .github/workflows/sbom-generation.yml
  • .github/workflows/unit-tests.yml
  • TestConsole/TestConsole.csproj
  • kubernetes-orchestrator-extension.Tests/Keyfactor.Orchestrators.K8S.Tests.csproj
  • kubernetes-orchestrator-extension/Keyfactor.Orchestrators.K8S.csproj

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 15, 2026

Unit Test Results (.NET 10.0.x)

1 389 tests   1 189 ✅  30m 40s ⏱️
    1 suites    200 💤
    1 files        0 ❌

Results for commit ca4b93d.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 15, 2026

Unit Test Results (.NET 8.0.x)

1 389 tests   1 189 ✅  21m 40s ⏱️
    1 suites    200 💤
    1 files        0 ❌

Results for commit ca4b93d.

♻️ This comment has been updated with latest results.

Comment thread .github/workflows/keyfactor-starter-workflow.yml Fixed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 15, 2026

Integration Test Results (K8s v1.29.0)

215 tests   215 ✅  2m 41s ⏱️
  1 suites    0 💤
  1 files      0 ❌

Results for commit ca4b93d.

♻️ This comment has been updated with latest results.

spbsoluble and others added 8 commits April 15, 2026 12:50
Reenrollment is not a supported operation. Remove it from the overview
sentence, fix the store type operations table (K8SJKS and K8SPKCS12 were
incorrectly listed as 'All + Reenrollment'), and remove ReenrollmentBase.cs
from the base class directory listing.
Update the compatibility statement and UO version matrix to explicitly
call out support for Keyfactor Command platform versions 24.x and 25.x,
and add a net10.0 row for Command 25.x and newer.
Add explicit mention of net8.0/net10.0 dual-targeting to the
Compatibility section so users know which build to download without
having to dig into the installation table.
Add missing breaking changes (JobBase dead property removal, KeystoreManager
removal), terraform feature, and richer 1.3.0 bug fixes (create-if-missing,
buddy-secret password, alias routing) and refactor/test chores from the
break/major_refactor branch changelog.
@spbsoluble spbsoluble changed the title feat: v2.0.0 — service layer, handler pattern, per-store-type jobs, X509Certificate2 removal feat: v2.0.0 — major refactor Apr 16, 2026
spbsoluble and others added 4 commits April 16, 2026 09:47
The Serializers/ directory containing JKS and PKCS12 store serializers
was never committed, causing build failures when handler files attempted
to reference the Keyfactor.Extensions.Orchestrator.K8S.Serializers namespace.
- Fix fragile grep/awk token lookup in get_service_account_creds.sh and
  create_service_account.sh — now uses direct jsonpath lookup with a
  clear error message if the token Secret is missing (k8s v1.22+)
- Add generate_client_cert_creds.sh: end-to-end script that applies RBAC,
  generates an RSA key, submits and approves a k8s CSR, and builds a
  client-cert kubeconfig in one step
- Add kubernetes_svc_account_cert_auth.yaml: ClusterRole + ClusterRoleBinding
  for cert-based auth (kind: User subject, no ServiceAccount required)
- Add example_kubeconfig_cert.json showing client-certificate-data layout
- Rewrite scripts/kubernetes/README.md to present both auth options equally
  with comparison table, quickstart, config reference, and manual steps
- Update docsource/content.md Requirements section to document both methods
Plugin changes:
- KubeClient.GetKubeClient(): detect KUBERNETES_SERVICE_HOST and call
  InClusterConfig() when no kubeconfig is provided, using the projected
  service account token mounted by kubelet (auto-rotated every hour)
- JobBase.InitializeProperties(): allow empty KubeSvcCreds when running
  in-cluster instead of throwing ConfigurationException

Scripts/docs:
- Add keyfactor-orchestrator-deployment.yaml: Deployment manifest that
  runs the UO as a pod using the keyfactor-orchestrator-sa ServiceAccount
- Update scripts/kubernetes/README.md: add Option 3 to comparison table
  and full setup section (apply SA YAML, deploy, leave Server Password blank)
- Update docsource/content.md: document all three auth options equally
@spbsoluble spbsoluble changed the title feat: v2.0.0 — major refactor feat: Major refactor for v2.0.0 Apr 21, 2026
spbsoluble and others added 5 commits April 21, 2026 10:56
Compliance remediations (all findings were pre-existing on branch):
- Redact certificate bytes in UpdateOpaqueSecret log traces (CRIT-1)
- Log CSR certificate length only, not content preview (CRIT-2)
- Add structured AUDIT log entries (store_access, secret_read/write/delete)
  to ManagementBase, InventoryBase, DiscoveryBase, SecretOperations (CRIT-3)
- ValidateK8SName throws ArgumentException instead of warning; 5+ segment
  paths return Success=false and fail the job (CRIT-4)
- Zero KubeSvcCreds and ServerPassword after KubeClient construction (HIGH-1)
- RedactKubeconfig validates JSON structure before applying label; non-JSON
  returns POSSIBLY_MALFORMED_CREDENTIAL (HIGH-2)
- Silent catch blocks in JKS/PKCS12 serializers now log exception type (HIGH-3)
- PAM resolution outcome promoted from LogTrace to LogInformation (HIGH-4)
- TLS skip override promoted from LogWarning to LogError with structured
  SECURITY_CONFIG_OVERRIDE field (HIGH-5)
- ReadBuddyPass: make passwordSecretName discard explicit with _ (HIGH-6)
- HandleRemove returns Warning (not Success) when store not found so job
  history distinguishes no-op from actual removal (HIGH-7)
- Remove KubeSvcCreds from storeProperties dict after client construction (MED-1)
- StorePathResolver rejects 5+ segment paths (MED-4)
- Handler NotFound catch blocks use HttpOperationException status code
  comparison instead of ex.Message string matching (MED-5)
- Discovery InitializeStore wrapped in try/catch matching Inventory/Management
  pattern (MED-6)

Bug fix:
- UseSSL value from job config (config.UseSSL) was never forwarded to
  KubeCertificateManagerClient — TLS verification was always defaulting to
  true regardless of the store's Use SSL checkbox. Now captured in each
  InitializeStore overload and passed through InitializeKubeClient.
Removes SHA-256 password correlation ID (MED-2) — low-entropy passwords
are reversible via dictionary attack and RedactPassword is already present
at all call sites. Updates CHANGELOG.md with all v2.0.0 changes from this
session including client cert auth, in-cluster auth, UseSSL fix, audit
logging, and compliance remediations.
Regenerated with fixed doctooldotnet (Keyfactor/doctooldotnet#9).
Named content.md sections were being emitted twice due to title mutation
before the custom-sections filter ran.

NOTE: Actions will revert this until doctooldotnet PR #9 is merged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation needs-review tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants