apache / apache/airflow

Support masking secrets in DagRun params

Open
#72,377 7 comments 0 reactions 0 assignees View on GitHub
kind:feature
Dominant language
Python
Stars
46.9k
Forks
17.8k
Avg merge
2d 9h
Merged PRs (30d)
472

Description

### Description

### Description

Currently, `Param` objects in Airflow support basic JSON schema types (string, integer, boolean, etc.). However, when passing sensitive variables at runtime via a DAG run's configuration JSON, any key-value pairs assigned to `params` or `dag_run.conf` are displayed in plaintext under the **DAG Run -> Details -> `conf`** section of the Airflow Webserver UI.

While `SecretsMasker` handles task log masking brilliantly, it does not mask the initial configuration payload stored in the database and surfaced in the UI.

To resolve this, I propose introducing a specialized data type or formatting rule for sensitive parameter inputs—such as a `password` format block or a native `SecretParam` object—that triggers UI redaction.

### Use Case

You have a Dag that needs to be triggered manually, and part of the config that needs to be passed to the Dag might be sensitive, like a token or a password to prove that the user who's triggering the Dag is allowed to, even if triggered via an API proxy. While storing sensitive data usually belongs in variables or connections, there are still many scenarios where ad-hoc execution requires passing sensitive data, which should not be visible in the UI.

Because the `conf` object is fully visible in the UI to users with standard permissions, users are forced to avoid `params` entirely for anything sensitive. Providing a native way to declare a parameter as "sensitive" ensures that Airflow natively redacts the configuration field within the UI metadata tab.

### Proposed Solution

Two potential implementations could resolve this:

1. **Leverage JSON Schema Formats:** Add native support for `"format": "password"` inside a standard Param dictionary.
```python
params={
"api_token": Param(
"default_token",
type="string",
format="password" # The UI rendering should catch this format and replace the value with "***"
)
}
```
2. **Dedicated Parameter Class:** Introduce a `SecretParam` object that extends `Param` and automatically marks the key for backend and UI masking.
```python
from airflow.models.param import SecretParam

params={
"api_token": SecretParam("default_token")
}
```

When either mechanism is parsed, the Airflow Webserver UI should display `***` instead of the raw string in both the "Trigger DAG w/ config" input form and the **DAG Run Details (`conf` tab)** view.

### Use case/motivation

Allow params to be defined as sensitive/ passwords, so that when rendered in the UI, they are masked.

### Related issues

_No response_

### Are you willing to submit a 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)

Contributor guide

Open the contributing guide

Research direction

Start by tracing how Param values and dag_run.conf are handled, then compare that path with SecretsMasker and the Airflow Webserver UI. The issue names the Trigger DAG configuration form and DAG Run Details conf view as the required surfaces; done means sensitive values are redacted in both without exposing the raw configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, frontend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.