Documentation

10. Setting up Authentication

Ansible Tower version 2.4.0 added authentication methods to help simplify logins for end users–offering single sign-ons using existing login information to sign into a third party website rather than creating a new login account specifically for that website.

Social authentication in Ansible Tower can be configured to centrally use OAuth2, while enterprise-level authentication can be configured for SAML, RADIUS, or even LDAP as a source for authentication information.

For websites, such as Google or GitHub, that offer social functionality to users, social login is often implemented using the OAuth standard. OAuth is a secure authorization protocol which is commonly used in conjunction with authentication to grant 3rd party applications a “session token” allowing them to make API calls to providers on the user’s behalf.

SAML (Security Assertion Markup Language) is an XML-based, open-standard data format for exchanging authentication and authorization data between an identity provider and a service provider.

The RADIUS distributed client/server system allows you to secure networks against unauthorized access and can be implemented in network environments requiring high levels of security while maintaining network access for remote users.

10.1. Basic Authentication Settings:

To enable or disable HTTP basic authentication as used in the API browser, edit the sessions.py file, setting the following line as either True or False:

AUTH_BASIC_ENABLED = False

After saving your changes, run the ansible-tower-service restart command to ensure your changes take effect.

10.2. Google OAuth2 Settings

Create a project at https://console.developers.google.com/ and obtain an OAuth2 key and secret for a web application. You will also need to provide the following callback URL for your application, replacing “tower.example.com” with the FQDN to your Tower server: https://tower.example.com/sso/complete/google-oauth2/

Ensure that the Google+ API is enabled.

Edit the /etc/tower/conf.d/social_auth.py file and enter in the appropriate values:

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = ''
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = ''

To restrict the domains who are allowed to login using Google OAuth2, uncomment the following line.

SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = ['example.com']

To only allow a single domain to authenticate using Google OAuth2, uncomment the following line; Google will not display any other accounts if the user is logged in with multiple Google accounts.

SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {'hd': 'example.com'}

Refer to the Python Social Auth documentation for advanced settings: https://python-social-auth.readthedocs.org/en/latest/backends/google.htmlgoogle-oauth2

Run ansible-tower-service restart on the Tower server to restart the instance and apply your changes.

10.3. Github OAuth2 Settings

Create a developer application at https://github.com/settings/developers and obtain an OAuth2 key (Client ID) and secret (Client Secret). You will also need to provide the following callback URL for your application, replacing “tower.example.com” with the FQDN to your Tower server: https://tower.example.com/sso/complete/github/

Edit the /etc/tower/conf.d/social_auth.py file and enter in the appropriate values:

SOCIAL_AUTH_GITHUB_KEY = ''
SOCIAL_AUTH_GITHUB_SECRET = ''

When defining authentication with either an organization or a team within an organization, you should use the specific organization and team settings. Authentication can be limited by an organization as well as by a team within an organization.

You can also choose to allow all by specifying non-organization or non-team based settings (as shown above).

To limit users who can login to Tower, in this case, to only those in an organization or on a team within an organization, rather than using:

SOCIAL_AUTH_GITHUB_KEY

Use the following instead (depending on whether you are setting up for an organization or a team):

SOCIAL_AUTH_GITHUB_ORG_KEY

SOCIAL_AUTH_GITHUB_TEAM_KEY

To setup authentication for your organization, create an organization-owned application at https://github.com/organizations/<yourorg>/settings/applications and obtain an OAuth2 key (Client ID) and secret (Client Secret). Each key and secret must belong to a unique application and cannot be shared or reused between different social authentication backends. Provide the following callback URL for your application, replacing “tower.example.com” with the FQDN to your Tower server: https://tower.example.com/sso/complete/github-org/

SOCIAL_AUTH_GITHUB_ORG_KEY = ''
SOCIAL_AUTH_GITHUB_ORG_SECRET = ''
SOCIAL_AUTH_GITHUB_ORG_NAME = ''

To setup authentication for your team, create a team-owned application at https://github.com/organizations/<yourorg>/settings/applications and obtain an OAuth2 key (Client ID) and secret (Client Secret). Each key and secret must belong to a unique application and cannot be shared or reused between different social authentication backends. You will also need to provide the following callback URL for your application, replacing “tower.example.com” with the FQDN to your Tower server: https://tower.example.com/sso/complete/github-team/

Find the numeric team ID using the Github API: http://fabian-kostadinov.github.io/2015/01/16/how-to-find-a-github-team-id/

SOCIAL_AUTH_GITHUB_TEAM_KEY = ''
SOCIAL_AUTH_GITHUB_TEAM_SECRET = ''
SOCIAL_AUTH_GITHUB_TEAM_ID = ''

Refer to Python Social Auth documentation for advanced settings: https://python-social-auth.readthedocs.org/en/latest/backends/github.html

Run ansible-tower-service restart on the Tower server to restart the instance and apply your changes.

10.4. SAML Authentication Settings

Note

SAML authentication is a feature specific to Enterprise-level license holders.

To setup SAML authentication, edit the /etc/tower/conf.d/social_auth.py file and enter in the appropriate values.

Set the SOCIAL_AUTH_SAML_SP_ENTITY_ID to a URL for a domain name you own (does not need to be a valid URL as this value is only used as a unique ID).

SOCIAL_AUTH_SAML_SP_ENTITY_ID = 'https://tower.example.com'

Create a keypair for Tower to use as a service provider (SP) and include the certificate and private key contents:

SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = ''
SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = ''

As an example for public certs:

SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = '''

-----BEGIN CERTIFICATE——
... cert text ...
-----END CERTIFICATE——

As an example for private keys:

SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = '''
-----BEGIN PRIVATE KEY--
... key text ...
-----END PRIVATE KEY——
'''

Configure the following settings with information about your application and contact information:

SOCIAL_AUTH_SAML_ORG_INFO = {
    'en-US': {
        'name': 'example',
        'displayname': 'Example',
        'url': 'http://www.example.com',
    },
}
SOCIAL_AUTH_SAML_TECHNICAL_CONTACT = {
    'givenName': 'Some User',
    'emailAddress': '[email protected]',
}
SOCIAL_AUTH_SAML_SUPPORT_CONTACT = {
    'givenName': 'Some User',
    'emailAddress': '[email protected]',
}

Configure the entity ID, SSO URL and certificate for each identity provider (IdP) in use. Multiple SAML IdPs are supported.

Some IdPs may provide user data using attribute names that differ from the default OIDs (https://github.com/omab/python-social-auth/blob/master/social/backends/saml.py). Attribute names may be overridden for each IdP as shown below.

SOCIAL_AUTH_SAML_ENABLED_IDPS = {
    'myidp': {
        'entity_id': 'https://idp.example.com',
        'url': 'https://myidp.example.com/sso',
        'x509cert': '',
    },
    'onelogin': {
        'entity_id': 'https://app.onelogin.com/saml/metadata/123456',
        'url': 'https://example.onelogin.com/trust/saml2/http-post/sso/123456',
        'x509cert': '',
        'attr_user_permanent_id': 'name_id',
        'attr_first_name': 'User.FirstName',
        'attr_last_name': 'User.LastName',
        'attr_username': 'User.email',
        'attr_email': 'User.email',
    },
}

Your SAML identity provider (IdP) may provide a certificate to put into the x509cert field. You can take that certificate (assuming it is base64 encoded), remove the BEGIN and END lines, concatenate all of the remaining lines into one (making sure there are no spaces), and put that single long line, string into the field.

Run ansible-tower-service restart on the Tower server to restart the instance and apply your changes.

Once configuration is complete, you must register your SP with each IdP. Provide the entity ID and the following callback URL for your application, replacing “tower.example.com” with the FQDN to your Tower server: https://tower.example.com/sso/complete/saml/

If your IdP allows uploading an XML metadata file, you can download one from your Tower installation customized with the settings above: https://tower.example.com/sso/metadata/saml/

10.5. RADIUS Authentication Settings

Note

RADIUS authentication is a feature specific to Enterprise-level license holders.

Ansible Tower can be configured to centrally use RADIUS as a source for authentication information. If backed by Active Directory, user access can be configured for RADIUS.

Edit the /etc/tower/conf.d/radius.py file and enter in the appropriate RADIUS server settings (skipped when RADIUS_SERVER is blank):

RADIUS_SERVER = ''
RADIUS_PORT = 1812
RADIUS_SECRET = ''

Run ansible-tower-service restart on the Tower server to restart the instance and apply your changes.

10.6. Using LDAP with Tower

Note

LDAP authentication is a feature specific to Enterprise-level license holders.

Administrators use LDAP as a source for authentication information for Tower users. User authentication is provided, but not the synchronization of user permissions and credentials. Organization membership (as well as the organization admin) and team memberships can be synchronized.

When so configured, a user who logs in with an LDAP username and password automatically gets a Tower account created for them and they can be automatically placed into organizations as either regular users or organization administrators.

Users created via an LDAP login cannot change their username, first name, last name, or set a local password for themselves. This is also tunable to restrict editing of other field names.

LDAP integration for Tower is configured in the file /etc/tower/conf.d/ldap.py. No configuration is accessible via the Tower user interface. Review the comments in that file for information on LDAP configuration and contact Ansible support via the Red Hat Customer Portal if you need help: https://access.redhat.com/

Note

Users of older versions of Tower (prior to Tower version 2.3) should update /etc/tower/settings.py instead of files within /etc/tower/conf.d/.

10.6.1. Enabling Logging for LDAP

To enable logging for LDAP, you must set the level to DEBUG in the LDAP configuration file, /etc/tower/conf/ldap.py:

LOGGING['handlers']['tower_warnings']['level'] =  'DEBUG'

10.7. Organization and Team Mapping

Next, you will need to control which users are placed into which Tower organizations based on their username and email address (mapping out your organization admins/users from social or enterprise-level authentication accounts).

Dictionary keys are organization names. Organizations will be created, if not already present and if the license allows for multiple organizations. Otherwise, the single default organization is used regardless of the key.

Values are dictionaries defining the options for each organization’s membership. For each organization, it is possible to specify which users are automatically users of the organization and also which users can administer the organization.

admins: None, True/False, string or list/tuple of strings.

  • If None, organization admins will not be updated.
  • If True, all users using social authentication will automatically be added as admins of the organization.
  • If False, no social authentication users will be automatically added as admins of the organization.
  • If a string or list of strings, specifies the usernames and emails for users who will be added to the organization. Compiled regular expressions may also be used instead of string literals.

remove_admins: True/False. Defaults to False.

  • If True, a user who does not match will be removed from the organization’s administrative list.

users: None, True/False, string or list/tuple of strings. Same rules apply as for admins.

remove_users: True/False. Defaults to False. Same rules as apply for remove_admins.

SOCIAL_AUTH_ORGANIZATION_MAP = {
 Add all users to the default organization.
'Default': {
    'users': True,
},
'Test Org': {
    'admins': ['[email protected]'],
    'users': True,
},
'Test Org 2': {
    'admins': ['[email protected]', re.compile(r'^tower-[^@]+*?@.*$],
    'users': re.compile(r'^[^@].*?@example\.com$'),
},
}

Organization mappings may be specified separately for each social authentication backend. If defined, these configurations will take precedence over the global configuration above.

SOCIAL_AUTH_GOOGLE_OAUTH2_ORGANIZATION_MAP = {}
SOCIAL_AUTH_GITHUB_ORGANIZATION_MAP = {}
SOCIAL_AUTH_GITHUB_ORG_ORGANIZATION_MAP = {}
SOCIAL_AUTH_GITHUB_TEAM_ORGANIZATION_MAP = {}
SOCIAL_AUTH_SAML_ORGANIZATION_MAP = {}

Mapping of team members (users) from social auth accounts. Keys are team names (will be created if not present). Values are dictionaries of options for each team’s membership, where each can contain the following parameters:

organization: string. The name of the organization to which the team belongs. The team will be created if the combination of organization and team name does not exist. The organization will first be created if it does not exist. If the license does not allow for multiple organizations, the team will always be assigned to the single default organization.

users: None, True/False, string or list/tuple of strings.

  • If None, team members will not be updated.
  • If True/False, all social auth users will be added/removed as team members.
  • If a string or list of strings, specifies expressions used to match users. User will be added as a team member if the username or email matches. Compiled regular expressions may also be used instead of string literals.

remove: True/False. Defaults to False. If True, a user who does not match the rules above will be removed from the team.

SOCIAL_AUTH_TEAM_MAP = {
'My Team': {
    'organization': 'Test Org',
    'users': ['re.compile(r'^[^@]+?@test\.example\.com$')'],
    'remove': True,
},
'Other Team': {
    'organization': 'Test Org 2',
    'users': re.compile(r'^[^@]+?@test2\.example\.com$'),
    'remove': False,
},
}

Team mappings may be specified separately for each social authentication backend, based on which of these you setup. If defined, these configurations will take precedence over the the global configuration above.

SOCIAL_AUTH_GOOGLE_OAUTH2_TEAM_MAP = {}
SOCIAL_AUTH_GITHUB_TEAM_MAP = {}
SOCIAL_AUTH_GITHUB_ORG_TEAM_MAP = {}
SOCIAL_AUTH_GITHUB_TEAM_TEAM_MAP = {}
SOCIAL_AUTH_SAML_TEAM_MAP = {}

Uncomment the line below (i.e. set SOCIAL_AUTH_USER_FIELDS to an empty list) to prevent new user accounts from being created. Only users who have previously logged in to Tower using social or enterprise-level authentication or have a user account with a matching email address will be able to login.

SOCIAL_AUTH_USER_FIELDS = []