# Architecture

The Swift API is HTTP-based. As described in the Swift documentation
[1], clients first make a request to an authentication URL, providing
a username and password. The reply contains a token which is used in
all subsequent requests.

Swift has a chain of filters through which all client requests go. The
filters to use are configured with the pipeline parameter in
/etc/swift/proxy-server.conf:

    [pipeline:main]
    pipeline = healthcheck cache tempauth proxy-server

For the single sign authentication, we added a new filter called
"kerbauth" and put it into the filter pipeline in place of tempauth.

The filter checks the URL for each client request. If it matches the
authentication URL, the client is redirected to a URL on a different
server (on the same machine). The URL is handled by a CGI script, which 
is set up to authenticate the client with Kerberos negotiation, retrieve
the user's system groups [2], store them in a memcache ring shared with
the Swift server, and return the authentication token to the client.

When the client provides the token as part of a resource request, the
kerbauth filter checks it against its memcache, grants administrator
rights based on the group membership retrieved from memcache, and
either grants or denies the resource access.

[1] http://docs.openstack.org/api/openstack-object-storage/1.0/content/authentication-object-dev-guide.html

[2] The user data and system groups are usually provided by Red Hat
    Enterprise Linux identity Management or Microsoft Active
    Directory. The script relies on the system configuration to be set
    accordingly (/etc/nsswitch.conf).

*****

## kerbauth.py

The script /usr/lib/python2.6/site-packages/swiftkerbauth.py began as
a copy of the tempauth.py script from
/usr/lib/python2.6/site-packages/swift/common/middleware. It contains
the following modifications, among others:

In the __init__ method, we read the ext_authentication_url parameter
from /etc/swift/proxy-server.conf. This is the URL that clients are
redirected to when they access either the Swift authentication URL, or
when they request a resource without a valid authentication token.

The configuration in proxy-server.conf looks like this:

    [filter:kerbauth]
    use = egg:swiftkerbauth#kerbauth
    ext_authentication_url = http://client.rhelbox.com/cgi-bin/swift-auth

The authorize method was changed so that global administrator rights
are granted if the user is a member of the auth_reseller_admin
group. Administrator rights for a specific account like vol1 are
granted if the user is a member of the auth_vol1 group. [3]

The denied_response method was changed to return a HTTP redirect to
the external authentication URL if no valid token was provided by the
client.

Most of the handle_get_token method was moved to the external
authentication script. This method now returns a HTTP redirect.

In the __call__ and get_groups method, we removed support for the
HTTP_AUTHORIZATION header, which is only needed when Amazon S3 is
used.

Like tempauth.py, swiftkerbauth.py uses a Swift wrapper to access
memcache. This wrapper converts the key to an MD5 hash and uses the
hash value to determine on which of a pre-defined list of servers to
store the data.

[3] "auth" is the default reseller prefix, and would be different if
    the reseller_prefix parameter in proxy-server.conf was set.

## swift-auth CGI script

swift-auth resides on an Apache server and assumes that Apache is
configured to authenticate the user before this script is
executed. The script retrieves the username from the REMOTE_USER
environment variable, and checks if there already is a token for this
user in the memcache ring. If not, it generates a new one, retrieves
the user's system groups with "id -Gn USERNAME", stores this
information in the memcache ring, and returns the token to the client.

To allow the CGI script to connect to memcache, the SELinux booleans
httpd_can_network_connect and httpd_can_network_memcache had to be
set.

The tempauth filter uses the uuid module to generate token
strings. This module creates and runs temporary files, which leads to
AVC denial messages in /var/log/audit/audit.log when used from an
Apache CGI script. While the module still works, the audit log would
grow quickly. Instead of writing an SELinux policy module to allow or
to silently ignore these accesses, the swift-auth script uses the
"random" module for generating token strings.

Red Hat Enterprise Linux 6 comes with Python 2.6 which only provides
method to list the locally defined user groups. To include groups from
Red Hat Enterprise Linux Identity Management and in the future from
Active Directory, the "id" command is run in a subprocess.
