Skip to content

Webserver doesn't mask rendered fields for pending tasks #22738

Description

@m1racoli

Apache Airflow version

2.2.5 (latest released)

What happened

When triggering a new dagrun the webserver will not mask secrets in the rendered fields for that dagrun's tasks which didn't start yet.

Tasks which have completed or are in state running are not affected by this.

What you think should happen instead

The webserver should mask all secrets for tasks which have started or not started.

Screenshot 2022-04-04 at 15 36 29

.

How to reproduce

Create a variable my_secret and run this DAG

from datetime import timedelta

from airflow import DAG
from airflow.operators.bash import BashOperator
from airflow.sensors.time_delta import TimeDeltaSensor
from airflow.utils.dates import days_ago

with DAG(
    "secrets",
    start_date=days_ago(1),
    schedule_interval=None,
) as dag:
    wait = TimeDeltaSensor(
        task_id="wait",
        delta=timedelta(minutes=1),
    )

    task = wait >> BashOperator(
        task_id="secret_task",
        bash_command="echo '{{ var.value.my_secret }}'",
    )

While the first task wait is running, displaying rendered fields for the second task secret_task will show the unmasked secret variable.

Screenshot 2022-04-04 at 15 33 43

Operating System

Debian (Astronomer Airflow Docker image)

Versions of Apache Airflow Providers

apache-airflow-providers-amazon==1!3.2.0
apache-airflow-providers-cncf-kubernetes==1!3.0.0
apache-airflow-providers-elasticsearch==1!3.0.2
apache-airflow-providers-ftp==1!2.1.2
apache-airflow-providers-google==1!6.7.0
apache-airflow-providers-http==1!2.1.2
apache-airflow-providers-imap==1!2.2.3
apache-airflow-providers-microsoft-azure==1!3.7.2
apache-airflow-providers-mysql==1!2.2.3
apache-airflow-providers-postgres==1!4.1.0
apache-airflow-providers-redis==1!2.0.4
apache-airflow-providers-slack==1!4.2.3
apache-airflow-providers-sqlite==1!2.1.3
apache-airflow-providers-ssh==1!2.4.3

Deployment

Astronomer

Deployment details

No response

Anything else

We have seen this issue also in Airflow 2.2.3.

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. tirkarthi commented on Apr 5, 2022

    @tirkarthi
    Contributor

    I have created #22754 as a fix. Can you please confirm if MASK_SECRETS_IN_LOGS is enabled in your settings?

  2. m1racoli commented on Apr 5, 2022

    @m1racoli
    ContributorAuthor

    I have created #22754 as a fix. Can you please confirm if MASK_SECRETS_IN_LOGS is enabled in your settings?

    I am not sure that variable is intended to be user configurable. But HIDE_SENSITIVE_VAR_CONN_FIELDS is set to True as per Airflow config reference.

  3. tirkarthi commented on Apr 5, 2022

    @tirkarthi
    Contributor

    Thanks, MASK_SECRETS_IN_LOGS should be set for masking of secret to work. It is set automatically when airflow tasks run is called. The sequential scheduler I use for local testing internally calls the airflow tasks run command to run tasks and thus I was confused over how masking is done when task is executed though the taskinstance.py file had not set the variable. I left a note in the PR over whether we should enable this just during rendering the task template in UI.

    #22754 (comment)

  4. added a commit that references this issue on May 21, 2022
    2dc8063
  5. added a commit that references this issue on May 27, 2022
    09be0c5
  6. added a commit that references this issue on Jun 2, 2022
    b10afd1
  7. hugochinchilla commented on Oct 20, 2022

    @hugochinchilla

    I'm still seing unmasked values for secrets on the rendered section for a pending task, once it runs the values get masked. In my case this is happening in the environment field of a docker operator. I don't know if the problem happens only because it's a different field, maybe the tests for this should be extended.

    I'm using Airflow 2.3.4

  8. hugochinchilla commented on Oct 20, 2022

    @hugochinchilla

    Here is an example on how the issue can still be reproduced:

    from datetime import timedelta
    
    from airflow import DAG
    from airflow.providers.docker.operators.docker import DockerOperator
    from airflow.sensors.time_delta import TimeDeltaSensor
    from airflow.utils.dates import days_ago
    from airflow.utils.log.secrets_masker import mask_secret
    
    secret_value = "you cannot see this"
    
    mask_secret(secret_value)
    
    with DAG(
        "secrets",
        start_date=days_ago(1),
        schedule_interval=None,
    ) as dag:
        wait = TimeDeltaSensor(
            task_id="wait",
            delta=timedelta(seconds=30),
        )
    
        task = wait >>     DockerOperator(
            task_id="docker",
            environment={
                "MY_VARIABLE": secret_value,
            },
            image="hello-world",
        )
  9. m1racoli commented on Oct 21, 2022

    @m1racoli
    ContributorAuthor

    @hugochinchilla I believe you need to store your secret in an Airflow variable or connection and then use jinja to render it in your MY_VARIABLE value in order to take advantage of secrets masking. Not sure this works for hard-coded values.

    Also secrets should not be hard-coded or loaded during DAG parsing (more in Airflow Best Practices).

  10. hugochinchilla commented on Oct 25, 2022

    @hugochinchilla

    Actually this is a simplification, the problem I'm having is actually using data inside a Connection, but that connection is serialized as base64 in a factory that creates the operators, the code calls mask_secret() but the value is exposed until the task actually runs.

    I've mitigated it creating a macro to call mask_secret() and return the value, so I can use something like {{ macros.plugin_name.mask_secret(some_secret) }} and the value is masked even when the task is pending.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions