Auth manager
Auth manager (인증·인가 관리자)
이 페이지는 Airflow에서 사용자 인증(authentication)과 인가(authorization)를 처리하는 컴포넌트인 Auth manager를 다뤄요. 공통 API를 가지며 "플러그 가능(pluggable)"해서 설치 요구사항에 따라 auth manager를 교체할 수 있어요. 기본 제공 Simple auth manager, 사용 가능한 auth manager 목록, 나만의 auth manager 작성법(BaseAuthManager 인터페이스)을 설명해요.
출처: 문서
본문
Auth(인증·인가) manager는 Airflow에서 사용자 인증과 사용자 인가를 처리하는 컴포넌트예요. 이들은 공통 API를 가지며 "플러그 가능"해서 설치 요구사항에 따라 auth manager를 교체할 수 있어요.

Airflow는 한 번에 하나의 auth manager만 구성할 수 있어요. 이는 설정 파일 [core] 섹션의 auth_manager 옵션으로 설정해요.
Note
Airflow 설정에 대한 자세한 내용은 설정 옵션 설정하기를 참고해요.
현재 어떤 auth manager가 설정되어 있는지 확인하려면 airflow config get-value core auth_manager 명령을 사용할 수 있어요:
$ airflow config get-value core auth_manager
airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager
사용할 수 있는 auth manager
다음은 현재 Airflow 환경에서 사용할 수 있는 auth manager 목록이에요.
Airflow가 제공:
Provider가 제공. 지원되는 auth manager 목록은 Auth managers에 있어요.
왜 플러그 가능한 auth manager인가?
Airflow는 다양한 설정을 가진 아주 다양한 사용자들이 사용해요. 어떤 Airflow 환경은 한 사용자만 사용할 수도 있고, 어떤 것은 수천 명이 사용할 수도 있어요. 한 명(또는 아주 소수)의 사용자만 있는 Airflow 환경은 수천 명이 사용하는 환경과 같은 사용자 관리가 필요하지 않아요.
이것이 전체 사용자 관리(사용자 인증과 사용자 인가)를 auth manager라는 하나의 컴포넌트에 패키징한 이유예요. 그래서 특정 요구사항에 맞는 auth manager를 쉽게 플러그앤플레이할 수 있어요.
기본적으로 Airflow는 Simple auth manager와 함께 제공돼요.
Note
다른 auth manager로 전환하는 것은 무거운 작업이며 그렇게 간주해야 해요. 이는 환경의 사용자에게 영향을 미칠 거예요. 로그인·로그아웃 경험이 매우 달라질 것이며, 미리 조언받지 않으면 사용자를 혼란스럽게 해요. 게다가 현재 모든 사용자와 권한을 이전 auth manager에서 다음으로 복사해야 해요.
나만의 auth manager 작성하기
모든 Airflow auth manager는 공통 인터페이스를 구현해서 플러그 가능하고, 어떤 auth manager든 Airflow 안의 모든 기능과 통합에 접근할 수 있어요. 이 인터페이스는 모든 사용자 인증·인가 관련 작업을 수행하기 위해 Airflow 전반에서 사용돼요.
공개 인터페이스는 BaseAuthManager예요. 가장 상세하고 최신의 인터페이스는 코드에서 볼 수 있지만, 몇 가지 중요한 하이라이트를 아래에 설명해요.
Note
Airflow 공개 인터페이스에 대한 자세한 내용은 Airflow 3.0+ 공개 인터페이스를 참고해요.
커스텀 auth manager를 작성하고 싶은 이유로는 다음이 있어요:
- 특정 사용 사례(특정 도구나 사용자 관리용 서비스 같은)에 맞는 auth manager가 존재하지 않음.
- 선호하는 클라우드 제공자의 identity provider를 활용하는 auth manager를 사용하고 싶음.
- 자신이나 조직에만 제공되는 사설 사용자 관리 도구가 있음.
사용자 표현
BaseAuthManager는 인증된 사용자 타입을 나타내는 사용자 클래스 T로 파라미터화된 인증 관리자를 정의해요. Auth manager 구현(BaseAuthManager의 서브클래스)은 연관된 구체적 사용자 타입을 지정해야 해요. 각 auth manager는 자신의 사용자 타입 정의가 있어요. 구체적 사용자 타입은 BaseUser의 서브클래스여야 해요.
인증 관련 메서드
get_url_login: 사용자가 로그인을 위해 리다이렉트되는 URL을 반환해요.get_url_logout: 로그아웃할 때 사용자가 리다이렉트되는 URL을 반환해요. 이 메서드는 선택적이며, 이 리다이렉션은 보통 로그아웃 시 세션 같은 리소스를 무효화하는 데 필요해요.serialize_user: 사용자 인스턴스를 dict로 직렬화해요. 이 dict는 JWT 토큰의 실제 내용이에요. 사용자를 식별하고 인가 요청을 하는 데 필요한 모든 정보를 포함해야 해요.deserialize_user: dict에서 사용자 인스턴스를 만들어요. 이 dict는 JWT 토큰의 페이로드예요.serialize_user가 반환한 것과 같은 dict예요.
인가 관련 메서드
BaseAuthManager의 대부분 인가 메서드는 비슷해 보여요. 이 메서드들이 사용하는 다양한 파라미터를 살펴볼게요.
method: HTTP 메서드 이름을 사용해 특정 리소스에 수행되는 작업 종류를 결정해요.GET: 사용자가 리소스를 읽을 수 있나요?POST: 사용자가 리소스를 만들 수 있나요?PUT: 사용자가 리소스를 수정할 수 있나요?DELETE: 사용자가 리소스를 삭제할 수 있나요?
details: 접근 중인 리소스에 대한 선택적 세부 정보.user: 리소스에 접근하려는 사용자.
이 인가 메서드들은:
is_authorized_configuration: 사용자가 Airflow 설정에 접근할 권한이 있는지 반환해요. 설정에 대한 일부 세부 정보(예: 설정 섹션)를 제공할 수 있어요.is_authorized_connection: 사용자가 Airflow connections에 접근할 권한이 있는지 반환해요. 연결에 대한 일부 세부 정보(예: connection ID)를 제공할 수 있어요.is_authorized_dag: 사용자가 Dag에 접근할 권한이 있는지 반환해요. Dag에 대한 일부 세부 정보(예: Dag ID)를 제공할 수 있어요. 또한is_authorized_dag는 Dags와 관련된 모든 엔티티(task instances, Dag runs 등)에 대해 호출돼요. 이 정보는access_entity로 전달돼요. 예:auth_manager.is_authorized_dag(method="GET", access_entity=DagAccessEntity.Run, details=DagDetails(id="dag-1"))는 사용자가 Dag "dag-1"의 Dag runs를 읽을 권한이 있는지 묻는 것이에요.is_authorized_asset: 사용자가 Airflow assets에 접근할 권한이 있는지 반환해요. asset에 대한 일부 세부 정보(예: asset ID)를 제공할 수 있어요.is_authorized_asset_alias: 사용자가 Airflow asset aliases에 접근할 권한이 있는지 반환해요. asset alias에 대한 일부 세부 정보(예: asset alias ID)를 제공할 수 있어요.is_authorized_pool: 사용자가 Airflow pools에 접근할 권한이 있는지 반환해요. pool에 대한 일부 세부 정보(예: pool name)를 제공할 수 있어요.is_authorized_variable: 사용자가 Airflow variables에 접근할 권한이 있는지 반환해요. variable에 대한 일부 세부 정보(예: variable key)를 제공할 수 있어요.is_authorized_view: 사용자가 Airflow의 특정 뷰에 접근할 권한이 있는지 반환해요. 뷰는access_view로 지정돼요 (예:AccessView.CLUSTER_ACTIVITY).is_authorized_custom_view: 사용자가 Airflow에 정의되지 않은 특정 뷰에 접근할 권한이 있는지 반환해요. 이 뷰는 auth manager 자체나 사용자가 정의한 플러그인이 제공할 수 있어요.filter_authorized_menu_items: UI의 메뉴 항목 목록이 주어지면, 사용자가 접근할 수 있는 메뉴 항목 목록을 반환해요.is_authorized_hitl_task: 사용자가 Human-in-the-loop(HITL) task를 승인하거나 거부할 권한이 있는지 반환해요. 이는 선택적 메서드로, 기본 구현은 사용자 ID가assigned_users(Task에 할당된 사용자 ID)에 있는지 반환해요. Airflow는 할당된 사용자가 있는 Task에 대해서만 이 메서드를 호출해요. Task에 할당된 사용자가 없으면 Airflow는 이 메서드를 건너뛰고, Task의 HITL 세부 정보를 업데이트할 수 있는 모든 사용자(access_entity=DagAccessEntity.HITL_DETAIL인is_authorized_dag)가 응답할 수 있어요.
위의 method 파라미터는 auth manager의 인가 메서드 중 특정 부분집합에만 관련이 있을 수 있다는 점을 유의하세요. 예를 들어 configuration 리소스는 정의상 읽기 전용이므로, is_authorized_configuration의 맥락에서는 GET 파라미터만 관련이 있어요.
Auth manager의 JWT 토큰 관리
Auth manager는 Airflow 공개 API와 상호작용하는 데 필요한 JWT 토큰을 만드는 책임이 있어요. 이를 위해 auth manager는 반드시 이 JWT 토큰을 만드는 엔드포인트를 제공해야 해요. 이 엔드포인트는 보통 POST /auth/token에 있어요. 정확한 토큰 생성 엔드포인트는 auth manager 문서를 다시 확인해 주세요.
Auth manager는 또한 JWT 토큰을 Airflow UI에 전달할 책임이 있어요. auth manager와 Airflow UI 사이의 JWT 토큰 교환 프로토콜은 쿠키를 사용해요. Auth manager는 Airflow UI로 리다이렉트하기 전에 _token이라는 쿠키에 JWT 토큰을 저장해야 해요. 그러면 Airflow UI가 그 쿠키를 읽고 저장한 뒤 삭제해요.
from airflow.api_fastapi.app import get_cookie_path
from airflow.api_fastapi.auth.managers.base_auth_manager import COOKIE_NAME_JWT_TOKEN
response = RedirectResponse(url="/")
secure = request.base_url.scheme == "https" or bool(conf.get("api", "ssl_cert", fallback=""))
response.set_cookie(COOKIE_NAME_JWT_TOKEN, token, path=get_cookie_path(), secure=secure, httponly=True)
return response
Note
쿠키 파라미터
httponly가True로 설정되었는지 확인해요. UI는 토큰을 관리하지 않아요.
JWT 토큰 새로고침
토큰 새로고침은 선택적 기능이며 그 가용성은 auth manager의 특정 구현에 따라 달라져요. Auth manager는 JWT 토큰이 만료될 때 새로고침할 책임이 있어요. Airflow API는 토큰의 유효성을 확인하는 모든 요청을 가로채는 미들웨어를 사용해요. 보안을 개선하기 위해 토큰 통신은 httponly 쿠키를 통해 처리돼요. 토큰이 만료되면 JWTRefreshMiddleware 미들웨어가 새 토큰을 얻기 위해 auth manager의 refresh_user 메서드를 호출해요.
토큰 새로고침 작업을 지원하려면 auth manager는 refresh_user 메서드를 구현해야 해요. 이 메서드는 만료된 토큰을 받고 새 유효한 토큰을 반환해야 해요. 사용자 정보는 만료된 토큰에서 추출되어 새 토큰을 생성하는 데 사용돼요.
refresh_user 구현 예제는 KeycloakAuthManager::refresh_user일 수 있어요. 사용자 정보는 BaseUser 인스턴스에서 파생돼요. 사용자 객체에 토큰을 새로고침하는 데 필요한 모든 필드가 포함되는 것이 중요해요. 예제 사용자 클래스는 KeycloakAuthManagerUser(BaseUser)일 수 있어요.
최적화를 위해 재정의하길 권장하는 선택적 메서드
다음 메서드는 기능하는 Airflow auth manager를 위해 재정의할 필요는 없어요. 그러나 재정의하면 auth manager를 더 빠르게(그리고 잠재적으로 덜 비싸게) 만들 수 있으므로 권장해요:
batch_is_authorized_connection:is_authorized_connection의 배치 버전. 재정의되지 않으면 항목마다is_authorized_connection을 호출해요.batch_is_authorized_dag:is_authorized_dag의 배치 버전. 재정의되지 않으면 항목마다is_authorized_dag를 호출해요.batch_is_authorized_pool:is_authorized_pool의 배치 버전. 재정의되지 않으면 항목마다is_authorized_pool을 호출해요.batch_is_authorized_variable:is_authorized_variable의 배치 버전. 재정의되지 않으면 항목마다is_authorized_variable을 호출해요.filter_authorized_connections: connection ID 목록(conn_id)이 주어지면, 사용자가 접근할 수 있는 connection ID 목록을 반환해요. 재정의되지 않으면 파라미터로 전달된 모든 connection에 대해is_authorized_connection을 호출해요.filter_authorized_dag_ids: Dag ID 목록이 주어지면, 사용자가 접근할 수 있는 Dag ID 목록을 반환해요. 재정의되지 않으면 파라미터로 전달된 모든 Dag에 대해is_authorized_dag를 호출해요.filter_authorized_pools: pool name 목록이 주어지면, 사용자가 접근할 수 있는 pool name 목록을 반환해요. 재정의되지 않으면 파라미터로 전달된 모든 pool에 대해is_authorized_pool을 호출해요.filter_authorized_variables: variable key 목록이 주어지면, 사용자가 접근할 수 있는 variable key 목록을 반환해요. 재정의되지 않으면 파라미터로 전달된 모든 variable에 대해is_authorized_variable을 호출해요.
CLI
Important
Airflow
3.2.0부터 auth manager와 executor 같은 core 확장을 관리하기 위한 provider 레벨 CLI 명령이 제공돼요. Provider 레벨 CLI 명령을 구현하면 필요하지 않을 때 무거운 import를 피해 CLI 시작 시간을 줄일 수 있어요. 구현 지침은 provider-level CLI를 참고해요.
Auth manager는 get_cli_commands 메서드를 구현해 airflow 명령 줄 도구에 포함될 CLI 명령을 판매(vend)할 수 있어요. 이 명령들은 필요한 리소스를 설정하는 데 사용할 수 있어요. 명령은 현재 구성된 auth manager에 대해서만 판매돼요. auth manager에서 CLI 명령 판매를 구현하는 의사 코드 예제는 아래에서 볼 수 있어요:
@staticmethod
def get_cli_commands() -> list[CLICommand]:
sub_commands = [
ActionCommand(
name="command_name",
help="Description of what this specific command does",
func=lazy_load_command("path.to.python.function.for.command"),
args=(),
),
]
return [
GroupCommand(
name="my_cool_auth_manager",
help="Description of what this group of commands do",
subcommands=sub_commands,
),
]
Note
현재 Airflow 명령 네임스페이스에 대한 엄격한 규칙은 없어요. 개발자가 다른 Airflow 컴포넌트와 충돌하지 않도록 충분히 고유한 이름을 CLI 명령에 사용하는 것은 개발자의 몫이에요.
Note
새 auth manager를 만들거나 기존 auth manager를 업데이트할 때, 모듈 레벨에서 비싼 작업·코드를 import하거나 실행하지 않도록 주의하세요. Auth manager 클래스는 여러 곳에서 import되며, import가 느리면 Airflow 환경의 성능, 특히 CLI 명령에 부정적 영향을 미쳐요.
API 서버 애플리케이션 확장
Auth manager는 Airflow API 서버를 확장하는 옵션을 가져요. 그렇게 하면, 예를 들어 추가 공개 API 엔드포인트를 판매할 수 있어요. API 서버 애플리케이션을 확장하려면 get_fastapi_app 메서드를 구현해야 해요. 이런 추가 엔드포인트는 auth manager가 처리하는 사용자, 그룹, 역할(있는 경우) 같은 리소스를 관리하는 데 사용할 수 있어요. get_fastapi_app이 정의한 엔드포인트는 /auth에 마운트돼요.
기타 선택적 메서드
init: 이 메서드는 Airflow가 초기화될 때 실행돼요. auth manager가 필요로 하는 어떤 작업(예: 리소스 생성, API 호출)을 해야 한다면 이 메서드를 오버라이드해요.get_extra_menu_items: UI의 메뉴에 추가할 추가 링크를 제공해요.get_db_manager: auth manager가 하나 이상의 데이터베이스 관리자(BaseDBManager참고)를 요구한다면, 그들의 클래스 경로를 이 메서드의 일부로 반환해야 해요. 그렇게 하면 config[database] external_db_managers에 자동으로 추가돼요.
추가 주의 사항
- Auth manager는 deprecated 과정에 있는
airflow.security.permissions모듈의 어떤 것도 참조하면 안 돼요. 대신airflow.api_fastapi.auth.managers.models.resource_details의 정의를 사용해야 해요.airflow.security.permissionsdeprecation에 대한 자세한 내용은 airflow.security.permissions의 Deprecation 공지를 참고해요. - Dag 인스턴스의
access_control속성은 FAB auth manager와만 호환돼요. 커스텀 auth manager 구현은 Dag 인스턴스 속성 기반 접근 제어를 더 커스터마이즈 가능한 방식(Dag tags, Dag bundles 등에 기반한 인가 등)으로 하려면get_authorized_dag_ids를 활용해야 해요. - 표준화된 인가 매커니즘 역할을 하는 사설·일반화된
_is_authorized메서드를 정의하고, 각 공개is_authorized_*메서드가 적절한 파라미터로 그 메서드를 호출하는 것이 유용할 수 있어요. 구체적 예제는SimpleAuthManager._is_authorized_method를 참고해요. 또한 사설 메서드 안에서airflow.api_fastapi.auth.managers.base_auth_manager.ExtendedResourceMethod참조를 선택적으로 사용하는 것이 유용할 수 있어요.
Dag와 Dag 하위 컴포넌트 인가
Dag와 그것의 복합 리소스의 계층 구조를 고려할 때, auth manager의 is_authorized_dag 메서드는 Dag runs, tasks, task instances에 대한 인가 로직도 처리해야 해요. is_authorized_dag에 전달되는 access_entity 파라미터는 사용자가 어떤 (있다면) Dag 하위 컴포넌트에 접근하려는지 나타내요. 이는 몇 가지 중요한 점으로 이어져요:
access_entity파라미터가None이면, 사용자는 Dag 자체(그 하위 컴포넌트 중 어느 것도 아님)와 직접 상호작용하려는 것이에요.access_entity파라미터가None이 아니면, 사용자가 Dag의 어떤 하위 컴포넌트에 접근하려는 것이에요. 이는 주목할 만한데, 어떤 경우method파라미터가 Dag의 하위 엔티티에는 유효하지만 Dag 자체에 대한 유효한 동작은 아닐 수 있기 때문이에요. 예를 들어POST메서드는 Dag runs에는 유효하지만, Dags에는 아니에요.- 위에서 언급한 예제 요청(
method가 Dag 하위 컴포넌트에서만 의미를 갖는)을 모델링하는 한 가지 방법은 두 문이 모두 참일 때 사용자를 인가하는 것이에요:- 사용자가 주어진 Dag에 대해
PUT("edit") 권한이 있다. - 사용자가 Dag runs에 대해
POST("create") 권한이 있다.
- 사용자가 주어진 Dag에 대해
다음 단계
BaseAuthManager 인터페이스를 구현하는 새 auth manager 클래스를 만들었다면, core.auth_manager 설정 값을 내 auth manager의 모듈 경로로 설정해 Airflow가 사용하도록 구성할 수 있어요:
[core]
auth_manager = my_company.auth_managers.MyCustomAuthManager
Note
Airflow 설정에 대한 자세한 내용은 설정 옵션 설정하기를 참고하고, Airflow에서 Python 모듈을 관리하는 방법은 Modules Management를 참고해요.