diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f1f8a2..5bb41c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loos
- Infisical API error responses are now parsed to surface the server-side `message`, `error`, and `reqId` fields. The 4xx/5xx exception message includes the human-readable explanation (e.g. "The project is of type secret-manager") instead of an opaque `Infisical API returned 400 (Bad Request)`. The `InfisicalApiException` gains `ApiErrorMessage` and `ApiRequestId` properties; `InfisicalErrorDetails` carries the same fields so PowerShell error records and logger output expose them.
- `Get-InfisicalCertificateProfile` added with `List` (default) and `ById` parameter sets. List binds to `GET /api/v1/cert-manager/certificate-profiles` (optional `-Limit`, `-Offset`, `-IncludeConfigs`); ById binds to `GET /api/v1/cert-manager/certificate-profiles/{certificateProfileId}`. New `InfisicalCertificateProfile` model surfaces ca/policy ids, slug, enrollment type, per-profile defaults (ttl, key/extended key usages), and the embedded CA/policy/apiConfig summaries.
- `Get-InfisicalCertificatePolicy` added with `List` (default) and `ById` parameter sets. List binds to `GET /api/v1/cert-manager/certificate-policies` (optional `-Limit`, `-Offset`); ById binds to `GET /api/v1/cert-manager/certificate-policies/{certificatePolicyId}`. New `InfisicalCertificatePolicy` model surfaces subject, SANs, key usages, extended key usages, algorithms, and validity. Polymorphic string-or-array fields (`allowed`, `required`, `keyAlgorithm`) are normalized to arrays; `sans` is normalized whether the API returns an object or an array.
+- `Get-InfisicalCertificateAuthority` gains a `-Kind` parameter on the List parameter set with values `Internal` (default, preserves prior behavior against `/api/v1/cert-manager/ca/internal`), `Any` (binds to the generic `/api/v1/cert-manager/ca` endpoint which returns both internal and ACME CAs), and `Acme` (uses the generic endpoint and client-side filters to ACME issuers only). ById retrieval is unchanged and still resolves against the internal CA endpoint.
## 2026.06.04.1920
diff --git a/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml b/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml
index 0501b7c..82c903b 100644
--- a/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml
+++ b/Module/PSInfisicalAPI/en-US/PSInfisicalAPI.dll-Help.xml
@@ -1006,17 +1006,17 @@ $RemoveInfisicalTagResult = Remove-InfisicalTag @RemoveInfisicalTagParameters
Get-InfisicalCertificateAuthority
- Lists or retrieves Infisical internal Certificate Authorities.
+ Lists or retrieves Infisical Certificate Authorities.
Get
InfisicalCertificateAuthority
- When -CaId is supplied (ById parameter set) returns a single CA. Otherwise (List parameter set) returns every internal CA visible in the project. -ProjectId defaults to the session-pinned project when omitted.
+ When -CaId is supplied (ById parameter set) returns a single internal CA. Otherwise (List parameter set) returns CAs scoped by -Kind: Internal (default, /api/v1/cert-manager/ca/internal), Any (/api/v1/cert-manager/ca returning both internal and ACME), or Acme (filters the generic endpoint to ACME issuers only). -ProjectId defaults to the session-pinned project when omitted.
Notes
- Only internal CAs are surfaced; external/ACME issuers are not enumerated by this cmdlet. CA Ids returned here are the values to pass on -CertificateAuthorityId to Request-InfisicalCertificate.
+ ByID retrieval currently always resolves against the internal CA endpoint. CA Ids returned here are the values to pass on -CertificateAuthorityId to Request-InfisicalCertificate. The Type property distinguishes 'internal' from 'acme' when -Kind Any is used.
@@ -1027,6 +1027,11 @@ $RemoveInfisicalTagResult = Remove-InfisicalTag @RemoveInfisicalTagParameters
EXAMPLE 2
+ Get-InfisicalCertificateAuthority -Kind Any
+ Lists every CA (internal and ACME) visible in the session-pinned project; inspect the Type property to distinguish them.
+
+
+ EXAMPLE 3
$GetInfisicalCertificateAuthorityListResult = Get-InfisicalCertificateAuthority | Where-Object { $_.FriendlyName -eq 'Issuing CA - Platform' }
$GetInfisicalCertificateAuthorityParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary' -ArgumentList ([System.StringComparer]::OrdinalIgnoreCase)
@@ -1035,7 +1040,7 @@ $GetInfisicalCertificateAuthorityParameters.ProjectId = $ConnectInfisicalParamet
$GetInfisicalCertificateAuthorityParameters.Verbose = $True
$GetInfisicalCertificateAuthorityResult = Get-InfisicalCertificateAuthority @GetInfisicalCertificateAuthorityParameters
- Filters the CA list by friendly name and then re-fetches the canonical CA record by id.
+ Filters the CA list by friendly name and then re-fetches the canonical CA record by id using a splatted parameter set.
diff --git a/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateAuthorityCmdlet.cs b/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateAuthorityCmdlet.cs
index bd90777..3857d9a 100644
--- a/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateAuthorityCmdlet.cs
+++ b/src/PSInfisicalAPI/Cmdlets/GetInfisicalCertificateAuthorityCmdlet.cs
@@ -16,6 +16,10 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter] public string ProjectId { get; set; }
+ [Parameter(ParameterSetName = "List")]
+ [ValidateSet("Internal", "Acme", "Any")]
+ public string Kind { get; set; } = "Internal";
+
protected override void ProcessRecord()
{
try
@@ -34,7 +38,20 @@ namespace PSInfisicalAPI.Cmdlets
return;
}
- InfisicalCertificateAuthority[] all = client.ListInternalCertificateAuthorities(connection, ProjectId);
+ InfisicalCertificateAuthority[] all;
+ if (string.Equals(Kind, "Internal", StringComparison.OrdinalIgnoreCase))
+ {
+ all = client.ListInternalCertificateAuthorities(connection, ProjectId);
+ }
+ else
+ {
+ all = client.ListAllCertificateAuthorities(connection, ProjectId);
+ if (string.Equals(Kind, "Acme", StringComparison.OrdinalIgnoreCase))
+ {
+ all = FilterByType(all, "acme");
+ }
+ }
+
foreach (InfisicalCertificateAuthority ca in all)
{
WriteObject(ca);
@@ -45,5 +62,20 @@ namespace PSInfisicalAPI.Cmdlets
ThrowTerminatingForException("GetInfisicalCertificateAuthorityCmdlet", "GetCertificateAuthority", exception);
}
}
+
+ private static InfisicalCertificateAuthority[] FilterByType(InfisicalCertificateAuthority[] source, string type)
+ {
+ if (source == null || source.Length == 0) { return Array.Empty(); }
+ System.Collections.Generic.List kept = new System.Collections.Generic.List();
+ foreach (InfisicalCertificateAuthority ca in source)
+ {
+ if (ca != null && string.Equals(ca.Type, type, StringComparison.OrdinalIgnoreCase))
+ {
+ kept.Add(ca);
+ }
+ }
+
+ return kept.ToArray();
+ }
}
}
diff --git a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs
index 78f934d..7ccdd03 100644
--- a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs
+++ b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointNames.cs
@@ -60,5 +60,7 @@ namespace PSInfisicalAPI.Endpoints
public const string ListCertificatePolicies = "ListCertificatePolicies";
public const string GetCertificatePolicy = "GetCertificatePolicy";
+
+ public const string ListCertificateAuthorities = "ListCertificateAuthorities";
}
}
diff --git a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs
index 985bab4..06abc80 100644
--- a/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs
+++ b/src/PSInfisicalAPI/Endpoints/InfisicalEndpointRegistry.cs
@@ -682,6 +682,16 @@ namespace PSInfisicalAPI.Endpoints
Template = "/api/v1/cert-manager/certificate-policies/{certificatePolicyId}",
RequiresAuthorization = true
});
+
+ Add(map, new InfisicalEndpointDefinition
+ {
+ Name = InfisicalEndpointNames.ListCertificateAuthorities,
+ Resource = "Pki",
+ Version = "v1",
+ Method = "GET",
+ Template = "/api/v1/cert-manager/ca",
+ RequiresAuthorization = true
+ });
}
public static InfisicalEndpointDefinition Get(string name)
diff --git a/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs b/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs
index 50efb1e..65e52b2 100644
--- a/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs
+++ b/src/PSInfisicalAPI/Pki/InfisicalPkiClient.cs
@@ -91,6 +91,36 @@ namespace PSInfisicalAPI.Pki
}
}
+ public InfisicalCertificateAuthority[] ListAllCertificateAuthorities(InfisicalConnection connection, string projectId)
+ {
+ if (connection == null) { throw new ArgumentNullException(nameof(connection)); }
+ string resolvedProjectId = FirstNonEmpty(projectId, connection.ProjectId);
+ if (string.IsNullOrEmpty(resolvedProjectId)) { throw new InfisicalConfigurationException("ProjectId is required."); }
+
+ List> query = new List>
+ {
+ new KeyValuePair("projectId", resolvedProjectId)
+ };
+
+ try
+ {
+ _logger.Information(Component, "Attempting to list Infisical certificate authorities. Please Wait...");
+ InfisicalHttpResponse response = _invoker.InvokeWithCandidateFallback(connection, InfisicalEndpointNames.ListCertificateAuthorities, "ListCertificateAuthorities", null, query, null);
+ string body = response.Body;
+ response.Clear();
+
+ List source = ParseCaListBody(body);
+ InfisicalCertificateAuthority[] mapped = InfisicalCaMapper.MapMany(source, resolvedProjectId);
+ _logger.Information(Component, "Infisical certificate authority list retrieval was successful.");
+ return mapped;
+ }
+ catch (Exception)
+ {
+ _logger.Error(Component, "Infisical certificate authority list retrieval failed.");
+ throw;
+ }
+ }
+
public InfisicalCertificate RetrieveCertificate(InfisicalConnection connection, string identifier)
{
if (connection == null) { throw new ArgumentNullException(nameof(connection)); }