Design

Overview

As opposed to the |SPECS| security tokens service, which is a completely new |SPECS| solution, designed and implemented from ground-up, the current credential service is tailored to handle existing security protocols, which in the current phase of the project are mainly |CSP| target service authentication schemes.

Because the main targeted |CSP|'s are |AWS| and |Eucalyptus|, both implementing the same de-facto standard (namely the one proposed by |Amazon|), the current prototype implements only the needed procedures to authenticate requests for this common security protocol. However the design presented below is generic enough that it can be tailored for other security protocols.

We shall first present a brief introduction into the current authentication schemes used by most |CSP|'s, followed by a brief description the concepts used by the credential service. Then we present the overall current and future architecture, and conclude with brief discussions about architectural, security and implementation concerns.

Important

We can not stress enough the fact that in the context of the credential service, the clients we speak about are not "humans" but instead software components or agents which interact with various external services on behalf of the |EU|. These clients are part of the deployed |SPECS| applications, acting on behalf of real persons which are |EU| in the |SPECS| terminology; meanwhile at the opposite end of the spectrum, the target services are other software components or agents part of either the same deployed |SPECS| applications, or most likely services offered as |SaaS| by external |CSP|'s.

Authentication schemes

Before going further into the details, we make a small detour and present how the usual (as in implemented by most |CSP|'s) authentication schemes work.

Basically most |CSP|'s provide the |EU| (developer or operator) a set of shared secrets that must be used when making calls to the services. For each individual call (in almost all cases |HTTP| calls conveying |REST|-ful requests or |SOAP| messages) the caller (a custom library provided by the |CSP|, operating on behalf of the |EU|) generates a fingerprint which uniquely identifies the call in question. Then this fingerprint is cryptographically combined (still by the |CSP| provided library) with the shared secret to obtain an authenticator, again, unique to the current call. Afterwards the call is submitted with the authenticator attached (in case of |HTTP| calls most likely as a header).

Technically in almost all cases the fingerprint involves a series of cryptographic hash function applications, and the authenticator involves a series of cryptographic |HMAC| function applications. The providers which implement such a scheme are all those compliant with the |AWS| de-facto standard (including |Eucalyptus|, |OpenStack|, newer versions of |OpenNebula|, etc.) |xiwe|.

On the other side some |CSP|'s use much more simple authentication schemes (again completely proprietary and not interoperable), many simply involving a cryptographic hash function application over the shared secret and timestamp (like in case of |GoGrid| |zowu|); some even require just sending the shared secrets with each call (like in the case of older versions of |OpenNebula|); meanwhile others imply obtaining a temporary access token (like in the case of |RackSpace| |yete|).

Concepts

The following are the concepts used by the credential service, which are essential for understanding the way this solution works and how it should be integrated into clients, and possible target services.

Credential:
As hinted in the overview of this report, credentials are any "secret" data that are used to access remote services (either provided by |CSP| or other applications), and which should be protected against leaks. For example in case of |AWS| they are pairs of "access-key" and "secret-key", but they can be any kind data which is expressible with the |JSON| syntax, including binary data as |Base64| strings, from private / public key pairs, to shared secrets, etc.
Module
It is an internal concept to the credential service (therefore not related with the module concept in the global |SPECS| terminology), and represents the set of operations that can be executed over a certain credential. Thus it is mostly just a logical grouping of operations, a kind of namespace in procedural programming languages or class or type in object oriented ones. However in terms of implementation, all the operations of a module are written inside the same file and loaded as a unit (see below in listing providing the implementation of the |AWS| module).
Operation
It is an algorithmic procedure (in most cases involving cryptographic functions), which based on inputs derived (by the client) from the actual request, returns a set of outputs that should be used to complement and authenticate the request. For example in case of |AWS| we have the authentication scheme described in |xiwe|.

Architecture

The architecture of the current prototype is quite simple, on the credential service side having only a single process (which internally uses an embedded database for storing the credentials), and on the client side a simple library which implements the |HTTP|-based |REST|-ful |API| needed to execute part of the security protocol and delegate the rest.

It must be noted the exposed |API| is so simple, that one can directly use the credential service directly from the console by invoking curl, just as seen in the listings in the section dedicated to its usage.

The current architecture are heavily influenced by the |Plan9| factotum service |zoti|, which fulfills a similar role.

Current architecture

For a sketch of the architecture one can look at the figure below, where the involved entities and the sequence of the calls are clearly identified.

http://data.volution.ro/specs/public/blueprints/uml/credential-service-v1/components.800x.png

Architecture of the credential service (current version)

Phases of the credential service (current version)

  1. The target service client executes part of the security protocol, namely all the steps that do not require the actual credential data. (Sometimes this phase is non-existant, depending on the security protocol.)
  2. The target service client provides the credential service the partial (and other required) data.
  3. The credential service executes the remainder of the security protocol, by combining the partial data with the actual credential data. (This phase might involve actual calls to the target service, depending on the security protocol.)
  4. The credential service replies to the target service client with the rest of the security protocol data. (This phase might actually require the credential service to provide the actual credential data, thus a no-operation, depending on the security protocol.)
  5. The target service client makes the actual request, sending besides the request also the required security protocol data.

As seen from the previous phases, the actual operations involved, and the level of security, depends solely on the security protocol at hand.

Future architecture

Although functionality wise the current architecture is good enough to fulfill the practical needs of any target service client, the following figure presents an evolution which also fulfills the non-functional requirement of separating the credential management from its storage, which is mandated by the need to limit the amount of damage caused by a possible successful attack on any of the credential service components.

However in practical terms, the evolution towards this future architecture does not impact in any way existing credential service clients, as the |API| between the client and the current credential service will remain the same as the one between the client and the credential manager, the credential store being hidden.

http://data.volution.ro/specs/public/blueprints/uml/credential-service-v2/components.800x.png

Architecture of the credential service (future version)

Phases of the credential service (future version)

Just like in the current version, the client implements part of the security protocol, delegating to the credential service only the actual credential usage. Therefore we jump over the common phases.

  1. The target service client provides the credential manager the partial (and other required) data.
  2. The credential manager determines the required credentials (based on the partial inputs).
  3. The credential manager requests from the credential store the encrypted credentials.
  4. The credential store retrieves (from an embedded database or another service) the encrypted credentials.
  5. The credential manager receives from the credential store the encrypted credentials.
  6. The credential manager decrypts the credentials.
  7. The credential manager executes the remained of the security protocol like in the current version.
  8. The credential manager replies to the target service client with the security protocol data like in the current version.
  9. The credential manager disposes (possibly after some delay) of the decrypted credentials, and possibly even of the encrypted variant.

Architectural concerns

As seen from the previous section, there are a multitude of non interoperable procedures to authenticate calls, each depending on the target |CSP|, and for some there are even multiple variants (like in the case of |AWS|); then for each client that needs to make such calls, a different library might be used (especially if each client is written in a different programming language). Moreover the involved shared secrets have to be conveyed from the deployment, through the client code, to the used library. Therefore the potential of credential leak is quite high, and the purpose of the credential service is to minimize such issues.

As such the credential service is built in such a way that the actual shared secrets remain confined inside the credential service, and potential clients delegate only the authentication operations to the service. (For an example see listing for the implementation of the |AWS| authentication scheme.)

It must be noted that the credential service does not act as a proxy for the call, but instead it should be perceived as an internal procedure that executes part of the authentication scheme (although remotely). Unfortunately this also implies that one has to change the code of the libraries provided by the |CSP| to extract the authentication execution and delegate it to the credential service.

Security concerns

Although the credential service solves the issue of leaking the actual credentials, it opens up a second problem, that of authenticating and authorizing the clients that need to have their requests authenticated.

In order to solve this new issue, the clients should use only |HTTPS| for securing the communication channel, and for authentication and authorization there are two broad options: using the |SPECS| security tokens service; or using |X.509| client certificates (as part of the |HTTPS| / |TLS| channel).

The current implementation does not use any kind of authentication and authorization, because the focus of the prototype is on the credential management, the other issues being a crosscutting concern that can be solved independently of the solution, and it is also required for other |SPECS| services. (Moreover the future evolutions will have an even tighter security model as mandated by one of the requirements of the credential service.)

Implementation concerns

The current prototype is implemented in a |JavaScript|-based asynchronous environment, namely |NodeJS|, which by providing a dynamically typed and interpreted environment, allows us to register and unregister modules at will, without requiring compilation or restarting the whole service.

The full source code of the service can be found on |GitHub|, under the Apache 2.0 license, at the following |URL|: https://github.com/ieat/mosaic-credential-service.

In the listing below one can analyze the implementation of the |AWS| module which currently only provides the |AWS| authentication scheme described in |xiwe|.

|AWS| module implementation

function _queryAuthenticate4 (_credential, _inputs, _onSuccess, _onError) {

    transcript.traceDebuggingObject ("signing query...", _inputs);

    var _accessKey = _credential["access-key"];
    var _secretKey = _credential["secret-key"];

    var _timestamp = _inputs.timestamp;
    var _region = _inputs.region;
    var _service = _inputs.service;
    var _request = _inputs.request;

    var _termination = "aws4_request";
    var _date = new Date (_timestamp);

    var _date1 = printf ("%04d%02d%02dT%02d%02d%02dZ",
            _date.getUTCFullYear (), _date.getUTCMonth () + 1, _date.getUTCDate (),
            _date.getUTCHours (), _date.getUTCMinutes (), _date.getUTCSeconds ());
    var _date2 = printf ("%04d%02d%02d",
            _date.getUTCFullYear (), _date.getUTCMonth () + 1, _date.getUTCDate ());

    var _credentialScope = [_date2, _region, _service, _termination].join ("/");
    var _credential = [_accessKey, _credentialScope].join ("/");

    var _target = [
            "AWS4-HMAC-SHA256",
            _date1,
            _credentialScope,
            _request,
    ].join ("\n");

    var _signedDate = crypto.hmac ("sha256", "AWS4" + _secretKey, _date2, "binary", "binary");
    var _signedRegion = crypto.hmac ("sha256", _signedDate, _region, "binary", "binary");
    var _signedService = crypto.hmac ("sha256", _signedRegion, _service, "binary", "binary");
    var _signatureKey = crypto.hmac ("sha256", _signedService, _termination, "binary", "binary");

    var _signature = crypto.hmac ("sha256", _signatureKey, _target, "binary", "hex");

    var _outcome = {
        credential : _credential,
        signature : _signature,
    };

    _onSuccess (_outcome);
}

module.operations.register ({
        identifier : "query-authenticate-v4",
        execute : _queryAuthenticate4,
});

Regarding the handling of the actual credentials they are currently stored in memory (thus they do not leak into the host storage layer, except perhaps swap if not encrypted); the only way to extract them is if a module directly exports them (not as part of a cryptographic procedure), or in case there is a security issue (or bug) that affects the environment itself or one of the libraries used (in addition to the actual implementation). However this issue will be mitigated in the future version which decouples the credential storage from its usage, as is mandated by one of the credential service requirements.

Docutils System Messages

System Message: ERROR/3 (<string>, line 13); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 13); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 13); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 15); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 15); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 15); backlink

Undefined substitution referenced: "Eucalyptus".

System Message: ERROR/3 (<string>, line 15); backlink

Undefined substitution referenced: "Amazon".

System Message: ERROR/3 (<string>, line 17); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "EU".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "EU".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "SaaS".

System Message: ERROR/3 (<string>, line 19); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 25); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "EU".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "HTTP".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "REST".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "SOAP".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "EU".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 27); backlink

Undefined substitution referenced: "HTTP".

System Message: ERROR/3 (<string>, line 29); backlink

Undefined substitution referenced: "HMAC".

System Message: ERROR/3 (<string>, line 29); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 29); backlink

Undefined substitution referenced: "Eucalyptus".

System Message: ERROR/3 (<string>, line 29); backlink

Undefined substitution referenced: "OpenStack".

System Message: ERROR/3 (<string>, line 29); backlink

Undefined substitution referenced: "OpenNebula".

System Message: ERROR/3 (<string>, line 29); backlink

Undefined substitution referenced: "xiwe".

System Message: ERROR/3 (<string>, line 31); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 31); backlink

Undefined substitution referenced: "GoGrid".

System Message: ERROR/3 (<string>, line 31); backlink

Undefined substitution referenced: "zowu".

System Message: ERROR/3 (<string>, line 31); backlink

Undefined substitution referenced: "OpenNebula".

System Message: ERROR/3 (<string>, line 31); backlink

Undefined substitution referenced: "RackSpace".

System Message: ERROR/3 (<string>, line 31); backlink

Undefined substitution referenced: "yete".

System Message: ERROR/3 (<string>, line 40); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 40); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 40); backlink

Undefined substitution referenced: "JSON".

System Message: ERROR/3 (<string>, line 40); backlink

Undefined substitution referenced: "Base64".

System Message: ERROR/3 (<string>, line 43); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 43); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 46); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 46); backlink

Undefined substitution referenced: "xiwe".

System Message: ERROR/3 (<string>, line 52); backlink

Undefined substitution referenced: "HTTP".

System Message: ERROR/3 (<string>, line 52); backlink

Undefined substitution referenced: "REST".

System Message: ERROR/3 (<string>, line 52); backlink

Undefined substitution referenced: "API".

System Message: ERROR/3 (<string>, line 54); backlink

Undefined substitution referenced: "API".

System Message: ERROR/3 (<string>, line 56); backlink

Undefined substitution referenced: "Plan9".

System Message: ERROR/3 (<string>, line 56); backlink

Undefined substitution referenced: "zoti".

System Message: ERROR/3 (<string>, line 85); backlink

Undefined substitution referenced: "API".

System Message: ERROR/3 (<string>, line 110); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 110); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 112); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 114); backlink

Undefined substitution referenced: "CSP".

System Message: ERROR/3 (<string>, line 122); backlink

Undefined substitution referenced: "HTTPS".

System Message: ERROR/3 (<string>, line 122); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 122); backlink

Undefined substitution referenced: "X.509".

System Message: ERROR/3 (<string>, line 122); backlink

Undefined substitution referenced: "HTTPS".

System Message: ERROR/3 (<string>, line 122); backlink

Undefined substitution referenced: "TLS".

System Message: ERROR/3 (<string>, line 124); backlink

Undefined substitution referenced: "SPECS".

System Message: ERROR/3 (<string>, line 130); backlink

Undefined substitution referenced: "JavaScript".

System Message: ERROR/3 (<string>, line 130); backlink

Undefined substitution referenced: "NodeJS".

System Message: ERROR/3 (<string>, line 132); backlink

Undefined substitution referenced: "GitHub".

System Message: ERROR/3 (<string>, line 132); backlink

Undefined substitution referenced: "URL".

System Message: ERROR/3 (<string>, line 134); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 134); backlink

Undefined substitution referenced: "AWS".

System Message: ERROR/3 (<string>, line 134); backlink

Undefined substitution referenced: "xiwe".

System Message: ERROR/3 (<string>, line 128); backlink

Undefined substitution referenced: "AWS".