Skip to content

Only refuse team scoped like secret ids when multi_team is on - #71078

Merged
vatsrahul1001 merged 1 commit into
apache:mainfrom
astronomer:teams-check
Aug 4, 2026
Merged

Only refuse team scoped like secret ids when multi_team is on#71078
vatsrahul1001 merged 1 commit into
apache:mainfrom
astronomer:teams-check

Conversation

@amoghrajesh

Copy link
Copy Markdown
Contributor

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Related to (#70878), (#70876), (#70899), (#70869), (#70877), (#70736)

Summary

  • Azure Key Vault, AWS Secrets Manager, AWS SSM, GCP Secret Manager, and Yandex Lockbox all refuse to look up any id that contains the team-namespace separator, to avoid ambiguity with a team-scoped secret name.
  • This runs even when multi-team mode is off, which is the default for almost every deployment. Without multi-team mode, no team-scoped secret can exist, so there's no ambiguity to protect against - it just silently breaks ordinary ids
  • On Azure specifically, an id is compared against its underscore-to-dash normalized form, so an ordinary
    connection id containing a double underscore (e.g. aws__prod) was silently refused as if it were a missing secret: https://github.com/apache/airflow/blob/main/providers/microsoft/azure/src/airflow/providers/microsoft/azure/secrets/key_vault.py#L230-L251

Trying to gate this by only run the check when [core] multi_team is enabled, same as Airflow already does at the model layer.


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@amoghrajesh
amoghrajesh requested a review from potiuk August 4, 2026 09:55
@boring-cyborg boring-cyborg Bot added area:providers area:secrets provider:amazon AWS/Amazon - related issues provider:google Google (including GCP) related issues provider:microsoft-azure Azure-related issues provider:yandex labels Aug 4, 2026

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Makes sense !

@potiuk potiuk added this to the Airflow 3.3.1 milestone Aug 4, 2026
@potiuk potiuk added the backport-to-v3-3-test Backport to v3-3-test label Aug 4, 2026
@amoghrajesh

Copy link
Copy Markdown
Contributor Author

@potiuk this touches providers only, so no need to backport.

@amoghrajesh

Copy link
Copy Markdown
Contributor Author

Here's the companion PR for env backend: #71079

@amoghrajesh amoghrajesh self-assigned this Aug 4, 2026
@amoghrajesh amoghrajesh removed the backport-to-v3-3-test Backport to v3-3-test label Aug 4, 2026
@vatsrahul1001
vatsrahul1001 merged commit 2209690 into apache:main Aug 4, 2026
85 of 86 checks passed
@vatsrahul1001
vatsrahul1001 deleted the teams-check branch August 4, 2026 11:57
Only checked in multi-team mode: ``team_name`` is never non-``None`` otherwise, so no
team scoped secret can exist to collide with.
"""
if not conf.getboolean("core", "multi_team", fallback=False):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The Google backend docs still say the opposite. providers/google/docs/secrets-backends/google-cloud-secret-manager-backend.rst:236 warns that the refusal "applies whether or not you use teams" and that an id already containing -- "stops resolving after upgrading and you must rename it". That rename advice is wrong after this change, and the new failure mode (an id with -- resolves fine until someone enables multi_team, then silently stops) isn't documented anywhere. Can this PR update that section?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, here you go: #71106

Only checked in multi-team mode: ``team_name`` is never non-``None`` otherwise, so no
team scoped secret can exist to collide with.
"""
if not conf.getboolean("core", "multi_team", fallback=False):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

get_config runs through this guard too (line 193), but config lookups are never team-scoped: _get_secret(self.config_prefix, key) passes no team_name, so a config key has no team-scoped name to collide with in either mode. The key here is the operator-chosen path from <option>_secret, and this backend maps _ onto the separator, so a path named after the env var (airflow__database__sql_alchemy_conn becomes airflow--database--sql-alchemy-conn) is still refused whenever multi_team is on. Google and Yandex never guarded get_config, and the Google docs state config lookups are unaffected, so dropping it from get_config here and in the two AWS backends would make all five agree. Happy for that to be a follow-up if you want to keep this PR narrow.

mock_client.get_secret.return_value = mock.Mock(value="world")
backend = AzureKeyVaultBackend()

assert backend.get_conn_value("prod--my_db") == "world"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

get_secret returns world for any name here, so these pass regardless of the name the backend computes, which is the part the prod__hello case in the description turns on. The tests above assert the resolved name (lines 45, 88, 111). Worth at least mock_client.get_secret.assert_any_call(name="airflow-variables-prod--hello") for the prod__hello lookup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Handled in #71106

returned_uri = ssm_backend.get_conn_value(conn_id="test_postgres", team_name="my_team")
assert returned_uri == "postgresql://airflow:airflow@host:5432/airflow"

@conf_vars({("core", "multi_team"): "True"})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The other four test files in this PR define multi_team_enabled = conf_vars({("core", "multi_team"): "True"}) at module level. Worth doing the same here rather than repeating the literal on six tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Handled in #71106

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

Labels

area:providers area:secrets provider:amazon AWS/Amazon - related issues provider:google Google (including GCP) related issues provider:microsoft-azure Azure-related issues provider:yandex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants