The GlobaliD Vault & PII Sharing

Verifications can contain personally identifiable information, or PII. The PII associated with a verification is always private. In some cases, partners may have a legal obligation to have access to some underlying PII data, or would request to share some way to connect with a user (ie email).

Note that verifications are public: when a user completes a set of required verifications, a partner application can view the list of verifications associated with an identity, along with additional details like the identity of the verifier, the type of verification, when it was verified, etc. For example:

       Date/Time              Verification                  Verifier    Public Data
       -------------------    --------------------------    --------    -----------
       2019-01-19 11:26:52    Has valid phone number        Twilio      USA
       2019-01-19 12_03:40    Has valid email address       Mandrill
       2019-01-19 12:08:28    Has valid Facebook account    Facebook

While verifications themselves may be public, the PII is not -- despite having the above set of public verifications associated with an identity, the email address, phone number and facebook account ID that was used to generate those verifications is not revealed. GlobaliD is fervently dedicated to protecting user PII and further believes that in 90+% of cases, partner applications do not need the underlying PII information, just the verifications associated with a user.

As you have questions surface throughout this section, feel free to engage with the GlobaliD team through our Discord Server or by emailing verifications@global.id.

Accessing PII in the GlobaliD Vault



The OpenID standard

When partners do need access to PII, GlobaliD utilizes the OpenID standard to share this information. This standard is implemented ontop of OAuth to provide identity authentication. It does this through the use of an identity token. You can read more about OpenID here and here. In the identity token, GlobaliD returns encrypted data tokens that a user has given a partner consent to access. These data tokens are then used to access encrypted data within the GlobaliD Vault, which is a multi-layered encrypted store of user PII information.

Prep for Vault Access

In order to set up vault access, partners must make sure to first do 3 things. Performing these steps will prevent common errors partners face in the process.

  • Generate key pairing and upload your public key to GlobaliD. To do, visit click the Upload button on the Private Key column in the App Details section of your developer application.
    Vault flow

  • When setting up Required Verification sets, toggle on which verifications you require PII.

  • When creating Connect URLs, making sure you include a required verification set, the scope of openid, a grant_type of code, and a randomly generated nonce appended to the URL that is longer than 8 characters.

How it works, in a nutshell


For a partner to access a user's PII, they must:

  1. Retrieve a user's access_token and id_token; the id_token provides partners information about the authenticated user, including a list of values called claims that a user has explicitly shared with them, which can be requested from the vault. These claims are encrypted data tokens that are used to grab data from the GlobaliD Vault. Make sure to decrypt the claims before using them in the future.

  2. Partners must request an access token for their application from the v1/auth/token endpoint.

  3. Call the vault API to access encrypted data associated with the claims listed from a user's id_token from the first step

  4. Decrypt the payload using the corresponding private key registered to the encrypted client public key.

  5. To access files stored in the vault, namely photos, make a separate call to an /attachment endpoint.



Engaging with the Vault



Vault flow

1. Get an id_token for the user

The vault service requires that you use a user's access token and their id_token. This is returned with access token from the /auth/token as a JSON Web Token (JWT) which shares claims, or data, a user has explicitly given consent for a partner to consent. These claims are the "encrypted data tokens" mentioned above. As standard with JWTs, it must be decoded to access its contents and the associated claims. This resource allows you to view JWTs and shares a few packages to decrypt JWTs. Once deccrypted, the JWT payload looks like so:

// The id_token

{
    "iss":"http://server.example.com",
    "sub":"248289761001",
    "aud":"s6BhdRkqt3",
    "nonce":"n-0S6_WzA2Mj",
    "exp": 1311281970,
    "iat": 1311280970,

    // the claims are below:
    "https://claims.idp.globalid.net/claims/${acrc_id}":
        {"${consent_id}": ["encrypted_data_tokens_with_partners_public_key"]}
}



2. Get an application access_token

Next, partner applications must get an access_token for their application using the /auth/token endpoint. Make sure the grant_type is set to client_credentials and use your associated client_id and client_secret keys. This access token should be cached to minimize the amount of times it is called.

return await axios.request({
    method: 'post',
    url: '/auth/token',
    baseURL: 'https://globalid.net/v1',
    headers: {'Content-Type': 'application/json'},
    data: {
        client_id: <CLIENT_ID>,
        client_secret: <CLIENT_SECRET>,
        grant_type: 'client_credentials',
    }
});



3. Retrieve encrypted PII data

After fetching an access token for the application, you will call the Vault API to get the associated PII data for the given user. Use the GET /v1/vault/get-encrypted-data endpoint using the unencrypted claim_ids from the user's id_token as well as the application's access_token. Note that the claim_ids from the identity token must be unencrypted using your private key.

Below is an example call to the get-encrypted-data endpoint using node:

return axios.request(`https://api.globalid.net/v1/vault/get-encrypted-data`, {
    method: 'post',
    data: {
        private_data_tokens: claims_tokens, // array of unencrypted tokens from the user id_token
    },
    headers: {
        'Authorization': `Bearer ${access_token}`,
    },
    json: true,
})



The response from the /v1/vault/get-encrypted-data will be an array of objects that look like the below; each one of these is data associated with a claim:

...
  {
    encrypted_data_password: "encrypted password to decrypt encrypted_data", 
    encrypted_data: "encrypted PII, should be decrypted with password from encrypted_data_password",
    encrypted_root_password: "encrypted password", 
  },
  {
    encrypted_data_password: "encrypted password to decrypt encrypted_data", 
    encrypted_data: "encrypted PII, should be decrypted with password from encrypted_data_password",
    encrypted_root_password: "encrypted password", 
    private_file_token: "a token to grab files, if any are present",
    private_file_token_expiry: "a timestamp for when this token expires"
  },
...



4. Decrypt the Vault response

Partners must decrypt the encrypted_data payload by first decrypting the associated encrypted_data_password using the associated private key for their application, and using that decrypted value to decrypt the PII data.

// decrypt passwrod from /get-encrypted-data 
const pass = RSADecrypt(data[0].encrypted_data_password, privateKey); 

// decrypt data using decrypted password 
const tokenData = AESDecrypt(data[0].encrypted_data, pass); 

// output tokenData 
console.log(JSON.parse(tokenData)) 

""" 
{ 
  value: "John", 
  type: "legal_first_name", 
  gid_uuid:"6c42df5b-8081-4912-8f1a-61d990e3f3ad", 
  attestation_request_uuid:` `"f034a1d9-6fb0-4bcb-8ba7-7cbbc91989 
  has_attachment: true 
} 
"""



Upon completing this flow, partners will have access to the PII data users have consented to share with them.

Accessing Files from the Vault

A few verifications also have files associated with them, such as photos from ID documents. To access the files store, partner applications must make a call to a different endpoint using the private_file_token returned from the get-encrypted-data object.

For every value returned from the /vault/get-encrypted-data endpoint, the unencrypted data value has a key private_file_token. If this value is set, grab this underlying "attachment" by calling the /vault/attachment/${private_file_token}/client endpoint. Upon receiving the response, partners should decrypt this value using the password returned from the vault/get-encrypted-data endpoint.

axios.request(devurl, {
    method: 'get',
    headers: {
        Authorization: `Bearer ${access_token}`,
    },
}).pipe(crypto.default.aes.decryptStream(password))
    .on('data', (chunk) => {
        chunks.push(chunk)
    })
    .on('error', reject)
    .on('finish', () => {
        resolve(`data:${piiValue.mime_type};base64,${Buffer.concat(chunks).toString('base64')}`)
    })
})



Common Errors

There are a few common errors that are made when accessing vault information:

  1. Make sure you are using the correct key pair. Double-check your private and public key you are using for a given client_id match.

  2. Make sure that all nonces you uses in your Connect URLs are longer than 8 characters. If not you will get an INVALID_CLIENT_CREDENTIALS error

  3. Make sure to always use secure URLs when calling the GlobaliD API. That is, all API endpoints are performed using https://. If you don't, you will receive timeout errors!

  4. Double check you have enabled PII sharing for your developer application. That is, you have uploaded your public key to your developer application, and have selected a few verifications in your Required Verifications Set that require PII sharing.

  5. Double check you have made calls using the correct scopes and grant types. Your connect URLs should have scope openid, your user tokens should have grant type authorization_code or code, and your client account token should use grant client_credentials.

A Note on Security

GlobaliD's vault has been built using the latest cryptographic techniques and with the user at the center of the experience. A user's PII data is encrypted using: - A generated password (if using Web connect) or private key (if using App Connect) only they have access to and - The partner's public key.
These multiple layers of encryption not only make certain that hackers cannot access the undelrying PII data while it is in the vault, but also ways of protecting user data upon a breach of a partner's private key or a breach of a user's device or password. GlobaliD simply re-encrypts the associated data with this breach with a new set of values and minimizes exposure to underlying PII data.



For more information or questions on the Vault and accessing PII data, please reach out to us in our discord channel or email devSupport@global.id.