Designs of Using a Dedicated Process to Protect the Client Secret Assigned to GPII Local Installation

From wiki.gpii
Jump to: navigation, search

Introduction

Recorded on this wiki page, the possible approaches for protecting the communication between the native GPII application installed on users devices and GPII Cloud are explored. At the meeting on Feb 16, 2017, the most promising approach that was selected is to use a dedicated process or service running on a different account for storing the GPII client secret.

This wiki page contains designs, including the server side design of http endpoints and the database structure, as well as UX sketches, of how this approach can be implemented.

Request and Manage Client Credentials

UI Sketches

Refer to another wiki page Workflows to Request and Manage Client Credentials for UI sketches that show workflows of several options that a native GPII application can request a client credential from GPII Cloud, as well as the workflow to manage client credentials at a central GPII site.

HTTP Endpoints

The design in this section is pending, and waiting for the finalization of the workflow to continue.

Request Client Credential for Native GPII Application Endpoint

HTTP method GET
Endpoint /request_client_credential?grant_type="password"&username={username}&password={password}&client_name={client_name}&computer_type={computer_type}scope="requested_by_native_app"
HTTP headers Accept: application/json
Payload -
Normal response Status: 200 OK

{

 "client_name": {String},   // the same client name sent in via request parameter
 "client_id": {String},
 "client_secret": {String}

}

Error response 400 The client name already exists

{

 "is_error": true,
 "message": "string"

}

Note: Rate limiting should be implemented for this endpoint to prevent brute force attacks.

Revoke Client Credential

HTTP method GET
Endpoint /revoke_client_credential?client_credential_id={client_credential_id}
HTTP headers -
Payload -
Normal response Status: 200 OK
Error response Status: 404 client credential is not found

{

 "is_error": true,
 "message": "string"

}

Request Access Token via GPII Access Requester Module

Introduction

In this design, a native GPII application contains 2 modules:

  1. GPII local flow manager: runs in the context of the login user
  2. GPII access requester: runs as a privileged process using a GPII specific user account

The access requester is responsible for:

  1. Store OAuth2 client id/secret;
  2. Receive GPII token from the local flow manager and in exchange with an access token;
  3. Communicate with GPII Cloud to request access tokens.

Workflow

GPII access requester.png

The flow illustrated in the figure above includes the following steps:

  1. The GPII local flow manager passes the GPII token to the GPII access requester;
  2. The access requester sends client id, client secret, gpii token to GPII Cloud via https;
  3. GPII Cloud validates all information. If passes, returns an access token;
  4. The access requester passes the access token back to the GPII local flow manager.

HTTP Endpoint

Access Token Endpoint

This endpoint is used at step 2, 3.

HTTP method POST
Endpoint /access_token
HTTP headers Accept: application/json
Payload grant_type="password"&username={gpii_token}&client_id={client_id}&client_secret={client_secret}
Normal response Status: 200 OK

{

 "access_token": "string",
 "token_type": "Bearer",
 "expires_in": integer  // The number of seconds left before the access token expires.

}

Error response Status: 400 Bad Request (if grant_type !== "password") / 401 Unauthorized (if the client id/secret don't match) / 404 User Not Found

{

 "is_error": true,
 "message": "string"

}

Note: Rate limiting should be implemented for this endpoint to prevent brute force attacks.

CouchDB Document Structure

The currently implemented CouchDB document structure is documented at here.

Resource Owner Password Credentials Access Token (New)

Option Type Description Default
id String The document id. Can be a UUID or any unique string. This value is saved into _id field in CouchDB/PouchDB. None
type String The document type to identify this record is an access token assigned to a native GPII application. The value must be set to "resourceOwnerToken".
clientId String The client id. Should match an id value of a "client" type document. None
gpiiToken String The GPII token that this access token is associated with. None
accessToken String The access token used by the client identified in this document to access settings of the GPII token in this document. None
expiresIn Integer The number of seconds left before the access token becomes invalid. 3600
revoked Boolean Whether this access token has been revoked. The access token should be revoked once the associated GPII token is keyed out. false
timestampCreated Date The timestamp when the access token is created. now()
timestampRevoked Date The timestamp when the access token is revoked. None

Client (Modified)

Option Type Description Default
id String The document id. Can be a UUID or any unique string. This value is saved into _id field in CouchDB/PouchDB. None
type String The document type for storing client information. The value must be set to "client".
name String The client name. None
oauth2ClientId String The unique identifier issued to a registered OAuth2 client by the authorization server. None
oauth2ClientSecret String Confidential shared secret between the client and the authorization server, used to verify the identity of the client. None
oauth2ClientType String The client type. The value must be one of these:
  • nativeGpiiApp: native GPII applications.
  • webApp: web applications.
  • thirdPartyApp: third party applications.
  • clientCredentials: applications that use OAuth2 client credential grant type, such as first discovery tool.
userId String The id of the user who created this client. None
origins String A list of javascript origins separated by comma. This is only required for clientType === "webApp". None
redirectUris String A list of redirect URIs separated by comma. This is only required for clientType === "webApp". None
revoked Boolean Whether this client has been revoked.. false
timestampCreated Date The timestamp when the client is created. now()
timestampRevoked Date The timestamp when the client is revoked. None

Note: The value of the field "oauth2ClientSecret" should be stored in the database as encrypted hashes.

References

Conclusion

The discussion for this version of the design took place on May 8, 2017 at Toronto face to face meeting. The details can be found in this pad. Conclusions in short:

  1. Simplify the process for the installing person to request a client credential: instead of having to go to GPII account management system to request a client credential prior to the installation and manually copy and input it into the GPII application, the GPII installation does this automatically provided that the installing person provides their GPII account login/password at a installation step;
  2. The registration of the client credential to ensure it's only used on one machine is unnecessary;
  3. Use the design of having a "GPII Access Requester Module" on the user's device;
  4. Instead of using admin/system account to run "GPII Access Requester Module", consider to use a low-privileged user account.