Machine-to-Machine Authentication

Outlining the machine-to-machine authentication using the client credentials grant type implementation.

The BridgeFT Wealthtech API now supports machine-to-machine authentication via the client_credentials grant type. The client_credentials grant is now the preferred method for authenticating against the API. It allows consumers to authenticate as an application, rather than authenticating on behalf of a user via the password grant or using and API key.

Wealthtech API Applications

Registering an Application

To use the client_credentials grant type, your organization and application must be registered on our developer platform. Please reach out to [email protected] to register. This process will be automated in the coming months.

Application Credentials

After your organization has been registered, details for the application will be provided. A JSON representation of an application can be found below:

{
  "name": "Application Name",
  "description": "Description of your application."
  "environment": "sandbox",
  "client_id": <YOUR_CLIENT_ID>,
  "client_secret": <YOUR_CLIENT_SECRET>
}

Environment

The environment field denotes the type of application. As of now, options are production and sandbox . Sandbox applications will only receive faked data generated by BridgeFT for development and testing purposes. Accounts and portfolio data for sandbox applications are not "live". Production applications consume "live" data directly from BridgeFT's connected data feeds.

Client Credentials

Applications are issued client credentials that are exchanged for access tokens.

The client_id is an application's public identifier that is safe to be logged, used in communicating with support, and is used by BridgeFT to log and track API usage.

The client_secret is a confidential key that is strictly used to exchange for access tokens along with the client_id. This secret should never be displayed or shared publicly.

Authenticating an Application

Retrieving an Access Token

The applications client_id and client_secret pair is used to authenticate and retrieve and access token. BridgeFT requires that client credentials be base64 URL-encoded and sent via the Basic auth pattern, per RFC 6749.

The unencoded string follows combines the client_id and client_secret with a single colon (;) separating the two like so: <CLIENT_ID>:<CLIENT_SECRET.

For example, if the client_id is BridgeFT and the client_secret is WealthTech, the authorization header will appear as:

Authorization: Basic QnJpZGdlRlQ6V2VhbHRoVGVjaA==

Along with the authorization header, all that is required to pass to the /v2/oauth2/token endpoint is a x-www-form-urlencoded header with the grant type.

An example authentication request looks like this:

curl --location --request POST 'https://api.bridgeft.com/v2/oauth2/token' \
--header 'Authorization: Basic QnJpZGdlRlQ6V2VhbHRoVGVjaA==' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials'

Authentication Response

A successful client_credential response from the token endpoint looks like this:

{
  "TokenType": "Bearer",
  "ExpiresIn": 3600,
  "AccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
ParameterDescription
AccessTokenToken the application uses to access secured API resources. The access token is a JSON web token (JWT).
ExpiresInThe amound of time, in seconds, that the access token is valid for.
TokenTypeIndicates how the token should be used in the Authorization Header. This will always be Bearer.

Access Token Expiration and Refresh

Access tokens will expire one hour after they are issued. API requests made with expired access tokens, will recieve an error with 401 Unauthorized.

Access Token Contents

The access token can be inspected for additional details using the tools and libraries made available by jwt.io.

An example of decoded access token looks like this:

{
  "app": {
    "application_id": 1,
    "application_name": "BridgeFT Sample Client",
    "client_id": "BridgeFT",
    "firm_ids": null,
    "organization_id": 1
  },
  "aud": [
    "bridgeft/api"
  ],
  "exp": 1669849184,
  "iat": 1669845584,
  "iss": "api.bridgeft.com/v2/oauth2/token",
  "sub": "BridgeFT"
}

JWT Standard Contents

ParameterDescription
expThe time the access token expires.
iatThe time the access token was issued.
issThe url the access token was issued from. This will always be "api.bridgeft.com/v2/oauth2/token"
subThe receiver of the access token. This will always be the client_id of the authenticated application.

Custom Claims

BridgeFT applies custom claims along with the JWT standard claims above. These can be found under the app section of the decoded access token.

ParameterDescription
application_nameThe name of the application.
client_idThe client_id of the application. This is logged with each API request.
firm_idsThe list of firm_ids scoped to the token. When null, the application will receive data for all of its accessible firms.

Additional Features

Scoping Requests

In addition to the standard client_credentials grant, we have added the ability to optionally scope your access token to limit the data that you see when you are making requests to secured resources.

When authenticating the application, a firm_ids parameter can be passed as a x-www-url-encoded header with a comma separated list of firm_ids. If provided, the firm_ids parameter will scope the access token, so that any downstream requests will only show data scoped to the specific firm id(s) provided. When firm_ids is not provided, requests will show data for any firm/advisor the application is connected to by default.

An example of a scoped access token request looks like this:

curl --location --request POST 'https://api.bridgeft.com/v2/oauth2/token' \
--header 'Authorization: Basic <YOUR_ENCODED_CREDENTIALS>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'firm_ids=39, 792'

The decoded access token returned from the request looks like this:

{
  "app": {
    "application_id": 1,
    "application_name": "BridgeFT Sample Client",
    "client_id": "53227c24",
    "firm_ids": [
      39,
      792
    ],
    "organization_id": 1
  },
  "aud": [
    "bridgeft/api"
  ],
  "exp": 1669998845,
  "iat": 1669995245,
  "iss": "api.bridgeft.com/v2/oauth2/token",
  "sub": "53227c24"
}

The firm_ids field is now populated with the firm_ids provided. Downstream requests will only return data belonging to those firms.