Trimble Identity (TID) Token-Exchange: Controller-to-Sensor Delegation
Overview
This is an extension to TID’s Token-Exchange mechanism that enables secure data aggregation and transmission from sensors without internet access. A nearby controller acts on behalf of the sensor device, with both devices pre-registered in TID and possessing unique certificates. This allows secure delegation of the sensor’s authority to transmit data to Trimble APIs.
When to Use This Flow
| Use Case | Description |
|---|---|
| Field-to-Cloud (F2C) | Sensor devices without direct internet access delegate authority to a controller |
| Secure device delegation | Both sensor and controller are registered in TID/IAM with certificates |
| BLE-based communication | Secure, local communication using Bluetooth Low Energy (BLE) |
How It Works
- Sensor generates a self-issued Proof-of-Possession (PoP) token (JWT) and securely transmits it to the controller over BLE.
- Controller receives the PoP token and, using its own access token, invokes the TID
/oauth/tokenmTLS endpoint. - TID validates the input tokens minting an “on-behalf-of” access token with
act.sub(actor subject) claim based within theactor_token.
Note: If a valid
actor_tokenis not supplied, the default behavior setting the calling application’s identity as theact.subshall be maintained.

Token Request
-
API CALL:
- POST
{``mTLS endpoint``}/oauth/token
- POST
-
HEADER:
- Accept: application/json
-
REQUEST BODY:
- grant_type:
urn:ietf:params:oauth:grant-type:token-exchange - subject_token_type:
urn:ietf:params:oauth:token-type:jwt - actor_token_type:
urn:ietf:params:oauth:token-type:jwt - actor_token: Controller’s access token.
- subject_token: Sensor’s self-issued PoP token.
- client_id: Application ID registered in TID/IAM.
- scope: (optional) space-separated list of scopes for the requested token.
- grant_type:
mTLS token endpoints:
- Staging:
https://mtls.stage.id.trimblecloud.com - Production:
https://mtls.id.trimble.com
Example Request
POST: /oauth/tokenHost: mtls.stage.id.trimblecloud.comAccept: application/jsonContent-Type: application/x-www-form-urlencodedCache-Control: no-cache
scope=openid Pt-Aus-Test-Region TestApplication_integ_1&grant_type=urn:ietf:params:oauth:grant-type:token-exchange&client_id=d13bb025-80df-4f3b-b32a-f739296bf7a1&subject_token_type=urn:ietf:params:oauth:token-type:jwt&actor_token_type=urn:ietf:params:oauth:token-type:jwt&actor_token=eyJhbGciOiJSUzI1NiIsImtpZC...```Token Response
If the token request succeeds, the server responds with a 200 response code.
A JSON response that is received includes the following values:
- access_token
- expires_in
Example Response
{"token_type" : "bearer","expires_in" : 3600,"access_token" : "eyJhbG...<JWT truncated for brevity>"}- To decode and verify the TID JWT Token, refer to Decode JWT
The access token received with this can be used for further API calls by the Controller.
Key Actors
1. Sensor Action
- Sensor generates a self-issued PoP token (JWT).
- Securely transmits the signed PoP token to the controller over BLE.
- The
cnfclaim in the PoP token must contain the SHA-256 hash/fingerprint of the controller’s public key (JWK).
Claims in Sensor’s Self-Issued PoP Token
| Claim | Description |
|---|---|
iss | Issuer (Sensor’s unique TID ID) |
sub | Subject (Sensor’s unique TID ID) |
aud | Audience (Controller’s unique TID ID) |
exp | Expiration time (max 5 min) |
iat | Issued At timestamp |
jti | JWT identifier (unique, prevents replay) |
cnf | Confirmation claim with SHA-256 hash (jkt) of Controller’s public key |
Example cnf claim:
{"cnf": { "jkt": "H7I7rX4p3g-qLh4fK5t0..." }}2. Controller Action
- Controller receives the sensor’s PoP token.
- Calls the TID
/oauth/tokenmTLS endpoint
Security and Best Practices
- The sensor and controller mutually authenticate using Certificate-Based Authentication Protocol (CBAP) over Bluetooth Low Energy (BLE).
- Use BLE with ephemeral ECDH for secure session key establishment.
- Enforce LE Secure and Authentication/Secure Pairing (BT4.2+).
- Use MiTM protection (Passkey Entry, Numeric Comparison, OOB methods).
- Sensor JWT should include:
- New token per session
exp< 5 minutesjti(unique token ID)nonce(64-bit CSPRNG random session value)