Views:

In this tutorial we’ll see how to authorise calls to the LUSID API, both directly to the REST API and indirectly using the SDKs.

Let’s imagine we want to create an application or service that extracts all the instruments in LUSID’s instrument master. To do this, we need to authorise a call to the LUSID ListInstruments API.

Note: To complete this tutorial, you must yourself have suitable permissions. This can most easily be achieved by assigning your LUSID user the built-in lusid-administrator role. This should already be the case if you are the domain owner.

Step 1: Setting up a service user account with appropriate permissions

There are two types of user in LUSID, personal and service.

Whilst it is perfectly possible to use the credentials of a personal user to authorise calls to the LUSID API, we recommend using those of a service user instead, especially if you are creating an automated service. This is because the account is not tied to the email address of a person who might leave your organisation.

We recommend setting up one service user account per distinct application or service so that it only has permissions to perform the operations for which it is designed, and no more. In this tutorial we're going to use the default roles and policies provided with LUSID to grant access to the example data also provided with LUSID, but you can create your own policies if you wish.

  1. Sign in to the LUSID web app using the credentials of a LUSID administrator.
  2. From the left-hand menu, select Identity and access > Users:
  3. On the Users dashboard, click the Create user button:
     
  4. Specify an Account type of Service, enter your Email address to become the service owner, specify a Login user name (this must look like an email address but no email will be sent to it) and click the Add roles button to assign the default lusid-evaluator role provided with LUSID:
  5. Click the Save button to send yourself an email to complete the sign up process.
  6. Follow the instructions in the email to verify the account and specify a complex password.

Step 2: Generating a client ID and a client secret

We now have a username and password for a verified LUSID service user.

In order to obtain an API access token, we also need a client ID and a client secret. To generate these:

  1. From the left-hand menu, select Identity and access > Applications.
  2. On the Applications dashboard, click the Create application button:
  3. Specify a Client Id (no spaces) and a Display name, and click the Save button. LUSID automatically generates a client secret.
  4. On the Applications dashboard, click the  View icon for the row to reveal the client secret and Okta's dedicated token URL for your LUSID domain:

Step 3: Obtaining an API access token

We now have: 

  • A username and password for a verified LUSID service user.
  • A client ID and a client secret.
  • A dedicated Okta token URL.

Note: This step assumes you have installed curl (similar tools are available).

Every call made to the LUSID API must be authorised by an API access token. To obtain one:

  1. Make a POST request to your dedicated Okta token URL, passing in the username, password, client ID and client secret, suitably encoded. For example:
    curl -X POST <your-okta-token-url>
       -H "Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1"
       --data-urlencode grant_type="password"
       --data-urlencode username="<your-username>"
       --data-urlencode password="<your-password>"
       --data-urlencode scope="openid client groups"
       --data-urlencode client_id="<your-client-id>"
       --data-urlencode client_secret="<your-client-secret>"
    The response from Okta contains 2 tokens (actual data shortened for brevity):
    {
       "token_type": "Bearer",
       "expires_in": 3600,
       "access_token": "eyJraWQiOiJvZDFzeFk4WTlPalMyZ2dZT3VidVBYT2dRX0dURkcwZ1...wmlxPjh49DYeEuh_w4vt2Q",
       "scope": client groups openid",
       "id_token": "eyJraWQiOiJvZDFzeFk4WTlPalMyZ2dZT3VidVBYT2dzeFk4WTlPalMKi8...Mh66mG9j7zfyQxsp7UPC4J"
    }
  2. Extract the first token, keyed access_token and ending wmlxPjh49DYeEuh_w4vt2Q in this example.

Step 4: Calling the REST API

We must supply the API access token as a Bearer token in the Authorization HTTP header of a call to the GET /api/instruments API endpoint.

In this example, we'll limit the response to the first instrument in the instrument master:

curl -X GET https://<your-domain>.lusid.com/api/api/instruments?limit=1 
   -H "Authorization: Bearer eyJraWQiOiJvZDFzeFk4WTlPalMyZ2dZT3VidVBYT2dRX0dURkcwZ1...wmlxPjh49DYeEuh_w4vt2Q" | python3 -m json.tool

Note here the response is piped through the Python json.tool module to make it easier to read:

{
    "values": [
        {
            "href": "https://<your-domain>.lusid.com/api/api/instruments/LusidInstrumentId/CCY_AED",
            "lusidInstrumentId": "CCY_AED",
            "version": {
                "effectiveFrom": "0001-01-01T00:00:00.0000000+00:00",
                "asAtDate": "2021-07-07T07:34:36.5367730+00:00"
            },
            "name": "AED",
            "identifiers": {
                "Currency": "AED",
                "LusidInstrumentId": "CCY_AED"
            },
            "properties": [],
            "state": "Active"
        }
    ],
    ...
}

Step 5: Using the Python SDK

Now we'll perform the same operation using the Python SDK, which you can install by running pip install lusid-sdk in a suitable environment.

Note: SDKs for LUSID in other languages are available.

The SDKs have helper classes that automate the process of obtaining an API access token and refreshing it upon expiry, so we don't need to supply one directly. Instead, we store the username, password, client ID, client secret and dedicated Okta token URL either as environment variables or in a secrets file, and make it available to the SDK.

In this example we'll use a secrets file (instructions for environment variables are here):

  1. Go back to the LUSID web app and select Identity and access > Applications.
  2. On the Applications dashboard, click the  View icon for the application we created in Step 2.
  3. In the Export credentials area, make sure Secrets file is selected and copy the data to the clipboard:
  4. Paste the data into an appropriate local file, for example secrets.json.
  5. In the file, replace <password> with your actual LUSID password.

Assuming secrets.json is in the same directory, run the following script to automatically generate an API access token when the InstrumentsApi.list_instruments method is called:

import lusid 
# Obtain an API access token and automatically refresh it: 
secrets_file_path = "secrets.json" 
api_factory = lusid.utilities.ApiClientFactory( 
   api_secrets_filename=secrets_file_path 
) 
# Build the instruments API: 
instruments_api = api_factory.build(lusid.api.InstrumentsApi) 
# Retrieve the first instrument in the master: 
response = instruments_api.list_instruments(limit=1)

The response is formatted slightly differently but contains the same information:

[{'href': 'https://<your-domain>.lusid.com/api/api/instruments/LusidInstrumentId/CCY_AED',
 'identifiers': {'Currency': 'AED', 'LusidInstrumentId': 'CCY_AED'},
 'instrument_definition': None,
 'links': None,
 'lookthrough_portfolio': None,
 'lusid_instrument_id': 'CCY_AED',
 'name': 'AED',
 'properties': [],
 'state': 'Active',
 'version': {'as_at_date': datetime.datetime(2021, 7, 6, 10, 49, 51, 849145, tzinfo=tzutc()),
             'effective_from': datetime.datetime(1, 1, 1, 0, 0, tzinfo=tzutc())}}]