민감한 데이터 마스킹

민감한 데이터 마스킹 (Masking sensitive data)

Airflow는 기본적으로 Task 로그, Variables UI, Rendered fields 뷰에서 민감한 값을 자동으로 마스킹해요. 어떤 값이 마스킹되고, 스스로 커스텀 마스크를 추가하는 방법, 그리고 환경 변수로는 마스킹되지 않는 이유를 설명해 드려요.

출처: 문서

본문

Airflow는 기본적으로 Connection의 비밀번호, 민감한 Variables, 그리고 Connection의 extra(JSON) 필드에서 이름에 민감한 키워드가 하나 이상 포함된 키들을 Task 로그, Variables UI, UI의 Rendered fields 뷰에 나타날 때 마스킹해요. extra JSON에서 이런 민감한 키워드를 하나도 포함하지 않는 키는 자동으로 검열되지 않아요.

Airflow는 출력 어디에든 나타나는 특정 을 찾아 이 작업을 수행해요. 즉, 비밀번호가 a인 connection이 있다면, 로그에 나타나는 모든 a 문자가 ***로 바뀐다는 뜻이에요.

마스킹을 비활성화하려면 hide_sensitive_var_conn_fields를 false로 설정하면 돼요.

자동 마스킹은 Connection 또는 Variable 접근으로 트리거돼요. 즉, XCom이나 다른 부수 채널(side-channel)을 통해 민감한 값을 전달하면 다운스트림 Task에서 출력될 때 마스킹되지 않아요.

민감한 필드 이름 (Sensitive field names)

마스킹이 활성화되면, Airflow는 Task가 접근하는 모든 Connection의 password 필드를 항상 마스킹해요.

또한 Variable 이름이나 필드 이름이 알려진 민감 키워드를 포함하면, Airflow Variable의 값, 렌더링된 템플릿 딕셔너리, XCom 딕셔너리, 또는 Connection의 extra JSON blob의 필드를 마스킹해요.

기본 민감 키워드 (Default Sensitive Keywords):

access_token, api_key, apikey, authorization, passphrase, passwd, password, private_key, secret, token, keyfile_dict, service_account.

이 목록은 AIRFLOW__CORE__SENSITIVE_VAR_CONN_NAMES 환경 변수로 확장할 수도 있어요:

[core]
sensitive_var_conn_names = comma,separated,sensitive,names

마스킹 동작 예시 (Examples of Masking Behavior):

Source Key / Variable Name Matching Keyword Masking Scope
Connection Extra google_keyfile_dict keyfile_dict Everywhere (Logs, Rendered Templates, UI)
Connection Extra hello None Not Masked
Variable service_account service_account Everywhere (Logs, Rendered Templates, UI)
Variable test_keyfile_dict keyfile_dict Variables UI Only

나만의 마스크 추가하기 (Adding your own masks)

위 방법 중 하나로 아직 마스킹되지 않은 추가 비밀을 마스킹하고 싶다면, DAG 파일이나 operator의 execute 함수에서 mask_secret 함수를 사용하면 돼요. 예를 들어:

@task
def my_func():
    from airflow.sdk.log import mask_secret

    mask_secret("custom_value")

    ...

또는

class MyOperator(BaseOperator):
    def execute(self, context):
        from airflow.sdk.log import mask_secret

        mask_secret("custom_value")

        ...

마스크는 효과가 있으려면 로그/출력이 생성되기 전에 설정되어야 해요.

환경 변수를 사용할 때는 마스킹되지 않아요

일부 operator — 예를 들어 airflow.providers.cncf.kubernetes.operators.pod.KubernetesPodOperator —를 사용할 때 환경 변수로 비밀을 전달하고 싶은 유혹이 있을 수 있어요. 이것은 매우 나쁜 습관인데, 환경 변수는 프로세스의 환경을 볼 수 있는 접근 권한이 있는 사람이라면 누구나 볼 수 있고, 환경 변수로 전달된 비밀은 Airflow가 마스킹하지 않기 때문이에요.

KubernetesPodOperator에 비밀을 전달해야 한다면, 네이티브 Kubernetes secrets를 사용하거나 Airflow Connection 또는 Variables를 사용해 비밀을 동적으로 가져와야 해요.

더 알아보기 (Learn more)