Skip to content

Fix environment variable leak and flag propagation for extensions#7314

Open
jongio wants to merge 4 commits intomainfrom
fix/env-leak-extensions
Open

Fix environment variable leak and flag propagation for extensions#7314
jongio wants to merge 4 commits intomainfrom
fix/env-leak-extensions

Conversation

@jongio
Copy link
Member

@jongio jongio commented Mar 25, 2026

Summary

This is a redo of #7035 (which was reverted by #7274) with the prerequisite work done first. It fixes two problems:

  1. Environment variable leak (azd <extension> -e <env> leaks default environment variables into extension process #7034): Extensions never received the correct -e/--environment value because extension commands use DisableFlagParsing: true, so cobra never parsed the flag. The DI resolver always fell back to the default environment.

  2. Flag propagation broken by revert (Revert: Fix env var leak when running extension commands with -e flag (#7035) #7274): The revert also broke --debug and --cwd propagation to extensions, since it changed extensions.go back to using cmd.Flags() which returns defaults for extension commands.

What changed

  • global_command_options.go: Added EnvironmentName field
  • auto_install.go: Added -e/--environment to CreateGlobalFlagSet() with strict validation in ParseGlobalFlags() (rejects invalid env names with clear error)
  • container.go: Updated EnvFlag DI resolver to fall back to globalOptions.EnvironmentName
  • extensions.go: Uses globalOptions (populated before cobra) for ALL InvokeOptions fields (debug, cwd, environment, no-prompt)
  • environment.go: Added exported InvalidEnvironmentNameError() for shared validation across all call sites
  • manager.go: Replaced 3 inconsistent error message formats with the shared InvalidEnvironmentNameError()
  • 64 snapshot files: Updated to reflect the new -e, --environment flag in help text
  • auto_install_test.go: 11 new subtests (6 valid env name + 5 invalid env name)

Key difference from #7035

PR #7035 added strict -e validation which broke extensions that reused -e for URLs. This PR is safe because PR #7313 migrates extensions off -e first.

How globalOptions solves it

ParseGlobalFlags() runs before cobra, manually parsing the raw os.Args. For extension commands (DisableFlagParsing: true), cobra skips all flag parsing, but globalOptions already has the correct values. Both the DI resolver and extension invocation now read from globalOptions instead of cmd.Flags().

Closes #7034
Closes #7271

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Extension commands use DisableFlagParsing, so cobra never parses global
flags like -e/--environment, --debug, or --cwd. This caused two problems:

1. The DI-resolved environment always loaded the default instead of the
   one specified with -e, leaking wrong env vars into extension processes
   and never setting AZD_ENVIRONMENT (#7034).

2. --debug and --cwd were also not propagated to extensions because
   extensions.go read them from cmd.Flags() which returns defaults.

Fix by:
- Adding -e/--environment to ParseGlobalFlags() with lenient validation:
  valid env names are accepted, non-env values (like URLs that extensions
  pass via -e) are silently skipped so extensions still work.
- Adding EnvironmentName to GlobalCommandOptions so the pre-parsed value
  is available to the DI container and extension runner.
- Updating container.go EnvFlag resolver to fall back to globalOptions
  when cmd.Flags() returns empty (extension commands).
- Updating extensions.go to use globalOptions for all InvokeOptions
  fields (debug, cwd, environment, no-prompt) instead of cmd.Flags().

Closes #7034

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes global flag propagation (notably -e/--environment, --debug, --cwd) to extension commands that run with DisableFlagParsing: true, and standardizes invalid environment-name errors.

Changes:

  • Introduces GlobalCommandOptions.EnvironmentName and parses -e/--environment early via ParseGlobalFlags().
  • Updates extension invocation and DI env resolver to read from pre-parsed globalOptions rather than cmd.Flags().
  • Centralizes invalid environment-name error formatting and updates help/usage snapshots to include the new global flag.

Reviewed changes

Copilot reviewed 71 out of 71 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cli/azd/pkg/environment/manager.go Replaces ad-hoc invalid env name messaging with shared InvalidEnvironmentNameError()
cli/azd/pkg/environment/environment.go Adds shared exported invalid env name error helper
cli/azd/internal/global_command_options.go Adds EnvironmentName to carry pre-parsed -e/--environment value
cli/azd/cmd/extensions.go Propagates debug/cwd/env/no-prompt to extensions via globalOptions
cli/azd/cmd/container.go DI resolver for EnvFlag falls back to globalOptions.EnvironmentName
cli/azd/cmd/auto_install.go Adds global -e/--environment and validates it in ParseGlobalFlags()
cli/azd/cmd/auto_install_test.go Adds tests for parsing/validating -e/--environment
cli/azd/cmd/testdata/TestFigSpec.ts Moves --environment/-e to persistent options; removes per-command env options in a few places
cli/azd/cmd/testdata/TestUsage-azd.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-x.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-version.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template-source.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template-source-remove.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template-source-list.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template-source-add.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template-show.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-template-list.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-pipeline.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-mcp.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-mcp-start.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-infra.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-hooks.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-upgrade.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-uninstall.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-source.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-source-validate.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-source-remove.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-source-list.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-source-add.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-show.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-list.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-extension-install.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-env.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-env-select.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-env-new.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-env-list.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-env-config.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-demo.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-copilot.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-copilot-consent.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-copilot-consent-revoke.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-copilot-consent-list.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-copilot-consent-grant.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-unset.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-show.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-set.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-reset.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-options.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-list-alpha.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-config-get.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-concurx.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-completion.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-completion-zsh.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-completion-powershell.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-completion-fish.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-completion-fig.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-completion-bash.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-coding-agent.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-auth.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-auth-status.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-auth-logout.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-auth-login.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-appservice.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-ai.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-ai-models.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-ai-finetuning.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-ai-agent.snap Updates help snapshot to include -e, --environment
cli/azd/cmd/testdata/TestUsage-azd-add.snap Updates help snapshot to include -e, --environment
Comments suppressed due to low confidence (2)

cli/azd/internal/global_command_options.go:1

  • This comment says EnvironmentName is empty when the passed -e value is not a valid environment name (e.g., extensions reuse -e for URLs), but ParseGlobalFlags() now returns an error for invalid values. Update the comment to match the new strict-validation behavior (or relax validation if the intent is still to allow extensions to reuse -e).
    cli/azd/pkg/environment/environment.go:1
  • The standardized error message hard-codes the allowed character set as 'only alphanumeric characters and hyphens'. In this PR, TestParseGlobalFlags_EnvironmentName treats a name containing a dot (my-env.v2) as valid. Either adjust the test expectations/validation to disallow dots, or update the error message to accurately describe what IsValidEnvironmentName permits so users get correct guidance.

jongio and others added 3 commits March 25, 2026 14:24
Agent detection (agentdetect package) walks the parent process tree and
auto-enables --no-prompt when it finds an AI coding agent. In CI and
local dev under Copilot CLI, this causes functional tests to fail
because piped stdin is ignored when no-prompt is active.

Changes:
- detect.go: Early return from detectAgent() when AZD_DISABLE_AGENT_DETECT
  is set, suppressing both env var and parent process detection
- cli.go: Set AZD_DISABLE_AGENT_DETECT=1 on all child azd processes in
  RunCommandWithStdIn(), with nil-Env safety (nil means inherit-all in Go)
- detect_test.go: Test that AZD_DISABLE_AGENT_DETECT suppresses detection
- env_test.go: Fix require.Fail -> require.Failf format string bug

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The gosec linter flags os.LookupEnv values as tainted input for log
injection (G706). Remove the env var value from the log message since
only the presence of the env var matters, not its value.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Member

@spboyer spboyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the core fix (switching extensionAction from cmd.Flags() to globalOptions for DisableFlagParsing extensions), IoC plumbing, AZD_DISABLE_AGENT_DETECT kill switch, InvalidEnvironmentNameError refactor, and require.Fail -> require.Failf fix. No issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

azd model custom create failing with latest Azd Version azd <extension> -e <env> leaks default environment variables into extension process

3 participants