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.
This commit is contained in:
GraceSolutions
2026-06-06 17:37:56 -04:00
parent 0fdafeca72
commit 318db70480
3 changed files with 44 additions and 3 deletions
@@ -333,7 +333,7 @@ $ConvertToInfisicalSecretDictionaryResult = ConvertTo-InfisicalSecretDictionary
<command:noun>InfisicalSecrets</command:noun>
</command:details>
<maml:description>
<maml:para>Buffers an incoming pipeline of InfisicalSecret objects and writes them to a file in the requested format (DotEnv, Json, Yaml, EnvironmentVariables, etc.) or sets them as environment variables on the chosen scope (Process, User, Machine). -Encoding controls text encoding for file outputs.</maml:para>
<maml:para>Buffers an incoming pipeline of InfisicalSecret objects and writes them to a file in the requested format (DotEnv, Json, Yaml, EnvironmentVariables, etc.) or sets them as environment variables on the chosen scope (Process, User, Machine). -Encoding controls text encoding for file outputs. -Prefix prepends a string to every emitted variable name regardless of format.</maml:para>
</maml:description>
<maml:alertSet>
<maml:title>Notes</maml:title>
@@ -361,6 +361,11 @@ $ExportInfisicalSecretsParameters.Verbose = $True
$ExportInfisicalSecretsResult = Export-InfisicalSecrets @ExportInfisicalSecretsParameters</dev:code>
<dev:remarks><maml:para>Projects the recursive secret result into Process-scope environment variables for the current PowerShell session.</maml:para></dev:remarks>
</command:example>
<command:example>
<maml:title>EXAMPLE 3</maml:title>
<dev:code>Get-InfisicalSecret -ProjectId $ProjectId -Environment 'dev' | Export-InfisicalSecrets -Format EnvironmentVariables -Scope Process -Prefix 'MYAPP_'</dev:code>
<dev:remarks><maml:para>Imports secrets into the process environment with every variable name prefixed by 'MYAPP_' (e.g. API_KEY becomes MYAPP_API_KEY).</maml:para></dev:remarks>
</command:example>
</command:examples>
</command:command>
+2 -1
View File
@@ -1213,7 +1213,8 @@ Export-InfisicalSecrets `
[-Path <FileInfo>] `
[-Scope <Process|User|Machine>] `
[-Force] `
[-Encoding <UTF8|UTF8Bom|Unicode>]
[-Encoding <UTF8|UTF8Bom|Unicode>] `
[-Prefix <string>]
```
## Parameter Rules
@@ -37,6 +37,9 @@ namespace PSInfisicalAPI.Cmdlets
[Parameter]
public InfisicalExportEncoding Encoding { get; set; } = InfisicalExportEncoding.UTF8;
[Parameter]
public string Prefix { get; set; }
private readonly List<InfisicalSecret> _buffer = new List<InfisicalSecret>();
protected override void ProcessRecord()
@@ -68,7 +71,7 @@ namespace PSInfisicalAPI.Cmdlets
InfisicalExportRequest request = new InfisicalExportRequest
{
Secrets = _buffer.ToArray(),
Secrets = ApplyPrefix(_buffer, Prefix),
Format = Format,
Path = Path,
Scope = Scope,
@@ -85,6 +88,38 @@ namespace PSInfisicalAPI.Cmdlets
}
}
private static InfisicalSecret[] ApplyPrefix(List<InfisicalSecret> source, string prefix)
{
if (string.IsNullOrEmpty(prefix)) { return source.ToArray(); }
InfisicalSecret[] result = new InfisicalSecret[source.Count];
for (int i = 0; i < source.Count; i++)
{
InfisicalSecret original = source[i];
result[i] = new InfisicalSecret
{
Id = original.Id,
InternalId = original.InternalId,
Workspace = original.Workspace,
Environment = original.Environment,
Version = original.Version,
Type = original.Type,
SecretName = string.Concat(prefix, original.SecretName),
SecretValue = original.SecretValue,
SecretValueHidden = original.SecretValueHidden,
SecretPath = original.SecretPath,
SecretComment = original.SecretComment,
CreatedAtUtc = original.CreatedAtUtc,
UpdatedAtUtc = original.UpdatedAtUtc,
IsRotatedSecret = original.IsRotatedSecret,
RotationId = original.RotationId,
Tags = original.Tags,
SecretMetadata = original.SecretMetadata
};
}
return result;
}
private static Encoding ResolveEncoding(InfisicalExportEncoding encoding)
{
switch (encoding)