Skip to content

Commit 368a70c

Browse files
moiseenkovAnton Nitochkin
authored andcommitted
Add config option [secrets]backends_order
1 parent 1e2e9e9 commit 368a70c

File tree

20 files changed

+683
-34
lines changed

20 files changed

+683
-34
lines changed

airflow-core/docs/security/secrets/secrets-backend/index.rst

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ When looking up a connection/variable, by default Airflow will search environmen
3939
database second.
4040

4141
If you enable an alternative secrets backend, it will be searched first, followed by environment variables,
42-
then metastore. This search ordering is not configurable. Though, in some alternative secrets backend you might have
42+
then metastore. Though, in some alternative secrets backend you might have
4343
the option to filter which connection/variable/config is searched in the secret backend. Please look at the
4444
documentation of the secret backend you are using to see if such option is available.
4545

4646
On the other hand, if a workers secrets backend is defined, the order of lookup has higher priority for the workers secrets
4747
backend and then the secrets backend.
4848

49+
The secrets backends search ordering is also configurable via the configuration option ``[secrets]backends_order``.
50+
4951
.. warning::
5052

5153
When using environment variables or an alternative secrets backend to store secrets or variables, it is possible to create key collisions.
@@ -64,12 +66,21 @@ The ``[secrets]`` section has the following options:
6466
[secrets]
6567
backend =
6668
backend_kwargs =
69+
backends_order =
6770
6871
Set ``backend`` to the fully qualified class name of the backend you want to enable.
6972

7073
You can provide ``backend_kwargs`` with json and it will be passed as kwargs to the ``__init__`` method of
7174
your secrets backend.
7275

76+
``backends_order`` comma-separated list of secret backends. These backends will be used in the order they are specified.
77+
Please note that the ``environment_variable`` and ``metastore`` are required values and cannot be removed
78+
from the list. Supported values are:
79+
80+
* ``custom``: Custom secret backend specified in the ``secrets[backend]`` configuration option.
81+
* ``environment_variable``: Standard environment variable backend ``airflow.secrets.environment_variables.EnvironmentVariablesBackend``.
82+
* ``metastore``: Standard metastore backend ``airflow.secrets.metastore.MetastoreBackend``.
83+
7384
If you want to check which secret backend is currently set, you can use ``airflow config get-value secrets backend`` command as in
7485
the example below.
7586

@@ -89,13 +100,22 @@ configure separate secrets backend for workers, you can do that using:
89100
[workers]
90101
secrets_backend =
91102
secrets_backend_kwargs =
103+
backends_order =
92104
93105
94106
Set ``secrets_backend`` to the fully qualified class name of the backend you want to enable.
95107

96108
You can provide ``secrets_backend_kwargs`` with json and it will be passed as kwargs to the ``__init__`` method of
97109
your secrets backend for the workers.
98110

111+
``backends_order`` comma-separated list of secret backends for workers. These backends will be used in the order they are specified.
112+
Please note that the ``environment_variable`` and ``execution_api`` are required values and cannot be removed
113+
from the list. Supported values are:
114+
115+
* ``custom``: Custom secret backend specified in the ``workers[secrets_backend]`` configuration option.
116+
* ``environment_variable``: Standard environment variable backend ``airflow.secrets.environment_variables.EnvironmentVariablesBackend``.
117+
* ``execution_api``: Standard execution_api backend ``airflow.sdk.execution_time.secrets.execution_api.ExecutionAPISecretsBackend``.
118+
99119
If you want to check which secret backend is currently set, you can use ``airflow config get-value workers secrets_backend`` command as in
100120
the example below.
101121

airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,52 @@ paths:
7777
security:
7878
- OAuth2PasswordBearer: []
7979
- HTTPBearer: []
80+
/ui/backends_order:
81+
get:
82+
tags:
83+
- Config
84+
summary: Get Backends Order Value
85+
operationId: get_backends_order_value
86+
security:
87+
- OAuth2PasswordBearer: []
88+
- HTTPBearer: []
89+
parameters:
90+
- name: accept
91+
in: header
92+
required: false
93+
schema:
94+
type: string
95+
enum:
96+
- application/json
97+
- text/plain
98+
- '*/*'
99+
default: '*/*'
100+
title: Accept
101+
responses:
102+
'200':
103+
description: Successful Response
104+
content:
105+
application/json:
106+
schema:
107+
$ref: '#/components/schemas/Config'
108+
'404':
109+
content:
110+
application/json:
111+
schema:
112+
$ref: '#/components/schemas/HTTPExceptionResponse'
113+
description: Not Found
114+
'406':
115+
content:
116+
application/json:
117+
schema:
118+
$ref: '#/components/schemas/HTTPExceptionResponse'
119+
description: Not Acceptable
120+
'422':
121+
description: Validation Error
122+
content:
123+
application/json:
124+
schema:
125+
$ref: '#/components/schemas/HTTPValidationError'
80126
/ui/connections/hook_meta:
81127
get:
82128
tags:
@@ -1259,6 +1305,41 @@ components:
12591305
- count
12601306
title: CalendarTimeRangeResponse
12611307
description: Represents a summary of DAG runs for a specific calendar time range.
1308+
Config:
1309+
properties:
1310+
sections:
1311+
items:
1312+
$ref: '#/components/schemas/ConfigSection'
1313+
type: array
1314+
title: Sections
1315+
additionalProperties: false
1316+
type: object
1317+
required:
1318+
- sections
1319+
title: Config
1320+
description: List of config sections with their options.
1321+
ConfigOption:
1322+
properties:
1323+
key:
1324+
type: string
1325+
title: Key
1326+
value:
1327+
anyOf:
1328+
- type: string
1329+
- prefixItems:
1330+
- type: string
1331+
- type: string
1332+
type: array
1333+
maxItems: 2
1334+
minItems: 2
1335+
title: Value
1336+
additionalProperties: false
1337+
type: object
1338+
required:
1339+
- key
1340+
- value
1341+
title: ConfigOption
1342+
description: Config option.
12621343
ConfigResponse:
12631344
properties:
12641345
page_size:
@@ -1312,6 +1393,23 @@ components:
13121393
- show_external_log_redirect
13131394
title: ConfigResponse
13141395
description: configuration serializer.
1396+
ConfigSection:
1397+
properties:
1398+
name:
1399+
type: string
1400+
title: Name
1401+
options:
1402+
items:
1403+
$ref: '#/components/schemas/ConfigOption'
1404+
type: array
1405+
title: Options
1406+
additionalProperties: false
1407+
type: object
1408+
required:
1409+
- name
1410+
- options
1411+
title: ConfigSection
1412+
description: Config Section Schema.
13151413
ConnectionHookFieldBehavior:
13161414
properties:
13171415
hidden:

airflow-core/src/airflow/api_fastapi/core_api/routes/ui/config.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@
1818

1919
from typing import Any
2020

21-
from fastapi import Depends, status
21+
from fastapi import Depends, HTTPException, status
2222

23+
from airflow.api_fastapi.common.headers import HeaderAcceptJsonOrText
2324
from airflow.api_fastapi.common.router import AirflowRouter
2425
from airflow.api_fastapi.common.types import UIAlert
26+
from airflow.api_fastapi.core_api.datamodels.config import (
27+
Config,
28+
ConfigOption,
29+
ConfigSection,
30+
)
2531
from airflow.api_fastapi.core_api.datamodels.ui.config import ConfigResponse
2632
from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc
2733
from airflow.api_fastapi.core_api.security import requires_authenticated
34+
from airflow.api_fastapi.core_api.services.public.config import _response_based_on_accept
2835
from airflow.configuration import conf
2936
from airflow.settings import DASHBOARD_UIALERTS
3037
from airflow.utils.log.log_reader import TaskLogReader
@@ -64,3 +71,32 @@ def get_configs() -> ConfigResponse:
6471
config.update({key: value for key, value in additional_config.items()})
6572

6673
return ConfigResponse.model_validate(config)
74+
75+
76+
@config_router.get(
77+
"/backends_order",
78+
responses={
79+
**create_openapi_http_exception_doc(
80+
[
81+
status.HTTP_404_NOT_FOUND,
82+
status.HTTP_406_NOT_ACCEPTABLE,
83+
]
84+
),
85+
},
86+
response_model=Config,
87+
dependencies=[Depends(requires_authenticated())],
88+
)
89+
def get_backends_order_value(
90+
accept: HeaderAcceptJsonOrText,
91+
):
92+
section, option = "secrets", "backends_order"
93+
if not conf.has_option(section, option):
94+
raise HTTPException(
95+
status_code=status.HTTP_404_NOT_FOUND,
96+
detail=f"Option [{section}/{option}] not found.",
97+
)
98+
99+
value = conf.get(section, option)
100+
101+
config = Config(sections=[ConfigSection(name=section, options=[ConfigOption(key=option, value=value)])])
102+
return _response_based_on_accept(accept, config)

airflow-core/src/airflow/config_templates/config.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,20 @@ secrets:
13221322
sensitive: true
13231323
example: ~
13241324
default: ""
1325+
backends_order:
1326+
description: |
1327+
Comma-separated list of secret backends. These backends will be used in the order they are specified.
1328+
Please note that the `environment_variable` and `metastore` are required values and cannot be removed
1329+
from the list. Supported values are:
1330+
1331+
* ``custom``: Custom secret backend specified in the ``secrets[backend]`` configuration option.
1332+
* ``environment_variable``: Standard environment variable backend
1333+
``airflow.secrets.environment_variables.EnvironmentVariablesBackend``.
1334+
* ``metastore``: Standard metastore backend ``airflow.secrets.metastore.MetastoreBackend``.
1335+
version_added: 3.2.0
1336+
type: string
1337+
example: ~
1338+
default: "custom,environment_variable,metastore"
13251339
use_cache:
13261340
description: |
13271341
.. note:: |experimental|
@@ -1581,6 +1595,22 @@ workers:
15811595
sensitive: true
15821596
example: ~
15831597
default: ""
1598+
backends_order:
1599+
description: |
1600+
Comma-separated list of secret backends for workers. These backends will be used in the order they are
1601+
specified. Please note that the `environment_variable` and `execution_api` are required values and
1602+
cannot be removed from the list.
1603+
Supported values are:
1604+
* ``custom``: Custom secret backend specified in the ``workers[secrets_backend]`` configuration
1605+
option.
1606+
* ``environment_variable``: Standard environment variable backend
1607+
``airflow.secrets.environment_variables.EnvironmentVariablesBackend``.
1608+
* ``execution_api``: Standard execution_api backend
1609+
``airflow.sdk.execution_time.secrets.execution_api.ExecutionAPISecretsBackend``.
1610+
version_added: 3.2.0
1611+
type: string
1612+
example: ~
1613+
default: "custom,environment_variable,execution_api"
15841614
min_heartbeat_interval:
15851615
description: |
15861616
The minimum interval (in seconds) at which the worker checks the task instance's

0 commit comments

Comments
 (0)