From 19fbcd1d237c6f4d39c099e3d91caa3d1528ddce Mon Sep 17 00:00:00 2001 From: SUPRATIM SARKAR <46316649+codewithsupra@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:41:08 +0530 Subject: [PATCH] feat(export): support multiple --path flags for merging secrets Adds support for specifying `--path` multiple times in `infisical export`, mirroring the behaviour already present in `infisical run`: infisical export --path /global --path /app-a --env prod > .env Secrets from each path are fetched and merged; later paths win on duplicate keys (same personal/shared override logic used by `run`). Implementation reuses `fetchSecrets()` defined in run.go (same `cmd` package) and switches the export flag from `String("/")` to `StringArray(["/"])`, keeping the single-path default unchanged. Closes #900 (export command) --- packages/cmd/export.go | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/packages/cmd/export.go b/packages/cmd/export.go index a27c5a0c..bfef4578 100644 --- a/packages/cmd/export.go +++ b/packages/cmd/export.go @@ -82,7 +82,7 @@ var exportCmd = &cobra.Command{ util.HandleError(err, "Unable to parse flag") } - secretsPath, err := cmd.Flags().GetString("path") + secretsPaths, err := cmd.Flags().GetStringArray("path") if err != nil { util.HandleError(err, "Unable to parse flag") } @@ -92,21 +92,15 @@ var exportCmd = &cobra.Command{ util.HandleError(err, "Unable to parse flag") } - request := models.GetAllSecretsParameters{ + multiPathRequest := models.GetMultiPathSecretsParameters{ Environment: environmentName, - TagSlugs: tagSlugs, WorkspaceId: projectId, - SecretsPath: secretsPath, + TagSlugs: tagSlugs, + SecretsPaths: secretsPaths, IncludeImport: includeImports, ExpandSecretReferences: shouldExpandSecrets, } - if token != nil && token.Type == util.SERVICE_TOKEN_IDENTIFIER { - request.InfisicalToken = token.Token - } else if token != nil && token.Type == util.UNIVERSAL_AUTH_TOKEN_IDENTIFIER { - request.UniversalAuthAccessToken = token.Token - } - if templatePath != "" { dynamicSecretLeases := NewDynamicSecretLeaseManager(nil, nil) @@ -131,17 +125,11 @@ var exportCmd = &cobra.Command{ return } - secrets, err := util.GetAllEnvironmentVariables(request, "") + secrets, err := fetchSecrets(multiPathRequest, "", secretOverriding, token) if err != nil { util.HandleError(err, "Unable to fetch secrets") } - if secretOverriding { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_PERSONAL) - } else { - secrets = util.OverrideSecrets(secrets, util.SECRET_TYPE_SHARED) - } - var output string secrets = util.FilterSecretsByTag(secrets, tagSlugs) secrets = util.SortSecretsByKeys(secrets) @@ -272,7 +260,7 @@ func init() { exportCmd.Flags().String("token", "", "Fetch secrets using service token or machine identity access token") exportCmd.Flags().StringP("tags", "t", "", "filter secrets by tag slugs") exportCmd.Flags().String("projectId", "", "manually set the projectId to export secrets from") - exportCmd.Flags().String("path", "/", "get secrets within a folder path") + exportCmd.Flags().StringArray("path", []string{"/"}, "get secrets within a folder path (can be specified multiple times to merge secrets from multiple paths)") exportCmd.Flags().String("template", "", "The path to the template file used to render secrets") exportCmd.Flags().StringP("output-file", "o", "", "The path to write the output file to. Can be a full file path, directory, or filename. If not specified, output will be printed to stdout") }