potiuk opened a new pull request, #70869:
URL: https://github.com/apache/airflow/pull/70869
`CloudSecretManagerBackend.get_conn_value` and `get_variable` both accept a
`team_name`, but the helper they delegate to has no such parameter:
```python
def get_conn_value(self, conn_id: str, team_name: str | None = None) -> str
| None:
...
return self._get_secret(self.connections_prefix, conn_id) # team_name
dropped
def _get_secret(self, path_prefix: str, secret_id: str) -> str | None:
```
The argument was discarded at the call boundary, so the backend built the
team
agnostic secret name in every case and a team scoped lookup resolved whatever
that name pointed at. No team scoping was applied at all.
### Approach
The team scope is threaded through and the team scoped name is resolved
first,
using the same `<team><TEAM_SEP><secret id>` convention the other secrets
backends use (`TEAM_SEP = "--"`, matching the Azure Key Vault backend).
1. **team scoped lookup first** — safe by construction, since it can only
ever
build the caller's own namespace;
2. after it misses, an id that already spells out a team scoped name is
**refused**, because the team agnostic name would otherwise land inside
some
team's namespace;
3. otherwise the team agnostic lookup proceeds as before.
**The id is never parsed to work out which team it names**, because it cannot
be: a team name may itself contain the separator, so nothing in the string
distinguishes team `a` with id `b--c` from team `a--b` with id `c`.
Comparing the
id against the prefix the caller's own team builds looks equivalent and is
not —
a caller in team `a` matches `a--b`'s namespace on the prefix and would read
its
secrets. Only the caller's own namespace is ever constructed, never parsed.
`get_config` is unchanged in behaviour for ordinary configuration keys; it
shares
`_get_secret`, so a config id that spells out a team scoped name is now
refused
too, which matches how the Azure backend already behaves.
### Behaviour change
- A team scoped lookup now resolves the team scoped secret name, where
before it
silently resolved the team agnostic one. Deployments that ran multi-team
mode
against this backend and relied on the old behaviour must store secrets
under
the team scoped name.
- An id that spells out a team scoped name is no longer resolvable through
the
team agnostic name from any scope.
- Single-team and non-team deployments are unaffected.
### Test plan
- [x]
`providers/google/tests/unit/google/cloud/secrets/test_secret_manager.py` —
36 pass (30 existing, 6 new)
- [x] New `TestCloudSecretManagerBackendTeamScope`: resolved for its own
team;
not resolved for another team; not resolved without a team scope; team
agnostic secrets still resolve for any scope; Variables scoped
identically
- [x] `test_team_whose_name_extends_the_callers_is_not_readable` — a team
named
`team_a--prod` is not readable by a caller in `team_a`, and still
reaches its
own secret with the bare id
- [x] 5 of the 6 new tests fail against the unmodified backend; the sixth is
a
no-regression guard for team agnostic lookups
- [x] `ruff check` / `ruff format` clean
##### Was generative AI tooling used to co-author this PR?
- [X] Yes — Claude Opus 5 (1M context)
Generated-by: Claude Opus 5 (1M context) following the guidelines at
https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]