A Gatekeeper is a design pattern in which access to storage is brokered so as to minimize the attack surface of privileged roles by limiting their interaction to communication over private internal channels and only to other web/worker roles. These roles are deployed on separate VMs. In the event of a successful attack on a web role, privileged key material is not compromised. The pattern can best be illustrated by the following example which uses two roles:
- The GateKeeper –
this is a web role that services requests from the Internet. Since these requests are potentially malicious, the Gatekeeper is not trusted with any duties other than validating the input it receives. The GateKeeper is implemented in managed code and runs with Windows Azure Partial Trust. The service configuration settings for this role do not contain any Shared Key information for use with Windows Azure Storage.
- The KeyMaster –
this is a privileged backend worker role that only takes inputs from the Gatekeeper and does so over a secured channel (an internal endpoint, or queue storage – either of which can be secured with HTTPS). The KeyMaster handles storage requests fed to it by the GateKeeper, and assumes that the requests have been sanitized to some degree. The KeyMaster, as the name implies, is configured with Windows Azure Storage account information from the service configuration to enableretrieval of data from Blob or Table storage. Data can then be relayed back to the requesting client. Nothing about this design requires Full Trust or Native Code, but it offers the flexibility of running the KeyMaster in a higher privilege level if necessary.
This solution is not ideal, since the KeyMaster is relying on GateKeeper to tell it what content to serve out. However, it does provide for separation of duty and it can poses additional challenges for an attacker. The amount of trust the KeyMaster places in the GateKeeper can be custom-tailored, but it is advisable to minimize the types of access requests allowed from the GateKeeper — allowing the KeyMaster to accept Storage Blob API read and list operations from GateKeeper, but not add or delete operations, for example.
This pattern can easily be adapted to work with more complex service architectures on Windows Azure. All that is needed is to put a partial trust “Gatekeeper” in front of more privileged (or native code) roles to do the parsing of potentially malicious data from the network. The concept is analogous to a firewall running as Network Service to interact with foreign TCP payloads before pushing them up the stack to more critical components.
The pattern is explained in the paper Security Best Practices For Developing Windows Azure Applications,which can be downloaded from from Microsoft Download.
