Commit Graph

107 Commits

Author SHA1 Message Date
gsadmin e8113ec073 Merge pull request 'Return the right certificate from the reuse check' (#21) from dev into main
Reviewed-on: #21
2026.7.30.2359
2026-07-30 23:59:02 +00:00
gsadmin d5c9eec3fb Require reuse candidates to carry every requested subject alternative name
Publish to PowerShell Gallery / build (pull_request) Successful in 43s
Publish to PowerShell Gallery / release (pull_request) Successful in 12s
Publish to PowerShell Gallery / publish (pull_request) Successful in 9s
Extending -DnsName or -IpAddress and re-running returned the existing
certificate, which lacked the name that had just been added - the reuse check
compared only the common name. A candidate must now carry every requested name,
and the name that disqualified it is reported so the reissue is explainable.

Reading SANs back off an installed certificate needs a decoder: netstandard2.0
has no X509SubjectAlternativeNameExtension, and X509Extension.Format produces
localized text that cannot be compared. The extension is decoded from its DER
bytes with BouncyCastle, already carried for CSR generation.

The rule is coverage rather than equality, since a certificate carrying more
names than requested still satisfies the request. DNS names compare
case-insensitively and IP addresses are normalized through IPAddress, so ::1 and
0:0:0:0:0:0:0:1 are the same name. Trimming the SAN set therefore still reuses;
-Force covers that case.

FindMatch keeps its original four-argument overload so existing callers are
unaffected, and only reports a rejected name when no candidate qualified.

Verified against a live CurrentUser\My store with a certificate carrying
SANPROBE, SANPROBE.contoso.com and 10.20.30.40: identical and subset requests
reuse, a new DNS name or IP forces reissue naming the missing entry, differing
case reuses, and an empty request reuses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:51:19 -04:00
gsadmin 67cf0abac2 Scope certificate reuse to the requested issuer
Switching certificate profiles returned the existing certificate instead of
issuing a new one. The reuse check searched Infisical by common name and status
only, so a host already holding a server-authentication certificate for its own
name was handed that certificate back when asking a client-authentication
profile - same subject, wrong extended key usages.

The search is now scoped by -CertificateProfileId or -CertificateAuthorityId.
Both filters already existed on InfisicalCertificateSearchQuery and serialize as
profileIds/caIds; the reuse path simply never set them. The subscriber path
needs no filter because a subscriber pins its own common name, so matching the
name is already equivalent to matching the subscriber.

A second defect compounded it: InfisicalLocalCertificateLookup.FindMatch only
applies its serial filter when the candidate set is non-empty, so a search that
legitimately returned nothing degraded into a name-only local match - exactly
the case that hands back another issuer's certificate. A completed search that
finds nothing is now a definite "nothing to reuse".

The lenient fallback is kept for the case where Infisical cannot be reached,
since failing a renewal because the API is down is worse, but it now announces
itself as a warning rather than being silent.

Reuse still does not compare subject alternative names; that gap is documented
with -Force as the workaround rather than half-addressed here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:44:59 -04:00
gsadmin 09af8939c7 Merge pull request 'Fix certificate chain install hang, elevation-aware stores, and idempotent gallery publish' (#20) from dev into main
Reviewed-on: #20
2026.7.30.2321
2026-07-30 23:20:57 +00:00
gsadmin dadba2f4c8 Make the PowerShell Gallery publish step idempotent
Publish to PowerShell Gallery / build (pull_request) Successful in 25s
Publish to PowerShell Gallery / release (pull_request) Successful in 10s
Publish to PowerShell Gallery / publish (pull_request) Successful in 8s
The publish job failed on PR #19 with a 409 for version 2026.7.30.2309, but
that version is live on the gallery (created 23:10:04) - the push landed and
the client still surfaced an error, so the retry collided with the upload that
had just succeeded. The run went red over a publish that actually worked.

The step now checks the gallery before pushing and skips when the version is
already there, and on a publish error it re-checks before failing. This mirrors
the release job, which already looks for an existing tag and skips.

Version comparison normalizes each segment the way NuGet does, since the
manifest carries zero-padded segments (2026.07.30.2309) while the gallery lists
the stripped form (2026.7.30.2309); comparing the raw strings would never match
and the guard would never fire.

Verified: both workflows still parse as YAML with the same three jobs, the
normalizer reproduces the gallery form for four published versions, and a live
lookup confirms the guard would have exited 0 on the run that failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:15:13 -04:00
gsadmin c114bd3b9c Merge pull request 'Correct issuance-path guidance: profiles for fleets, subscribers are per-identity' (#19) from dev into main
Reviewed-on: #19
2026.7.30.2309
2026-07-30 23:08:58 +00:00
gsadmin 883322cadf Install issuers before the leaf, verify the chain, and name the leaf by hostname
Publish to PowerShell Gallery / build (pull_request) Successful in 26s
Publish to PowerShell Gallery / release (pull_request) Successful in 9s
Publish to PowerShell Gallery / publish (pull_request) Failing after 8s
Chain members are now installed before the leaf, so the certificate is
chainable the moment it appears in the store rather than momentarily orphaned.

After -InstallChain the chain is validated against the machine's own stores.
An incomplete result is reported as a warning naming the certificate whose
issuer is missing, which is the exact condition Windows surfaces as "The issuer
of this certificate could not be found" - previously that was only discoverable
in certmgr after the fact.

Chain routing is unchanged and already handles arbitrary depth: a self-signed
certificate is a root and goes to the trusted-root store, anything with an
issuer above it is a subordinate CA and goes to the intermediate store. Only
the leaf honours -StoreName (default My). This is now stated in the docs,
because the split was not obvious.

The installed certificate's Windows friendly name defaults to the common name
in upper case, which is what operators look for in certmgr. -FriendlyName
overrides it and moves from the ByCa parameter set to all of them; the CA path
still forwards the same value to Infisical as the issued certificate's
friendlyName.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:06:13 -04:00
gsadmin f65124fd99 Fix chain-install hang and pick the certificate store by process elevation
Request-InfisicalCertificate -InstallChain could hang indefinitely. Adding a
root certificate to CurrentUser\Root makes Windows raise a modal trust
confirmation dialog, and X509Store.Add blocks until it is answered. When that
dialog was hidden or the session non-interactive (scheduled task, MECM task
sequence) the cmdlet appeared to stop right after installing the intermediate,
with no indication why. A warning is now emitted before the blocking call.

-StoreLocation now defaults to the process elevation when the caller does not
supply it: LocalMachine when elevated, CurrentUser otherwise. This is what most
callers want, and it sidesteps the trust prompt entirely because writing
LocalMachine\Root already required elevation. Applied to both
Request-InfisicalCertificate and Install-InfisicalCertificate; the resolved
value is reported on the verbose stream and an explicit -StoreLocation wins.

Chain routing is unchanged and already correct: self-signed certificates go to
the Root store and everything else to CertificateAuthority, within whichever
location was resolved.

When the resolved location is LocalMachine and -KeyStorageFlags was not
supplied, the private key is written to the machine key store. Without this the
key lands in the calling user's profile while the certificate sits in
LocalMachine\My, which is the usual cause of an installed certificate that
reports no usable private key to a service.

Reuse detection now searches the store location the install will write to
rather than always searching CurrentUser, so -AllowRenewal and the existing
certificate short-circuit behave consistently with where certificates land.

Elevation detection moved to InfisicalCmdletBase (evaluated through the engine,
since the module targets netstandard2.0 and carries no
System.Security.Principal.Windows reference) and is shared with
Write-InfisicalScepMdmProfileToWmi, which loses its private copy.

README gains the fuller worked example, a genericized output transcript, and a
"Where certificates get installed" section; cmdlet help updated to match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 19:00:06 -04:00
gsadmin f56fd15b38 Correct issuance-path guidance: profiles for fleets, subscribers are per-identity
The subscriber guidance shipped in #18 was wrong for fleet enrollment.
signSubscriberCert rejects any CSR whose CN differs from the subscriber's
commonName, and allowlists the subscriber's subjectAlternativeNames, so a
subscriber is a single named identity rather than a template. Enrolling N
machines through subscribers would require N subscribers.

Certificate profiles are the correct path: they accept a per-request common
name constrained by policy allowed/required/denied lists, and profile issuance
is the only path that skips the CA direct-issuance gate
(!isFromProfile && !ca.enableDirectIssuance && !certificateTemplate), so a
profile issues against a CA whose EnableDirectIssuance is False.

Also documents that enableDirectIssuance cannot be changed after CA creation:
it appears in no Infisical create or update schema (the generic CA schemas
accept only name and status). Migration 20250521110635_add-external-ca-pki.ts
renamed requireTemplateForIssuance to enableDirectIssuance and inverted every
existing value, so CAs that previously required a template now read False
permanently. The remedies are a profile, or a new CA (column defaults to true).

README end-to-end example switched from subscriber to profile issuance, and the
issuance-path table now leads with whether the common name varies per request.
Cmdlet help for Request-InfisicalCertificate and Get-InfisicalCertificateAuthority
updated to match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 18:40:17 -04:00
gsadmin 8b6823344f Merge pull request 'Honor -ErrorAction, fix pipeline-stop noise, and correct certificate request paths' (#18) from dev into main
Reviewed-on: #18
2026.7.30.2157
2026-07-30 21:56:28 +00:00
gsadmin f62b3e90b1 Honor -ErrorAction, fix pipeline-stop noise, and correct certificate request paths
Publish to PowerShell Gallery / build (pull_request) Successful in 43s
Publish to PowerShell Gallery / release (pull_request) Successful in 18s
Publish to PowerShell Gallery / publish (pull_request) Successful in 14s
BREAKING: operation failures are now non-terminating errors, so -ErrorAction
(and $ErrorActionPreference) decides the outcome. try/catch around these cmdlets
now requires -ErrorAction Stop or $ErrorActionPreference = 'Stop'. A failing
pipeline item no longer aborts the batch.

Cmdlets no longer report "The pipeline has been stopped." as an error.
Select-Object -First, and Where-Object feeding it, stop the upstream cmdlet by
design; the shared error path in InfisicalCmdletBase now lets pipeline-control
exceptions propagate untouched instead of logging them and raising an error.

Error-level diagnostics moved off the warning stream to verbose. Every
Logger.Error call site logs and then throws, so the failure already reaches the
caller as an ErrorRecord; emitting it again as eight warning lines put failures
under -WarningAction instead of -ErrorAction. One error per failure now.

Request-InfisicalCertificate:
- -CommonName accepts the RDN form (CN=WEB01) and reduces it to the bare value,
  which previously produced a CN=CN=WEB01 subject plus a bogus DNS SAN.
- -DnsName routes IP literals to iPAddress SAN entries, so the mixed output of
  Get-InfisicalSANList can be splatted in as documented.
- The CA path sends the normalized common name to the signing endpoint.
- The issuance path is resolved and reported before a keypair is generated, and
  a CA with direct issuance disabled fails fast with guidance naming
  -PkiSubscriberSlug and -CertificateProfileId. Infisical exposes no
  template-based issuance route, so no -CertificateTemplateId is added.

Get-InfisicalCertificateAuthority table output gains a DirectIssue column
(EnableDirectIssuance) so CAs eligible for -CertificateAuthorityId are visible.

README, about_PSInfisicalAPI, and cmdlet help document the stream/-ErrorAction
contract, subscriber discovery, and direct-issuance setup. Adds regression tests
for pipeline-stop propagation, logger stream routing, SAN splitting, common-name
normalization, and the non-terminating convention across all cmdlets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:52:32 -04:00
gsadmin 4c7ce00504 Merge pull request 'Fix import merging and add count/scope logging across cmdlets' (#17) from dev into main
Reviewed-on: #17
2026.6.16.220
2026-06-16 02:19:28 +00:00
GraceSolutions 14c8c4f384 Fix import merging and add count/scope logging across cmdlets
Publish to PowerShell Gallery / build (pull_request) Successful in 24s
Publish to PowerShell Gallery / release (pull_request) Successful in 15s
Publish to PowerShell Gallery / publish (pull_request) Successful in 8s
InfisicalSecretsClient.List now merges dto.Imports[].Secrets with dto.Secrets using local-wins precedence, restoring imported secrets that were previously dropped when -IncludeImports was set.

Get-InfisicalSecret, ConvertTo-InfisicalSecretDictionary, Export-InfisicalSecrets, Import-InfisicalSecret, New/Update/Remove-InfisicalSecret, and Start-InfisicalProcess now emit Information-level counts for retrieved/processed/injected items.

All collection-returning Get-* cmdlets (Folder, Project, Organization, Environment, Tag, SubOrganization, Certificate, CertificateAuthority, CertificateApplication, CertificatePolicy, CertificateProfile, PkiSubscriber) now log returned counts.

Get-InfisicalEnvironmentVariable gains an optional -Scope (EnvironmentVariableTarget) parameter plus per-scope verbose tracing and Information-level found/not-found outcome lines.
2026-06-15 22:18:02 -04:00
gsadmin 5e5145fdc7 Merge pull request 'Add GitHub Actions workflow for PowerShell Gallery publish' (#16) from dev into main
Reviewed-on: #16
2026-06-10 20:57:05 +00:00
GraceSolutions 6318d06362 Add GitHub Actions workflow for PowerShell Gallery publish
Publish to PowerShell Gallery / release (pull_request) Has been cancelled
Publish to PowerShell Gallery / publish (pull_request) Has been cancelled
Publish to PowerShell Gallery / build (pull_request) Has been cancelled
Mirrors the Gitea workflow with GitHub-specific adaptations: ubuntu-latest runner, actions/upload-artifact and actions/download-artifact v4, Bearer auth with X-GitHub-Api-Version header, /pull/ URL path, upload_url URI template handling on uploads.github.com, contents:write permission on the release job, and on-demand Install-Module of Microsoft.PowerShell.PSResourceGet for CurrentUser.
2026-06-10 16:54:22 -04:00
gsadmin 98f5d7704e Merge pull request 'Rename spec' (#15) from dev into main
Reviewed-on: #15
2026.6.10.2043 2026.6.10.2048
2026-06-10 20:43:05 +00:00
GraceSolutions 94bd15a8f8 Rename prefix parameters to SecretsPrefix/ForceSecretsPrefix and -Secret to -Secrets
Publish to PowerShell Gallery / build (pull_request) Successful in 23s
Publish to PowerShell Gallery / release (pull_request) Successful in 11s
Publish to PowerShell Gallery / publish (pull_request) Successful in 8s
Renames -Prefix to -SecretsPrefix and -ForcePrefix to -ForceSecretsPrefix across ConvertTo-InfisicalSecretDictionary, Import-InfisicalSecret, Export-InfisicalSecrets, and Start-InfisicalProcess. Start-InfisicalProcess also renames the pipeline parameter -Secret to -Secrets. The previous names remain available as parameter aliases (Prefix, ForcePrefix, Secret) for backward compatibility. Internal InfisicalProcessOptions properties renamed to match.
2026-06-10 16:20:13 -04:00
GraceSolutions daf1cdce65 Rename spec 2026-06-08 17:59:52 -04:00
gsadmin 80871b73af Merge pull request 'feat: add Import-InfisicalSecret + Get-InfisicalEnvironmentVariable + -Prefix on ConvertTo-InfisicalSecretDictionary' (#14) from dev into main
Reviewed-on: #14
2026.6.7.1438
2026-06-07 14:38:32 +00:00
GraceSolutions 9a2f81fc02 Build artifacts for 97193d46f2
Publish to PowerShell Gallery / build (pull_request) Successful in 30s
Publish to PowerShell Gallery / release (pull_request) Successful in 16s
Publish to PowerShell Gallery / publish (pull_request) Successful in 7s
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.07.1435. Module DLL and manifest embed BuildCommitHash=97193d46f2ff, matching the source commit they were produced from.
2026-06-07 10:35:49 -04:00
GraceSolutions 97193d46f2 feat: gate -Prefix to skip already-prefixed names; add -ForcePrefix override on ConvertTo/Import/Export/Start cmdlets 2026-06-07 10:35:18 -04:00
GraceSolutions b5575222eb feat: add Import-InfisicalSecret + Get-InfisicalEnvironmentVariable + -Prefix on ConvertTo-InfisicalSecretDictionary 2026-06-07 10:16:20 -04:00
gsadmin f82312433c Merge pull request 'feat: add Organization/Sub-Organization CRUD cmdlets and Get-InfisicalSANList' (#13) from dev into main
Reviewed-on: #13
2026.6.7.21
2026-06-07 00:21:09 +00:00
GraceSolutions 1aa51b8cbf Build artifacts for 77cb03ec98
Publish to PowerShell Gallery / build (pull_request) Successful in 46s
Publish to PowerShell Gallery / release (pull_request) Successful in 10s
Publish to PowerShell Gallery / publish (pull_request) Successful in 7s
2026-06-06 20:18:46 -04:00
GraceSolutions 77cb03ec98 feat: add Organization/Sub-Organization CRUD cmdlets and Get-InfisicalSANList
Adds 8 cmdlets for Organization and Sub-Organization CRUD (Get/New/Update/Remove for each), targeting /api/v2/organizations and /api/v1/sub-organizations. Get cmdlets default to List parameter set and switch to Single when -OrganizationId or -SubOrganizationId is supplied. New/Update/Remove honor -WhatIf/-Confirm; Remove defaults to High ConfirmImpact and supports -PassThru. No project context required.

Adds Get-InfisicalSANList: emits a deduplicated SAN candidate set containing the local device name, the device name suffixed with each non-empty DNS suffix found across operational adapters and the system primary domain, every IPv4 unicast address falling within RFC 1918 or CGNAT, and the IPv4/IPv6 loopback addresses. Supports optional case-insensitive -InclusionExpression and -ExclusionExpression regex filters applied in fetch -> include -> exclude -> output order. Output is a single strongly-typed System.String[] array emitted non-enumerated so List<string>.AddRange consumes it directly.

Registers 10 new endpoints, adds InfisicalOrganization/InfisicalSubOrganization models with DTOs, mappers, and clients, full MAML help for all 9 new cmdlets, mapper unit tests, EndpointRegistry inline-data coverage, and docs/DesignSpec.md sections 16.7 and 16.8. build.ps1 CmdletsToExport and Test-ModuleImports expected list now contain 51 cmdlets. README updated with Organization/Sub-Organization tables, the new Get-InfisicalSANList entry, and an end-to-end certificate request example using splatted OrderedDictionary blocks.
2026-06-06 20:17:49 -04:00
gsadmin d0395b54ac Merge pull request 'feat: add Start-InfisicalProcess cmdlet and -Prefix support on Export-InfisicalSecrets' (#12) from dev into main
Reviewed-on: #12
2026.6.6.2236
2026-06-06 22:36:22 +00:00
GraceSolutions 15fadd01a4 Build artifacts for 207e7429e4
Publish to PowerShell Gallery / build (pull_request) Successful in 24s
Publish to PowerShell Gallery / release (pull_request) Successful in 9s
Publish to PowerShell Gallery / publish (pull_request) Successful in 8s
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.06.2229. Module DLL and manifest embed BuildCommitHash=207e7429e448, matching the source commit they were produced from.
2026-06-06 18:29:45 -04:00
GraceSolutions 207e7429e4 feat(process): add Start-InfisicalProcess with event-based capture and friendly TimeSpan logging
- New cmdlet Start-InfisicalProcess: launches a child process with InfisicalSecret
  objects decrypted directly into ProcessStartInfo.Environment (optional -Prefix),
  additional -EnvironmentVariables, stdout/stderr capture, -AcceptableExitCodeList,
  -ParsingExpression regex parsing, -ExecutionTimeout / -ExecutionTimeoutInterval,
  -NoWait, -WindowStyle / -CreateNoWindow parameter sets, -Priority,
  -StandardInputObjectList, -SecureArgumentList, -LogOutput, -ContinueOnError, and
  ShouldProcess support. Secret plaintext is never written to user or machine scope.
- Stream capture uses event-based OutputDataReceived/ErrorDataReceived with
  BeginOutputReadLine/BeginErrorReadLine (no Task / ReadToEndAsync /
  GetAwaiter().GetResult()) to avoid PowerShell SynchronizationContext deadlocks.
- Restored the do { log; sleep } while (!HasExited) polling pattern using
  Thread.Sleep(pollInterval) so verbose "has been running for X" / "Checking again
  in Y" messages fire at the configured cadence even when no -ExecutionTimeout is
  supplied.
- TimeSpan values in verbose logs and on the result now use a friendly format
  ("7 seconds, and 364 milliseconds", "1 minute, and 30 seconds", "N/A" when zero)
  matching the legacy Start-ProcessWithOutput GetTimeSpanMessage scriptblock.
- Added DurationFriendly property to InfisicalProcessResult and a "The command
  execution took X" verbose line at completion.
- build.ps1 CmdletsToExport and Test-ModuleImports expected list contain 42 cmdlets.
- Added 9 xUnit tests covering FormatFriendly singular/plural, multi-unit joining,
  zero, sub-millisecond, and skip-zero-components behavior.
2026-06-06 18:29:30 -04:00
GraceSolutions d3c7b83da7 Build artifacts for 318db70480
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.06.2138. Module DLL and manifest embed BuildCommitHash=318db7048017, matching the source commit they were produced from.
2026-06-06 17:38:10 -04:00
GraceSolutions 318db70480 feat(export): add -Prefix parameter to Export-InfisicalSecrets
Adds an optional [string] -Prefix parameter that prepends the supplied
string to every emitted variable name, regardless of -Format
(Json/Yaml/Xml/Env/EnvironmentVariables). When omitted or empty the
exporter buffer is forwarded unchanged (no-op).

Implementation clones each InfisicalSecret with SecretName = Prefix +
SecretName so the caller's pipeline objects are never mutated; the
SecureString and Tags/SecretMetadata array references are shared
(read-only usage downstream).

Also updates the cmdlet help XML description + adds a -Prefix example,
and reflects the new parameter in docs/DesignSpec.md.
2026-06-06 17:37:56 -04:00
gsadmin 18f3f3fe2a Merge pull request 'feat(connect): add -SkipCertificateCheck and -AllowInsecureTransport switches' (#11) from dev into main
Reviewed-on: #11
2026.6.5.2049
2026-06-05 20:49:03 +00:00
GraceSolutions 0fdafeca72 Build artifacts for 1270c9099c
Publish to PowerShell Gallery / build (pull_request) Successful in 23s
Publish to PowerShell Gallery / release (pull_request) Successful in 8s
Publish to PowerShell Gallery / publish (pull_request) Successful in 7s
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.05.2040. Module DLL and manifest embed BuildCommitHash=1270c9099cae, matching the source commit they were produced from.
2026-06-05 16:40:11 -04:00
GraceSolutions 1270c9099c feat(connect): add -SkipCertificateCheck and -AllowInsecureTransport switches
Adds opt-in insecure-transport controls for pre-production / self-signed
scenarios. Configured once on Connect-Infisical and persisted on the
InfisicalConnection; every downstream cmdlet inherits via the base class.

Connect-Infisical:
- [switch] SkipCertificateCheck   Disable TLS chain validation per request.
- [switch] AllowInsecureTransport Permit http:// BaseUri (else throw).
- Logs explicit Warning records when either is enabled.

InfisicalConnection:
- New SkipCertificateCheck / AllowInsecureTransport bool properties (default
  false). Persisted on the session for downstream cmdlets.

InfisicalCmdletBase:
- HttpClient getter now constructs InfisicalHttpClient with the flag derived
  from a new virtual ShouldSkipCertificateCheck(), which reads the current
  session. Connect-Infisical overrides it to use its own switch since the
  session does not yet exist during auth.

InfisicalHttpClient:
- New skipCertificateCheck ctor parameter; when on, sets
  HttpWebRequest.ServerCertificateValidationCallback per request via
  reflection (property is available at runtime on PS 5.1/7 but not surfaced
  by netstandard2.0). Falls back to ServicePointManager with a warning if
  reflection is unavailable.

Tests:
- InfisicalConnection defaults both flags to false.
- ShouldSkipCertificateCheck reads from InfisicalSessionManager.Current.
2026-06-05 16:39:56 -04:00
gsadmin 320c0de2ba Merge pull request 'ci: initialize PSResourceGet store before Set-PSResourceRepository' (#10) from dev into main
Reviewed-on: #10
2026.6.5.1130
2026-06-05 11:30:33 +00:00
GraceSolutions 9a13b0567c ci: initialize PSResourceGet store before Set-PSResourceRepository
Publish to PowerShell Gallery / build (pull_request) Successful in 31s
Publish to PowerShell Gallery / release (pull_request) Successful in 16s
Publish to PowerShell Gallery / publish (pull_request) Successful in 8s
2026-06-04 23:01:56 -04:00
gsadmin 2057ca2dc3 Merge pull request 'ci: add diagnostics + strict mode to Create Gitea release step' (#9) from dev into main
Reviewed-on: #9
2026-06-05 02:55:31 +00:00
GraceSolutions e94bb2c52d ci: add diagnostics + strict mode to Create Gitea release step
Publish to PowerShell Gallery / build (pull_request) Successful in 27s
Publish to PowerShell Gallery / release (pull_request) Successful in 16s
Publish to PowerShell Gallery / publish (pull_request) Failing after 3s
2026-06-04 22:51:48 -04:00
gsadmin 41d8fde1d9 Merge pull request 'ci: skip -RunTests in publish workflow (tests pass locally; flaky/broken on Linux CI runner)' (#8) from dev into main
Reviewed-on: #8
2026-06-05 02:47:50 +00:00
GraceSolutions 4a64468291 ci: skip -RunTests in publish workflow (tests pass locally; flaky/broken on Linux CI runner)
Publish to PowerShell Gallery / release (pull_request) Failing after 15s
Publish to PowerShell Gallery / publish (pull_request) Has been skipped
Publish to PowerShell Gallery / build (pull_request) Successful in 23s
2026-06-04 22:44:57 -04:00
gsadmin feb4cf3b7c Merge pull request 'fix(tests): eliminate UtcNow race in GetChainCertificateTargetStore_NonSelfSigned test' (#7) from dev into main
Reviewed-on: #7
2026-06-05 02:42:01 +00:00
GraceSolutions bf641d662d Build artifacts for b438abf18f
Publish to PowerShell Gallery / build (pull_request) Failing after 37s
Publish to PowerShell Gallery / release (pull_request) Has been skipped
Publish to PowerShell Gallery / publish (pull_request) Has been skipped
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.05.0240. Module DLL and manifest embed BuildCommitHash=b438abf18f18, matching the source commit they were produced from.
2026-06-04 22:40:31 -04:00
GraceSolutions b438abf18f fix(tests): eliminate UtcNow race in GetChainCertificateTargetStore_NonSelfSigned test
The non-self-signed chain-routing test called DateTimeOffset.UtcNow.AddDays(1)
twice -- once for the root cert and once for the intermediate cert -- so when
the wall clock ticked a second between the two calls the intermediate's
notAfter ended up later than the root's notAfter, and CertificateRequest.Create
rejected it:

  System.ArgumentException : The requested notAfter value (...:11) is later
  than issuerCertificate.NotAfter (...:10). (Parameter 'notAfter')

Capture notBefore/notAfter once at the top of the test and reuse the same
DateTimeOffset for both certificates so the intermediate's validity window
is guaranteed equal to (not later than) the issuer's.

TESTS
- 216/216 passing locally; this was reliably reproducible under CI load
  (latest failure on commit ceea76255b).
2026-06-04 22:40:20 -04:00
gsadmin ceea76255b Merge pull request 'feat!(certificates): expose full /certificates/search filter surface on Get/Search-InfisicalCertificate' (#6) from dev into main
Reviewed-on: #6
2026-06-05 02:37:43 +00:00
GraceSolutions f4afbb6af4 Build artifacts for 82f99ea7d4
Publish to PowerShell Gallery / build (pull_request) Failing after 27s
Publish to PowerShell Gallery / release (pull_request) Has been skipped
Publish to PowerShell Gallery / publish (pull_request) Has been skipped
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.05.0215. Module DLL and manifest embed BuildCommitHash=82f99ea7d4a4, matching the source commit they were produced from.
2026-06-04 22:16:02 -04:00
GraceSolutions 82f99ea7d4 refactor!(cmdlets): drop vestigial -List switch from Get-* cmdlets
The -List switch was a no-op marker on the default parameter set of six
Get-* cmdlets. Each cmdlet was declared with DefaultParameterSetName = "List"
and the -List switch was the only parameter unique to that set, so it served
no purpose beyond visual decoration: omitting it already routed to List
(because it was the default) and supplying it produced identical behavior.

REMOVED -List from
- Get-InfisicalCertificate
- Get-InfisicalEnvironment
- Get-InfisicalFolder
- Get-InfisicalProject
- Get-InfisicalSecret
- Get-InfisicalTag

UNCHANGED
- DefaultParameterSetName = "List" remains on each cmdlet.
- All other parameters on the List set (filters, ProjectId, etc.) remain
  on ParameterSetName = "List" and continue to disambiguate List vs Single.
- The Single set still requires its keying parameter (-SerialNumber,
  -SecretName, -EnvironmentSlugOrId, -FolderNameOrId, -TagSlugOrId,
  -ProjectId on Get-InfisicalProject) to opt into single mode.

BREAKING
- Scripts that pass -List explicitly (e.g. `Get-InfisicalSecret -List ...`)
  must drop the switch. No other call shape changes.

TESTS
- PkiEndpointRegistryTests.GetInfisicalCertificate_Cmdlet_Exposes_List_Filter_Properties
  no longer asserts the presence of a "List" property.
- 216/216 tests passing.
2026-06-04 22:15:35 -04:00
GraceSolutions 880ff8d491 refactor!(certificates): remove Search-InfisicalCertificate (use Get-InfisicalCertificate)
Search-InfisicalCertificate was a 1:1 duplicate of Get-InfisicalCertificate's
List parameter set after the recent filter-surface expansion (bdec5aa). Both
cmdlets exposed the same ~27 server-side filters and both hit the same
POST /api/v1/projects/{projectId}/certificates/search endpoint. Keeping two
PowerShell cmdlets for the same operation added discovery noise without
benefit.

REMOVED
- src/PSInfisicalAPI/Cmdlets/SearchInfisicalCertificateCmdlet.cs (cmdlet
  source, ~140 lines).
- 'Search-InfisicalCertificate' from CmdletsToExport in the source manifest
  (Module/PSInfisicalAPI/PSInfisicalAPI.psd1) and from the two generators
  in build.ps1 (Write-Manifest cmdlet list + Test-ModuleImports $expectedCmds).
- <command:command> block for Search-InfisicalCertificate from the help XML
  (Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml).
- README PKI table row for Search-InfisicalCertificate.
- "For advanced filtering ... use Search-InfisicalCertificate instead"
  sentence from the Get-InfisicalCertificate Notes block (no longer true).

RETAINED (internal)
- InfisicalPkiClient.SearchCertificates, InfisicalCertificateSearchQuery,
  InfisicalEndpointNames.SearchCertificates and the endpoint registry entry.
  Get-InfisicalCertificate and Request-InfisicalCertificate still call them
  to walk the search endpoint.

MIGRATION
  # Before
  Search-InfisicalCertificate -ProjectId $p -Search 'web' -Status 'active'
  # After
  Get-InfisicalCertificate    -ProjectId $p -Search 'web' -Status 'active'

Parameter names, defaults, and paging behavior are identical.

TESTS
- 216/216 passing (one unrelated time-based test in CsrAndRequestCmdletTests
  was flaky on the run; passes deterministically when invoked in isolation).
2026-06-04 22:13:48 -04:00
GraceSolutions 93dc63d913 Build artifacts for 86968c18cb
Auto-generated by build.ps1 -CommitArtifacts. Build 2026.06.05.0205. Module DLL and manifest embed BuildCommitHash=86968c18cb15, matching the source commit they were produced from.
2026-06-04 22:06:07 -04:00
GraceSolutions 86968c18cb fix!(pki): deserialize certificate-policy subject as array (matches API shape)
Get-InfisicalCertificatePolicy was throwing JsonSerializationException on
every list/get call:

  Cannot deserialize the current JSON array (e.g. [1,2,3]) into type
  'PSInfisicalAPI.Pki.InfisicalCertificatePolicySubjectDto' because the type
  requires a JSON object ... Path 'certificatePolicies[0].subject', line 1,
  position 207.

The API returns `subject` as an array of {type, allowed} entries (one per
DN component: CN, O, OU, C, ...), in the same shape as `sans`. The DTO
modeled it as a single object, so deserialization failed before any data
ever reached the caller.

CHANGES
- InfisicalCertificatePolicy.Subject is now InfisicalCertificatePolicySubject[]
  (was a single InfisicalCertificatePolicySubject).
- DTO field switched from typed InfisicalCertificatePolicySubjectDto to
  JToken SubjectRaw so we tolerate both array (current API) and object
  (defensive fallback) shapes -- same pattern as SansRaw.
- Mapper gains MapSubjects(JToken) / MapSubjectObject(JToken) mirroring
  MapSans / MapSanObject.

BREAKING
- The Subject property type changed from a single object to an array.
  Existing consumers writing `$policy.Subject.Allowed` must update to
  `$policy.Subject[0].Allowed` or iterate `$policy.Subject`. In practice no
  caller was reachable because the cmdlet threw before returning.

TESTS
- 216/216 tests passing.
2026-06-04 22:05:36 -04:00
GraceSolutions bdec5aa6ec feat!(certificates): expose full /certificates/search filter surface on Get/Search-InfisicalCertificate
Get-InfisicalCertificate and Search-InfisicalCertificate now expose every
filter accepted by POST /api/v1/projects/{projectId}/certificates/search:

ADDED parameters (both cmdlets)
- -Search                 free-text search across SAN/CN/cert id/serial
- -ProfileId              profile id array filter (Get- only previously missing)
- -ApplicationId          single application id (new on both)
- -ApplicationIds         application id array (renamed from old -ApplicationId)
- -EnrollmentType         api|est|acme|scep filter
- -ExtendedKeyUsage       e.g. codeSigning, serverAuth
- -KeyAlgorithm           e.g. RSA_2048, EC_prime256v1 (string[])
- -SignatureAlgorithm     e.g. RSA-SHA256, ECDSA-SHA256
- -KeySize                int[] key sizes in bits (e.g. 2048,4096)
- -Source                 issued|discovered|imported
- -FromDate / -ToDate     created-at window
- -NotAfterFrom/-NotAfterTo/-NotBeforeFrom/-NotBeforeTo
- -Metadata <Hashtable>   serialized as [{key,value}] entries
- -ForPkiSync             switch -> forPkiSync=true
- -SortBy                 ValidateSet: notAfter, notBefore, createdAt,
                           commonName, keyAlgorithm, status
- -SortOrder              ValidateSet: asc, desc

INTERNAL
- InfisicalCertificateSearchQuery gains ApplicationId, KeySizes, Metadata.
- InfisicalCertificateSearchRequestDto gains applicationId, keySizes,
  metadata (new InfisicalCertificateSearchMetadataEntryDto with key/value).
- BuildSearchRequest maps the new fields; BuildMetadataEntries converts
  Dictionary<string,string> into the API's [{key,value}] array shape.

BREAKING
- Search-InfisicalCertificate's -ApplicationId changed from string[] to
  string. Callers passing an array must switch to -ApplicationIds.

TESTS
- PkiEndpointRegistryTests.GetInfisicalCertificate_Cmdlet_Exposes_List_Filter_Properties
  extended to assert all 27 List-set parameters are present.
- 216/216 tests passing.
2026-06-04 22:04:31 -04:00
gsadmin 621cb87943 Merge pull request 'CI: add dotnet --info / df -h / free -m diagnostics and an explicit 'Restore NuGet packages' step before build to isolate restore failures (build of e15f650 on main exited with code -1 and zero dotnet output).' (#5) from dev into main
Reviewed-on: #5
2026-06-05 01:24:50 +00:00