JetS3t Gatekeeper

Gatekeeper is a server-side application for authorizing client applications to interact with an S3 account without providing the client with the AWS login credentials. The Gatekeeper uses the S3 Query String Authorization URL signing capabilities to generate time-limited URLs that client applications use to Upload, Download, and Delete objects in S3.

Gatekeeper is primarily intended for situations where a service provider has an S3 account where they store data on behalf of clients. The service provider manages the S3 storage on behalf of the client, who need not know or care that S3 is the underlying technology being used.

Gatekeeper was designed to work with the CockpitLite and Uploader client-side applications that are included in the JetS3t suite.

Introductory Concepts

Although a Gatekeeper Java Servlet implementation is available as part of the JetS3t suite, the concepts involved in providing a gatekeeper-like service for S3 could be easily implemented in other server-side languages. These concepts are discussed in a generic way in Gatekeeper Concepts, please read this document first if you wish to understand how the Gatekeeper works, or implement your own version of the Gatekeeper.

Running the Gatekeeper Servlet

The Gatekeeper servlet is packaged as a standard WAR (Web Application aRchive) file in the JetS3t distribution:
servlets/gatekeeper/gatekeeper-0.9.1.war
This WAR file can be deployed to any application server that is able to run Java servlets.

For example, to deploy it to the Apache Tomcat server simply copy the WAR file to the $TOMCAT_HOME/webapps directory. When you run Tomcat the servlet archive will be automatically extracted and run, and will be available at a URL looking something like this:
http://localhost:8080/gatekeeper-0.9.1/GatekeeperServlet

Configuration

The JetS3t Gatekeeper is configurable in two ways: by configuring the standard functionality included with the servlet, and by adding specialised functionality with code modules. This section deals with the standard configuration.

The Gatekeeper is configured by setting properties in the servlet's web.xml configuration file (found in the WEB-INF directory). The configuration includes two steps:

  1. Specific configuration parameters required by the implementation classes. For the default Gatekeeper, the only settings required are your AWS credentials and the name of an S3 bucket.
  2. If you wish to modify the Gatekeeper application to work with your own, existing authentication framework, you can provide your own implementation classes for the authentication modules: TransactionIdProvider, Gatekeeper, UrlSigner, and BucketLister.

Configuration Properties

Properties for default implementation
AwsAccessKey AWS Access Key for an S3 Account
AwsSecretKey AWS Secret Key for an S3 Account
S3BucketName The name of the bucket where objects are stored, and where files will be uploaded to
SecondsToSign The number of seconds until signed URLs will expire
Default: 180
Implementation Classes - Override these to implement specialized functionality
TransactionIdProviderClass A class that generates a unique transaction ID for each message received from a client.
Default: org.jets3t.servlets.gatekeeper.impl.DefaultTransactionIdProvider
AuthorizerClass A class that determines whether or allow or deny a particular operation request
Default: org.jets3t.servlets.gatekeeper.impl.DefaultAuthorizer
UrlSignerClass The class that generates signed URLs for GET, HEAD, PUT and DELETE operations.
Default: org.jets3t.servlets.gatekeeper.impl.DefaultUrlSigner
BucketListerClass A class that returns a listing of a bucket's contents to the CockpitLite application. This listing may include all of a bucket's contents, or only a subset.
Default: org.jets3t.servlets.gatekeeper.impl.DefaultBucketLister

User Authentication

The Gatekeeper application is designed to be extended with code modules that perform specific tasks, such as authenticating users and permitting them to perform specific operations on the mediated S3 account. However, the simplest way to enforce user authentication with the Gatekeeper is to put the servlet in a secured web location that is only accessible when the user enters a valid username and password.

A simple form of user authentication can be applied by requiring HTTP Authorization. This authorization mechanism is supported by all web server and servlet engines and is relatively simple to setup and configure. By limiting access to the Gatekeeper in this way you can ensure that only authorized users can access the S3 account mediated by the Gatekeeper without having to implement your own modules.

Specializing the Gatekeeper

The Gatekeeper implementation can be specialized by plugging in code components to perform the tasks of the TransactionIdProvider, Gatekeeper, and UrlSigner. Each of these components has an abstract base class named after the component in the package org.jets3t.servlets.gatekeeper.

The code components are plugged into the servlet by making the new implementation classes available to the servlet as a library or in the WEB-INF/classes directory, and changing the appropriate implementation class configuring property (see above) to refer to the new implementation.

Example implementation: RenameToUuidUrlSigner

The example UrlSigner implementation class RenameToUuidUrlSigner exends the DefaultUrlSigner to perform basic object renaming based on the Transaction ID that uniquely identifies each request message from a client. This class renames all objects to the format transactionId.objectCount.objectExtension, and adds a metadata property transactionId to store the transaction id. For example, a file uploaded with the name MyDocument.txt and assigned a transaction id ABC123 will be renamed to ABC123.0.txt and will have a metadata property transactionId with the value ABC123.

This class also recognises a special type of object used by the JetS3t Uploader application, and flagged with the special object metadata item jets3t-uploader-summary-doc. This special object is an XML document that may be generated as a summary of the files the Uploader has successfully stored to S3. This object is not renamed, as the Uploader application itself assigns the XML document with a name based on the transaction ID used for the prior uploads.