blob: c7a25b21d18abfa224698d4229a594a0287117b6 [file] [log] [blame]
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Security &mdash; Airflow Documentation</title>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Time zones" href="timezone.html" />
<link rel="prev" title="Plugins" href="plugins.html" />
<script src="_static/js/modernizr.min.js"></script>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
_paq.push(['disableCookies']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '13']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo -->
<link rel="canonical" href="https://airflow.apache.org/docs/apache-airflow/stable/security.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="index.html" class="icon icon-home"> Airflow
</a>
<div class="version">
1.10.2
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="project.html">Project</a></li>
<li class="toctree-l1"><a class="reference internal" href="license.html">License</a></li>
<li class="toctree-l1"><a class="reference internal" href="start.html">Quick Start</a></li>
<li class="toctree-l1"><a class="reference internal" href="installation.html">Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="howto/index.html">How-to Guides</a></li>
<li class="toctree-l1"><a class="reference internal" href="ui.html">UI / Screenshots</a></li>
<li class="toctree-l1"><a class="reference internal" href="concepts.html">Concepts</a></li>
<li class="toctree-l1"><a class="reference internal" href="profiling.html">Data Profiling</a></li>
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command Line Interface</a></li>
<li class="toctree-l1"><a class="reference internal" href="scheduler.html">Scheduling &amp; Triggers</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugins.html">Plugins</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Security</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#web-authentication">Web Authentication</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#password">Password</a></li>
<li class="toctree-l3"><a class="reference internal" href="#ldap">LDAP</a></li>
<li class="toctree-l3"><a class="reference internal" href="#roll-your-own">Roll your own</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#multi-tenancy">Multi-tenancy</a></li>
<li class="toctree-l2"><a class="reference internal" href="#kerberos">Kerberos</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#limitations">Limitations</a></li>
<li class="toctree-l3"><a class="reference internal" href="#enabling-kerberos">Enabling kerberos</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#airflow">Airflow</a></li>
<li class="toctree-l4"><a class="reference internal" href="#hadoop">Hadoop</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#using-kerberos-authentication">Using kerberos authentication</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#oauth-authentication">OAuth Authentication</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#github-enterprise-ghe-authentication">GitHub Enterprise (GHE) Authentication</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#setting-up-ghe-authentication">Setting up GHE Authentication</a></li>
<li class="toctree-l4"><a class="reference internal" href="#using-ghe-authentication-with-github-com">Using GHE Authentication with github.com</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#google-authentication">Google Authentication</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#setting-up-google-authentication">Setting up Google Authentication</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#ssl">SSL</a></li>
<li class="toctree-l2"><a class="reference internal" href="#impersonation">Impersonation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#default-impersonation">Default Impersonation</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#flower-authentication">Flower Authentication</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="timezone.html">Time zones</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">Experimental Rest API</a></li>
<li class="toctree-l1"><a class="reference internal" href="integration.html">Integration</a></li>
<li class="toctree-l1"><a class="reference internal" href="metrics.html">Metrics</a></li>
<li class="toctree-l1"><a class="reference internal" href="kubernetes.html">Kubernetes</a></li>
<li class="toctree-l1"><a class="reference internal" href="lineage.html">Lineage</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog</a></li>
<li class="toctree-l1"><a class="reference internal" href="faq.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="code.html">API Reference</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Airflow</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> &raquo;</li>
<li>Security</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/security.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="security">
<h1>Security<a class="headerlink" href="#security" title="Permalink to this headline"></a></h1>
<p>By default, all gates are opened. An easy way to restrict access
to the web application is to do it at the network level, or by using
SSH tunnels.</p>
<p>It is however possible to switch on authentication by either using one of the supplied
backends or creating your own.</p>
<p>Be sure to checkout <a class="reference internal" href="api.html"><span class="doc">Experimental Rest API</span></a> for securing the API.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Airflow uses the config parser of Python. This config parser interpolates
‘%’-signs. Make sure escape any <code class="docutils literal notranslate"><span class="pre">%</span></code> signs in your config file (but not
environment variables) as <code class="docutils literal notranslate"><span class="pre">%%</span></code>, otherwise Airflow might leak these
passwords on a config parser exception to a log.</p>
</div>
<div class="section" id="web-authentication">
<h2>Web Authentication<a class="headerlink" href="#web-authentication" title="Permalink to this headline"></a></h2>
<div class="section" id="password">
<h3>Password<a class="headerlink" href="#password" title="Permalink to this headline"></a></h3>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This is for flask-admin based web UI only. If you are using FAB-based web UI with RBAC feature,
please use command line interface <code class="docutils literal notranslate"><span class="pre">create_user</span></code> to create accounts, or do that in the FAB-based UI itself.</p>
</div>
<p>One of the simplest mechanisms for authentication is requiring users to specify a password before logging in.
Password authentication requires the used of the <code class="docutils literal notranslate"><span class="pre">password</span></code> subpackage in your requirements file. Password hashing
uses <code class="docutils literal notranslate"><span class="pre">bcrypt</span></code> before storing passwords.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">authenticate</span> <span class="o">=</span> True
<span class="nv">auth_backend</span> <span class="o">=</span> airflow.contrib.auth.backends.password_auth
</pre></div>
</div>
<p>When password auth is enabled, an initial user credential will need to be created before anyone can login. An initial
user was not created in the migrations for this authentication backend to prevent default Airflow installations from
attack. Creating a new user has to be done via a Python REPL on the same machine Airflow is installed.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># navigate to the airflow installation directory</span>
$ <span class="nb">cd</span> ~/airflow
$ python
Python <span class="m">2</span>.7.9 <span class="o">(</span>default, Feb <span class="m">10</span> <span class="m">2015</span>, <span class="m">03</span>:28:08<span class="o">)</span>
Type <span class="s2">&quot;help&quot;</span>, <span class="s2">&quot;copyright&quot;</span>, <span class="s2">&quot;credits&quot;</span> or <span class="s2">&quot;license&quot;</span> <span class="k">for</span> more information.
&gt;&gt;&gt; import airflow
&gt;&gt;&gt; from airflow import models, settings
&gt;&gt;&gt; from airflow.contrib.auth.backends.password_auth import PasswordUser
&gt;&gt;&gt; <span class="nv">user</span> <span class="o">=</span> PasswordUser<span class="o">(</span>models.User<span class="o">())</span>
&gt;&gt;&gt; user.username <span class="o">=</span> <span class="s1">&#39;new_user_name&#39;</span>
&gt;&gt;&gt; user.email <span class="o">=</span> <span class="s1">&#39;new_user_email@example.com&#39;</span>
&gt;&gt;&gt; user.password <span class="o">=</span> <span class="s1">&#39;set_the_password&#39;</span>
&gt;&gt;&gt; <span class="nv">session</span> <span class="o">=</span> settings.Session<span class="o">()</span>
&gt;&gt;&gt; session.add<span class="o">(</span>user<span class="o">)</span>
&gt;&gt;&gt; session.commit<span class="o">()</span>
&gt;&gt;&gt; session.close<span class="o">()</span>
&gt;&gt;&gt; exit<span class="o">()</span>
</pre></div>
</div>
</div>
<div class="section" id="ldap">
<h3>LDAP<a class="headerlink" href="#ldap" title="Permalink to this headline"></a></h3>
<p>To turn on LDAP authentication configure your <code class="docutils literal notranslate"><span class="pre">airflow.cfg</span></code> as follows. Please note that the example uses
an encrypted connection to the ldap server as we do not want passwords be readable on the network level.</p>
<p>Additionally, if you are using Active Directory, and are not explicitly specifying an OU that your users are in,
you will need to change <code class="docutils literal notranslate"><span class="pre">search_scope</span></code> to “SUBTREE”.</p>
<p>Valid search_scope options can be found in the <a class="reference external" href="http://ldap3.readthedocs.org/searches.html?highlight=search_scope">ldap3 Documentation</a></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">authenticate</span> <span class="o">=</span> True
<span class="nv">auth_backend</span> <span class="o">=</span> airflow.contrib.auth.backends.ldap_auth
<span class="o">[</span>ldap<span class="o">]</span>
<span class="c1"># set a connection without encryption: uri = ldap://&lt;your.ldap.server&gt;:&lt;port&gt;</span>
<span class="nv">uri</span> <span class="o">=</span> ldaps://&lt;your.ldap.server&gt;:&lt;port&gt;
<span class="nv">user_filter</span> <span class="o">=</span> <span class="nv">objectClass</span><span class="o">=</span>*
<span class="c1"># in case of Active Directory you would use: user_name_attr = sAMAccountName</span>
<span class="nv">user_name_attr</span> <span class="o">=</span> uid
<span class="c1"># group_member_attr should be set accordingly with *_filter</span>
<span class="c1"># eg :</span>
<span class="c1"># group_member_attr = groupMembership</span>
<span class="c1"># superuser_filter = groupMembership=CN=airflow-super-users...</span>
<span class="nv">group_member_attr</span> <span class="o">=</span> memberOf
<span class="nv">superuser_filter</span> <span class="o">=</span> <span class="nv">memberOf</span><span class="o">=</span><span class="nv">CN</span><span class="o">=</span>airflow-super-users,OU<span class="o">=</span>Groups,OU<span class="o">=</span>RWC,OU<span class="o">=</span>US,OU<span class="o">=</span>NORAM,DC<span class="o">=</span>example,DC<span class="o">=</span>com
<span class="nv">data_profiler_filter</span> <span class="o">=</span> <span class="nv">memberOf</span><span class="o">=</span><span class="nv">CN</span><span class="o">=</span>airflow-data-profilers,OU<span class="o">=</span>Groups,OU<span class="o">=</span>RWC,OU<span class="o">=</span>US,OU<span class="o">=</span>NORAM,DC<span class="o">=</span>example,DC<span class="o">=</span>com
<span class="nv">bind_user</span> <span class="o">=</span> <span class="nv">cn</span><span class="o">=</span>Manager,dc<span class="o">=</span>example,dc<span class="o">=</span>com
<span class="nv">bind_password</span> <span class="o">=</span> insecure
<span class="nv">basedn</span> <span class="o">=</span> <span class="nv">dc</span><span class="o">=</span>example,dc<span class="o">=</span>com
<span class="nv">cacert</span> <span class="o">=</span> /etc/ca/ldap_ca.crt
<span class="c1"># Set search_scope to one of them: BASE, LEVEL , SUBTREE</span>
<span class="c1"># Set search_scope to SUBTREE if using Active Directory, and not specifying an Organizational Unit</span>
<span class="nv">search_scope</span> <span class="o">=</span> LEVEL
</pre></div>
</div>
<p>The superuser_filter and data_profiler_filter are optional. If defined, these configurations allow you to specify LDAP groups that users must belong to in order to have superuser (admin) and data-profiler permissions. If undefined, all users will be superusers and data profilers.</p>
</div>
<div class="section" id="roll-your-own">
<h3>Roll your own<a class="headerlink" href="#roll-your-own" title="Permalink to this headline"></a></h3>
<p>Airflow uses <code class="docutils literal notranslate"><span class="pre">flask_login</span></code> and
exposes a set of hooks in the <code class="docutils literal notranslate"><span class="pre">airflow.default_login</span></code> module. You can
alter the content and make it part of the <code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code> and configure it as a backend in <code class="docutils literal notranslate"><span class="pre">airflow.cfg</span></code>.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">authenticate</span> <span class="o">=</span> True
<span class="nv">auth_backend</span> <span class="o">=</span> mypackage.auth
</pre></div>
</div>
</div>
</div>
<div class="section" id="multi-tenancy">
<h2>Multi-tenancy<a class="headerlink" href="#multi-tenancy" title="Permalink to this headline"></a></h2>
<p>You can filter the list of dags in webserver by owner name when authentication
is turned on by setting <code class="docutils literal notranslate"><span class="pre">webserver:filter_by_owner</span></code> in your config. With this, a user will see
only the dags which it is owner of, unless it is a superuser.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">filter_by_owner</span> <span class="o">=</span> True
</pre></div>
</div>
</div>
<div class="section" id="kerberos">
<h2>Kerberos<a class="headerlink" href="#kerberos" title="Permalink to this headline"></a></h2>
<p>Airflow has initial support for Kerberos. This means that airflow can renew kerberos
tickets for itself and store it in the ticket cache. The hooks and dags can make use of ticket
to authenticate against kerberized services.</p>
<div class="section" id="limitations">
<h3>Limitations<a class="headerlink" href="#limitations" title="Permalink to this headline"></a></h3>
<p>Please note that at this time, not all hooks have been adjusted to make use of this functionality.
Also it does not integrate kerberos into the web interface and you will have to rely on network
level security for now to make sure your service remains secure.</p>
<p>Celery integration has not been tried and tested yet. However, if you generate a key tab for every
host and launch a ticket renewer next to every worker it will most likely work.</p>
</div>
<div class="section" id="enabling-kerberos">
<h3>Enabling kerberos<a class="headerlink" href="#enabling-kerberos" title="Permalink to this headline"></a></h3>
<div class="section" id="airflow">
<h4>Airflow<a class="headerlink" href="#airflow" title="Permalink to this headline"></a></h4>
<p>To enable kerberos you will need to generate a (service) key tab.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># in the kadmin.local or kadmin shell, create the airflow principal</span>
kadmin: addprinc -randkey airflow/fully.qualified.domain.name@YOUR-REALM.COM
<span class="c1"># Create the airflow keytab file that will contain the airflow principal</span>
kadmin: xst -norandkey -k airflow.keytab airflow/fully.qualified.domain.name
</pre></div>
</div>
<p>Now store this file in a location where the airflow user can read it (chmod 600). And then add the following to
your <code class="docutils literal notranslate"><span class="pre">airflow.cfg</span></code></p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>core<span class="o">]</span>
<span class="nv">security</span> <span class="o">=</span> kerberos
<span class="o">[</span>kerberos<span class="o">]</span>
<span class="nv">keytab</span> <span class="o">=</span> /etc/airflow/airflow.keytab
<span class="nv">reinit_frequency</span> <span class="o">=</span> <span class="m">3600</span>
<span class="nv">principal</span> <span class="o">=</span> airflow
</pre></div>
</div>
<p>Launch the ticket renewer by</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># run ticket renewer</span>
airflow kerberos
</pre></div>
</div>
</div>
<div class="section" id="hadoop">
<h4>Hadoop<a class="headerlink" href="#hadoop" title="Permalink to this headline"></a></h4>
<p>If want to use impersonation this needs to be enabled in <code class="docutils literal notranslate"><span class="pre">core-site.xml</span></code> of your hadoop config.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>&lt;property&gt;
&lt;name&gt;hadoop.proxyuser.airflow.groups&lt;/name&gt;
&lt;value&gt;*&lt;/value&gt;
&lt;/property&gt;
&lt;property&gt;
&lt;name&gt;hadoop.proxyuser.airflow.users&lt;/name&gt;
&lt;value&gt;*&lt;/value&gt;
&lt;/property&gt;
&lt;property&gt;
&lt;name&gt;hadoop.proxyuser.airflow.hosts&lt;/name&gt;
&lt;value&gt;*&lt;/value&gt;
&lt;/property&gt;
</pre></div>
</div>
<p>Of course if you need to tighten your security replace the asterisk with something more appropriate.</p>
</div>
</div>
<div class="section" id="using-kerberos-authentication">
<h3>Using kerberos authentication<a class="headerlink" href="#using-kerberos-authentication" title="Permalink to this headline"></a></h3>
<p>The hive hook has been updated to take advantage of kerberos authentication. To allow your DAGs to
use it, simply update the connection details with, for example:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">{</span> <span class="s2">&quot;use_beeline&quot;</span>: true, <span class="s2">&quot;principal&quot;</span>: <span class="s2">&quot;hive/_HOST@EXAMPLE.COM&quot;</span><span class="o">}</span>
</pre></div>
</div>
<p>Adjust the principal to your settings. The _HOST part will be replaced by the fully qualified domain name of
the server.</p>
<p>You can specify if you would like to use the dag owner as the user for the connection or the user specified in the login
section of the connection. For the login user, specify the following as extra:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">{</span> <span class="s2">&quot;use_beeline&quot;</span>: true, <span class="s2">&quot;principal&quot;</span>: <span class="s2">&quot;hive/_HOST@EXAMPLE.COM&quot;</span>, <span class="s2">&quot;proxy_user&quot;</span>: <span class="s2">&quot;login&quot;</span><span class="o">}</span>
</pre></div>
</div>
<p>For the DAG owner use:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">{</span> <span class="s2">&quot;use_beeline&quot;</span>: true, <span class="s2">&quot;principal&quot;</span>: <span class="s2">&quot;hive/_HOST@EXAMPLE.COM&quot;</span>, <span class="s2">&quot;proxy_user&quot;</span>: <span class="s2">&quot;owner&quot;</span><span class="o">}</span>
</pre></div>
</div>
<p>and in your DAG, when initializing the HiveOperator, specify:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="nv">run_as_owner</span><span class="o">=</span>True
</pre></div>
</div>
<p>To use kerberos authentication, you must install Airflow with the <cite>kerberos</cite> extras group:</p>
<div class="highlight-base notranslate"><div class="highlight"><pre><span></span>pip install airflow[kerberos]
</pre></div>
</div>
</div>
</div>
<div class="section" id="oauth-authentication">
<h2>OAuth Authentication<a class="headerlink" href="#oauth-authentication" title="Permalink to this headline"></a></h2>
<div class="section" id="github-enterprise-ghe-authentication">
<h3>GitHub Enterprise (GHE) Authentication<a class="headerlink" href="#github-enterprise-ghe-authentication" title="Permalink to this headline"></a></h3>
<p>The GitHub Enterprise authentication backend can be used to authenticate users
against an installation of GitHub Enterprise using OAuth2. You can optionally
specify a team whitelist (composed of slug cased team names) to restrict login
to only members of those teams.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">authenticate</span> <span class="o">=</span> True
<span class="nv">auth_backend</span> <span class="o">=</span> airflow.contrib.auth.backends.github_enterprise_auth
<span class="o">[</span>github_enterprise<span class="o">]</span>
<span class="nv">host</span> <span class="o">=</span> github.example.com
<span class="nv">client_id</span> <span class="o">=</span> oauth_key_from_github_enterprise
<span class="nv">client_secret</span> <span class="o">=</span> oauth_secret_from_github_enterprise
<span class="nv">oauth_callback_route</span> <span class="o">=</span> /example/ghe_oauth/callback
<span class="nv">allowed_teams</span> <span class="o">=</span> <span class="m">1</span>, <span class="m">345</span>, <span class="m">23</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you do not specify a team whitelist, anyone with a valid account on
your GHE installation will be able to login to Airflow.</p>
</div>
<p>To use GHE authentication, you must install Airflow with the <cite>github_enterprise</cite> extras group:</p>
<div class="highlight-base notranslate"><div class="highlight"><pre><span></span>pip install airflow[github_enterprise]
</pre></div>
</div>
<div class="section" id="setting-up-ghe-authentication">
<h4>Setting up GHE Authentication<a class="headerlink" href="#setting-up-ghe-authentication" title="Permalink to this headline"></a></h4>
<p>An application must be setup in GHE before you can use the GHE authentication
backend. In order to setup an application:</p>
<ol class="arabic simple">
<li>Navigate to your GHE profile</li>
<li>Select ‘Applications’ from the left hand nav</li>
<li>Select the ‘Developer Applications’ tab</li>
<li>Click ‘Register new application’</li>
<li>Fill in the required information (the ‘Authorization callback URL’ must be fully qualified e.g. <a class="reference external" href="http://airflow.example.com/example/ghe_oauth/callback">http://airflow.example.com/example/ghe_oauth/callback</a>)</li>
<li>Click ‘Register application’</li>
<li>Copy ‘Client ID’, ‘Client Secret’, and your callback route to your airflow.cfg according to the above example</li>
</ol>
</div>
<div class="section" id="using-ghe-authentication-with-github-com">
<h4>Using GHE Authentication with github.com<a class="headerlink" href="#using-ghe-authentication-with-github-com" title="Permalink to this headline"></a></h4>
<p>It is possible to use GHE authentication with github.com:</p>
<ol class="arabic simple">
<li><a class="reference external" href="https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/">Create an Oauth App</a></li>
<li>Copy ‘Client ID’, ‘Client Secret’ to your airflow.cfg according to the above example</li>
<li>Set <code class="docutils literal notranslate"><span class="pre">host</span> <span class="pre">=</span> <span class="pre">github.com</span></code> and <code class="docutils literal notranslate"><span class="pre">oauth_callback_route</span> <span class="pre">=</span> <span class="pre">/oauth/callback</span></code> in airflow.cfg</li>
</ol>
</div>
</div>
<div class="section" id="google-authentication">
<h3>Google Authentication<a class="headerlink" href="#google-authentication" title="Permalink to this headline"></a></h3>
<p>The Google authentication backend can be used to authenticate users
against Google using OAuth2. You must specify the domains to restrict
login, separated with a comma, to only members of those domains.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">authenticate</span> <span class="o">=</span> True
<span class="nv">auth_backend</span> <span class="o">=</span> airflow.contrib.auth.backends.google_auth
<span class="o">[</span>google<span class="o">]</span>
<span class="nv">client_id</span> <span class="o">=</span> google_client_id
<span class="nv">client_secret</span> <span class="o">=</span> google_client_secret
<span class="nv">oauth_callback_route</span> <span class="o">=</span> /oauth2callback
<span class="nv">domain</span> <span class="o">=</span> <span class="s2">&quot;example1.com,example2.com&quot;</span>
</pre></div>
</div>
<p>To use Google authentication, you must install Airflow with the <cite>google_auth</cite> extras group:</p>
<div class="highlight-base notranslate"><div class="highlight"><pre><span></span>pip install airflow[google_auth]
</pre></div>
</div>
<div class="section" id="setting-up-google-authentication">
<h4>Setting up Google Authentication<a class="headerlink" href="#setting-up-google-authentication" title="Permalink to this headline"></a></h4>
<p>An application must be setup in the Google API Console before you can use the Google authentication
backend. In order to setup an application:</p>
<ol class="arabic simple">
<li>Navigate to <a class="reference external" href="https://console.developers.google.com/apis/">https://console.developers.google.com/apis/</a></li>
<li>Select ‘Credentials’ from the left hand nav</li>
<li>Click ‘Create credentials’ and choose ‘OAuth client ID’</li>
<li>Choose ‘Web application’</li>
<li>Fill in the required information (the ‘Authorized redirect URIs’ must be fully qualified e.g. <a class="reference external" href="http://airflow.example.com/oauth2callback">http://airflow.example.com/oauth2callback</a>)</li>
<li>Click ‘Create’</li>
<li>Copy ‘Client ID’, ‘Client Secret’, and your redirect URI to your airflow.cfg according to the above example</li>
</ol>
</div>
</div>
</div>
<div class="section" id="ssl">
<h2>SSL<a class="headerlink" href="#ssl" title="Permalink to this headline"></a></h2>
<p>SSL can be enabled by providing a certificate and key. Once enabled, be sure to use
<a class="reference external" href="https://">https://</a>” in your browser.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>webserver<span class="o">]</span>
<span class="nv">web_server_ssl_cert</span> <span class="o">=</span> &lt;path to cert&gt;
<span class="nv">web_server_ssl_key</span> <span class="o">=</span> &lt;path to key&gt;
</pre></div>
</div>
<p>Enabling SSL will not automatically change the web server port. If you want to use the
standard port 443, you’ll need to configure that too. Be aware that super user privileges
(or cap_net_bind_service on Linux) are required to listen on port 443.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Optionally, set the server to listen on the standard SSL port.</span>
<span class="nv">web_server_port</span> <span class="o">=</span> <span class="m">443</span>
<span class="nv">base_url</span> <span class="o">=</span> http://&lt;hostname or IP&gt;:443
</pre></div>
</div>
<p>Enable CeleryExecutor with SSL. Ensure you properly generate client and server
certs and keys.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>celery<span class="o">]</span>
<span class="nv">ssl_active</span> <span class="o">=</span> True
<span class="nv">ssl_key</span> <span class="o">=</span> &lt;path to key&gt;
<span class="nv">ssl_cert</span> <span class="o">=</span> &lt;path to cert&gt;
<span class="nv">ssl_cacert</span> <span class="o">=</span> &lt;path to cacert&gt;
</pre></div>
</div>
</div>
<div class="section" id="impersonation">
<h2>Impersonation<a class="headerlink" href="#impersonation" title="Permalink to this headline"></a></h2>
<p>Airflow has the ability to impersonate a unix user while running task
instances based on the task’s <code class="docutils literal notranslate"><span class="pre">run_as_user</span></code> parameter, which takes a user’s name.</p>
<p><strong>NOTE:</strong> For impersonations to work, Airflow must be run with <cite>sudo</cite> as subtasks are run
with <cite>sudo -u</cite> and permissions of files are changed. Furthermore, the unix user needs to
exist on the worker. Here is what a simple sudoers file entry could look like to achieve
this, assuming as airflow is running as the <cite>airflow</cite> user. Note that this means that
the airflow user must be trusted and treated the same way as the root user.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>airflow ALL=(ALL) NOPASSWD: ALL
</pre></div>
</div>
<p>Subtasks with impersonation will still log to the same folder, except that the files they
log to will have permissions changed such that only the unix user can write to it.</p>
<div class="section" id="default-impersonation">
<h3>Default Impersonation<a class="headerlink" href="#default-impersonation" title="Permalink to this headline"></a></h3>
<p>To prevent tasks that don’t use impersonation to be run with <cite>sudo</cite> privileges, you can set the
<code class="docutils literal notranslate"><span class="pre">core:default_impersonation</span></code> config which sets a default user impersonate if <cite>run_as_user</cite> is
not set.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>core<span class="o">]</span>
<span class="nv">default_impersonation</span> <span class="o">=</span> airflow
</pre></div>
</div>
</div>
</div>
<div class="section" id="flower-authentication">
<h2>Flower Authentication<a class="headerlink" href="#flower-authentication" title="Permalink to this headline"></a></h2>
<p>Basic authentication for Celery Flower is supported.</p>
<p>You can specify the details either as an optional argument in the Flower process launching
command, or as a configuration item in your <code class="docutils literal notranslate"><span class="pre">airflow.cfg</span></code>. For both cases, please provide
<cite>user:password</cite> pairs separated by a comma.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>airflow flower --basic_auth<span class="o">=</span>user1:password1,user2:password2
</pre></div>
</div>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="o">[</span>celery<span class="o">]</span>
<span class="nv">flower_basic_auth</span> <span class="o">=</span> user1:password1,user2:password2
</pre></div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="timezone.html" class="btn btn-neutral float-right" title="Time zones" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="plugins.html" class="btn btn-neutral" title="Plugins" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>