Skip to content

Conversation

@kaxil
Copy link
Member

@kaxil kaxil commented Jul 3, 2020

We should be able to get the followings config containing passwords and other sensitive data from Secret Backends:

        ('core', 'sql_alchemy_conn'),
        ('core', 'fernet_key'),
        ('celery', 'broker_url'),
        ('celery', 'flower_basic_auth'),
        ('celery', 'result_backend'),
        ('atlas', 'password'),
        ('smtp', 'smtp_password'),
        ('ldap', 'bind_password'),
        ('kubernetes', 'git_password'),

Make sure to mark the boxes below before creating PR: [x]

  • Description above provides context of the change
  • Unit tests coverage for changes (not needed for documentation changes)
  • Target Github ISSUE in description if exists
  • Commits follow "How to write a good git commit message"
  • Relevant documentation is updated including usage instructions.
  • I will engage committers as explained in Contribution Workflow Example.

In case of fundamental code change, Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in UPDATING.md.
Read the Pull Request Guidelines for more information.

@kaxil kaxil requested a review from ashb July 3, 2020 15:41
@boring-cyborg boring-cyborg bot added area:secrets provider:amazon AWS/Amazon - related issues labels Jul 3, 2020
@kaxil kaxil marked this pull request as draft July 3, 2020 15:41
Comment on lines 285 to 302
Copy link
Member

Choose a reason for hiding this comment

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

Hmmmm, not a huge fan of the duplication here and in airflow/secrets/__init__.py.

Since this would only be called after the class is constructed would we instead do

Suggested change
@cached_property
def _secrets_backend_client(self):
if super().has_option('secrets', 'backend') is False:
return None
secrets_backend_cls = super().get('secrets', 'backend')
if not secrets_backend_cls:
return None
print("secrets_backend_cls", secrets_backend_cls)
secrets_backend = import_string(secrets_backend_cls)
if secrets_backend:
try:
alternative_secrets_config_dict = json.loads(
super().get('secrets', 'backend_kwargs', fallback='{}')
)
except json.JSONDecodeError:
alternative_secrets_config_dict = {}
return secrets_backend(**alternative_secrets_config_dict)
@cached_property
def _secrets_backend_client(self):
if super().has_option('secrets', 'backend') is False:
return None
from airflow.secrets import secrets_backend_list
return secrets_backend_list

(give or take).

By delaying the import to inside the function no import loop is created.

This probably also means adding a get_config(section, key) to airflow.secrets, and possibly changing the default implemenation from NotImplementedError to return None.

Note: we should pass they key and section in directly, and let the secret backends convert that to a single parameter if needed (for instance we could have /config/core/sql_alchemy_conn, rather than config/core__sql_alchemy_conn)

Copy link
Member Author

@kaxil kaxil Jul 3, 2020

Choose a reason for hiding this comment

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

The main reason there is some code duplication here is we can't use airflow.secrets as otherwise we would have infinite loop (even when the import is inside the loop) since the DEFAULT_SECRET_BACKEND ( Environment Variable and Connection ) needs sql_achemy_conn value.

I can separate the code to a different file and import that file at both places if the concern is just duplication

Copy link
Member Author

Choose a reason for hiding this comment

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

sql_alchemy_conn_secret = conn/sql_alchemy_conn

should already allow that.

Whatever they pass to sql_alchemy_conn_secret will be directly used to get secret

Copy link
Member Author

@kaxil kaxil Jul 4, 2020

Choose a reason for hiding this comment

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

Updated with TYPE_CHECKING in ed8cc1a

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
And if configurations_prefix is ``airflow/configurations/sql_alchemy_conn``, this would be accessible
And if configurations_prefix is ``airflow/config/core/sql_alchemy_conn``, this would be accessible

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if you provide ``{"configurations_prefix": "airflow/configurations"}`` and request variable
if you provide ``{"configurations_prefix": "airflow/config"}`` and request variable

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
configurations_prefix: str = 'airflow/configuration',
config_prefix: str = 'airflow/config',

Copy link
Member

Choose a reason for hiding this comment

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

etc (haven't made this change everywhere)

Copy link
Member Author

Choose a reason for hiding this comment

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

:D I went back and forth with this

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def get_configuration(self, key: str) -> Optional[str]:
def get_configuration(self, section: str, key: str) -> Optional[str]:

@kaxil kaxil force-pushed the get-secret-config-from-backend branch from ada4ac6 to 3b38109 Compare July 4, 2020 01:39
@kaxil kaxil marked this pull request as ready for review July 4, 2020 01:40
@aneesh-joseph
Copy link
Contributor

thank you for picking this one and sorting it quickly @kaxil - this is super useful, hoping to see this in the next 1.10.* release

Comment on lines 284 to 288
env_var_cmd = env_var + '_SECRET'
if env_var_cmd in os.environ:
# if this is a valid command key...
if (section, key) in self.sensitive_config_values:
return _get_config_value_from_secret_backend(os.environ[env_var_cmd])
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
env_var_cmd = env_var + '_SECRET'
if env_var_cmd in os.environ:
# if this is a valid command key...
if (section, key) in self.sensitive_config_values:
return _get_config_value_from_secret_backend(os.environ[env_var_cmd])
env_var_secret_path = env_var + '_SECRET'
if env_var_secret_path in os.environ:
# if this is a valid secret key...
if (section, key) in self.sensitive_config_values:
return _get_config_value_from_secret_backend(os.environ[env_var_secret_path])

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 032d33f

"""
raise NotImplementedError()

def get_config(self, key: str) -> Optional[str]: # pylint: disable=unused-argument
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be

Suggested change
def get_config(self, key: str) -> Optional[str]: # pylint: disable=unused-argument
def get_config(self, section: str, key: str) -> Optional[str]: # pylint: disable=unused-argument

Copy link
Member

Choose a reason for hiding this comment

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

Oh, except it comes from a single value in the config file. Hmmmm.

Perhaps update the example to show include a / in it?

[core]
sql_alchemy_conn_secret = core/sql_alchemy_conn

Dunno.

Copy link
Member Author

@kaxil kaxil Jul 7, 2020

Choose a reason for hiding this comment

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

added docs in 032d33f

.. code-block:: ini
[core]
sql_alchemy_conn_secret = sql_alchemy_conn
Copy link
Member

Choose a reason for hiding this comment

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

Hmmmmm, I wonder if this will be confusing for people running in Kube, who might expect this to come from a Kube secret.

(I don't have a suggestion on how to deal with this.)

Copy link
Member Author

Choose a reason for hiding this comment

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

for Kubernetes, the section would be kubernetes_secrets:

image

The universal order of precedence for all configuration options is as follows:

#. set as an environment variable
#. set as a command environment variable
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
#. set as a command environment variable
#. set as a command environment variable
#. set as a secret environment variable

Though the wording on this isn't that clear :(

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed in 032d33f

return output


def _get_config_value_from_secret_backend(config_key):
Copy link
Member

Choose a reason for hiding this comment

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

Any reason why this is a function in the module, and not a method on the AirflowConfiguration class?

Copy link
Member Author

Choose a reason for hiding this comment

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

Just to keep it similar to def run_command(command):, no other reason

If variables prefix is ``airflow/variables/hello``, this would be accessible
if you provide ``{"variables_prefix": "airflow/variables"}`` and request variable key ``hello``.
And if configs_prefix is ``airflow/configs/sql_alchemy_conn``, this would be accessible
if you provide ``{"configs_prefix": "airflow/configs"}`` and request variable
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if you provide ``{"configs_prefix": "airflow/configs"}`` and request variable
if you provide ``{"configs_prefix": "airflow/configs"}`` and request config

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated in d8d5b8f

self,
connections_prefix: str = 'airflow/connections',
variables_prefix: str = 'airflow/variables',
configs_prefix: str = 'airflow/configs',
Copy link
Member

Choose a reason for hiding this comment

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

This should probably just be config, not configs -- as config is both singular and plural, at least in British English. (Configurations/configs) sounds odd to my ears.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed in 35d75e5

kaxil added 2 commits July 8, 2020 12:26
@kaxil kaxil merged commit 2f31b30 into apache:master Jul 8, 2020
@kaxil kaxil deleted the get-secret-config-from-backend branch July 8, 2020 12:29
@kaxil kaxil added this to the Airflow 1.10.12 milestone Jul 8, 2020
kaxil added a commit to astronomer/airflow that referenced this pull request Sep 19, 2020
kaxil added a commit to astronomer/airflow that referenced this pull request Sep 19, 2020
Adds support to Google Cloud CloudSecretManagerBackend for feature added in apache#9645
kaxil added a commit that referenced this pull request Sep 19, 2020
cfei18 pushed a commit to cfei18/incubator-airflow that referenced this pull request Mar 5, 2021
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Sep 15, 2021
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Sep 17, 2021
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Sep 23, 2021
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Nov 25, 2021
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Mar 9, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Jun 3, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Jun 7, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Jul 9, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Aug 27, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Oct 4, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
aglipska pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Oct 7, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Dec 7, 2022
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
leahecole pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Jan 27, 2023
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to kosteev/composer-airflow-test-copybara that referenced this pull request Sep 11, 2024
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to kosteev/composer-airflow-test-copybara that referenced this pull request Sep 12, 2024
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Sep 17, 2024
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Nov 7, 2024
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request May 1, 2025
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request May 21, 2025
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Sep 16, 2025
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Oct 15, 2025
…023)

Adds support to AWS SSM for feature added in apache/airflow#9645

GitOrigin-RevId: 2410f592a4ab160b377f1a9e5de3b7262b9851cc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:secrets provider:amazon AWS/Amazon - related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants