andy

Airflow, Azure and OAuth

NOTE: This is an incomplete article – I will continue to publish more as I can. I have provided the needed code for “webserver_config.py” I have not included information for the “App Registration” in Azure.

This article stems from me not finding enough information, in one place, pertaining to authenticating to Apache Airflow leveraging OAuth and Azure.

I was able to piece what I needed together using documentation from different sources: GitHub, Flask, Apache, etc.

My hope is that this article provide you with the information needed to get authentication functional in your environment.

If you are using the Apache Airflow public helm chart – this is the code that will help get you going. This can be added to your “values.yaml” or “overrides.yaml” file.  If not using a helm chart, then add the python portion – starting with the first “from” to the end of the code block and add it to your “webserver_config.py” file.

webserver:
  service:
    type: NodePort
  webserverConfig: |
    
    from airflow.www.security import AirflowSecurityManager
    import logging
    from typing import Dict, Any, List, Union
    from flask_appbuilder.security.manager import AUTH_OAUTH
    import os

    # basedir = os.path.abspath(os.path.dirname(__file__))

    WTF_CSRF_ENABLED = True
    # SQLALCHEMY_DATABASE_URI = conf.get("core", "SQL_ALCHEMY_CONN")

    AUTH_TYPE = AUTH_OAUTH
    AUTH_ROLES_SYNC_AT_LOGIN = True
    PERMANENT_SESSION_LIFETIME = 1800 # force users to reauth after inactivity period time in seconds
    AUTH_USER_REGISTRATION = True
    AUTH_USER_REGISTRATION_ROLE = "Public"

    class AzureRoleBasedSecurityManager(AirflowSecurityManager):
        def _get_oauth_user_info(self, provider, resp):
            if provider == "azure":
                me = self._azure_jwt_token_parse(resp["id_token"])
                return {
                    "id": me["oid"],
                    "username": me["upn"],
                    "name": me["name"],
                    "email": me["upn"],
                    "first_name": me["given_name"],
                    "last_name": me["family_name"],
                    "role_keys": me["roles"],
                }
            return {}
        oauth_user_info = _get_oauth_user_info

    SECURITY_MANAGER_CLASS = AzureRoleBasedSecurityManager

    # In order of least permissive - default is "Public" - see AUTH_USER_REGISTRATION_ROLE
    AUTH_ROLES_MAPPING = {
      "Public": ["Public"],
      "Viewer": ["Viewer"],
      "User": ["User"],
      "Op": ["Op"],
      "Admin": ["Admin"],
    }

    OAUTH_PROVIDERS = [
      {
        "name": "azure",
        "icon": "fa-windows",
        "token_key": "access_token",
        "remote_app": {
          "client_id": "<from Azure>",
          "client_secret": "<from Azure>",
          "api_base_url": "https://login.microsoftonline.com/<from Azure>/oauth2",
          "client_kwargs": {
            "scope": "User.read name preferred_username email profile upn",
            "resource": "<from Azure>"},
          "access_token_url": "https://login.microsoftonline.com/<from Azure>/oauth2/token",
          "authorize_url": "https://login.microsoftonline.com/<from Azure>/oauth2/authorize",
          "request_token_url": None,
        },
      },
    ]


Security Through Obscurity

Security Through Obscurity?

This my first ever post and I feel it’s a pertinent one to mention.

What is it and why is it bad?
Security through obscurity can be said to be bad because it often implies that the obscurity is being used as the principal means of security. Obscurity is fine until it is discovered, but once someone has worked out your particular obscurity, then your system is vulnerable again. [source: https://en.wikipedia.org/wiki/Security_through_obscurity]

Security is an often overlooked topic in organizations. I’ve heard many different arguments for why things were configured a certain way. Once thing that stands is security through obscurity should never be overlooked. Things are always secure, until they’re not. You should never expose something publicly that is not meant to be exposed publicly.

Continue reading…