s-manzhak opened a new issue, #70192:
URL: https://github.com/apache/airflow/issues/70192
### Under which category would you file this issue?
Airflow Core
### Apache Airflow version
3.2.2
### What happened and how to reproduce it?
**Issue Description**
With `multi_team = True`, connections that have `team_name` set (e.g.
`Portal`) cannot be tested from the UI.
Airflow 3.1.7+ includes a fix for masked passwords (`***`) in
`/connections/test` (#59643): the API tries to load the existing connection via
`Connection.get_connection_from_secrets(conn_id)` and then merges the form body
with `update_orm_from_pydantic`, restoring the real password when the UI sends
`***`.
That lookup does **not** pass `team_name`. For team-scoped connections,
`get_connection_from_secrets` raises `AirflowNotFoundException` even though the
connection exists in the metastore. The API then falls back to constructing a
connection from the request body only, which still contains `password="***"`,
so the test authenticates with the literal masked placeholder and fails.
This happens for both admin and team users. The stored credentials are
correct: the same connection works with `PostgresHook` / DAG runtime when the
team context is available.
**Steps to reproduce:**
1. Enable multi-team mode (`[core] multi_team = True`) with at least one
team (e.g. `Portal`) and a DAG bundle with `team_name="Portal"`.
2. Create a Postgres connection in the UI:
- `conn_id`: `recruitment_crm_db` (any id)
- valid host/login/password
- assign `team_name = Portal`
3. Confirm the row exists in the metadata DB with `team_name='Portal'`.
4. Open the connection in the UI (as admin or as a Portal user) and click
**Test** without re-entering the password (password field shows masked `***`).
5. Observe authentication failure (e.g. `password authentication failed`).
**Repro evidence (same deployment):**
```python
from airflow.models.connection import Connection
from airflow.secrets.metastore import MetastoreBackend
from airflow.providers.postgres.hooks.postgres import PostgresHook
from airflow.settings import Session
c = Session().query(Connection).filter(Connection.conn_id ==
"recruitment_crm_db").one()
# team_name == "Portal", password decrypts correctly
PostgresHook(connection=c).test_connection()
# -> (True, "Connection successfully tested")
MetastoreBackend().get_connection("recruitment_crm_db")
# -> None
MetastoreBackend().get_connection("recruitment_crm_db", team_name="Portal")
# -> Connection(...)
Connection.get_connection_from_secrets("recruitment_crm_db")
# -> AirflowNotFoundException: The conn_id `recruitment_crm_db` isn't defined
### What you think should happen instead?
---
### What you think should happen instead?
```markdown
`/connections/test` should successfully test team-scoped connections when
the caller is allowed to access that team.
Expected behavior:
1. Resolve the existing connection using the correct team context (or
otherwise include team-scoped metastore rows), so `update_orm_from_pydantic`
can restore the real password when the UI sends the masked placeholder `***`.
2. Alternatively, detect `password == "***"` (masked value) and never treat
it as a real credential.
3. UI Test should succeed for a valid team-owned Postgres connection without
requiring the user to re-type the password.
Current behavior is erroneous because:
- the connection exists and credentials are valid;
- DAG/hook usage works;
- only UI Test fails due to secrets lookup without `team_name`, then auth
with literal `***`.
### Operating System
Debian GNU/Linux 12 (bookworm) # inside official apache/airflow container
### Deployment
Docker-Compose
### Apache Airflow Provider(s)
_No response_
### Versions of Apache Airflow Providers
apache-airflow-providers-postgres==6.7.0
apache-airflow-providers-common-sql==2.0.0
apache-airflow-providers-common-compat==1.15.0
apache-airflow-providers-common-io==1.7.2
apache-airflow-providers-common-messaging==2.0.3
### Official Helm Chart version
Not Applicable
### Kubernetes Version
Not Applicable
### Helm Chart configuration
Not Applicable
### Docker Image customizations
Based on official image:
```dockerfile
FROM apache/airflow:3.2.2
USER root
COPY requirements.txt /requirements.txt
RUN chown -R airflow:root /requirements.txt
USER airflow
RUN pip install --no-cache-dir -r /requirements.txt
requirements.txt only adds DAG libs (jira, pymysql, python-gitlab) — not
related to this bug. Relevant config:
[core]
multi_team = True
test_connection = Enabled
DAG bundle example:
[{"name":"company-dags","classpath":"airflow.dag_processing.bundles.local.LocalDagBundle","kwargs":{"path":"/opt/airflow/dags/company"},"team_name":"Company"}]
### Anything else?
### Anything else?
```markdown
Every time for any saved connection with non-null `team_name` when using UI
Test without re-entering the password.
Workarounds:
1. Re-type the real password in the UI form before clicking Test.
2. Temporarily set `team_name = NULL` on the connection (loses team
isolation).
3. Validate with PostgresHook / DAG instead of UI Test.
Related:
- #59298 / #59643 / #61670 — masked password fix (works for non-team
connections)
- This report is specifically about the remaining gap when `multi_team=True`
and connection.team_name is set.
### Are you willing to submit PR?
- [ ] Yes I am willing to submit a PR!
### Code of Conduct
- [x] I agree to follow this project's [Code of
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)
--
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]