LogoLogo
DocsHomeSupportContact
  • Getting Started
    • Introduction
    • Build on DIMO
  • DEVELOPER GUIDE
    • Developer Overview
    • Developer Console
    • Authentication
    • DIMO Developer SDKs
      • Data SDK
      • Login with DIMO SDK
        • React Component
        • Login with DIMO Redirect
        • Core Functionalities
      • TypeScript: Transactions SDK
      • SDK Release Notes
    • Low Code Tools
      • n8n: Getting Started
    • Permissions Contract: SACD
    • DIMO Credits
    • Response Types
    • Rate Limits
    • Developer FAQ
    • Developer Changelogs
    • Troubleshooting Common Issues
  • API References
    • Overview of DIMO API
    • Attestation API
    • Device Definitions API
    • Identity API
      • Schema & Types
      • Scalars
      • Nodes & Objects
        • AftermarketDevice
        • AftermarketDeviceConnection
        • DCN
        • DCNConnection
        • DeveloperLicense
        • DeviceDefinition
        • Earning
        • EarningsConnection
        • Manufacturer
        • Sacd
        • SyntheticDevice
        • Vehicle
        • VehicleConnection
        • VehicleEarnings
        • UserRewards
      • Common Queries
    • Telemetry API
      • Schema & Types
      • Scalars
      • Nodes & Objects
        • Signals
        • SignalsLatest
      • Common Queries
    • Token Exchange API
    • Trips API
    • Valuations API
  • DIMO Hardware
    • Introduction
    • DIMO Hardware Application
    • DIMO Manufacturing License
    • Development & Certification
    • Audits & Assessments
      • Hardware & Security Audit
      • Customer Experience Assessment
      • Integration Testing & Quality Control
      • Final Approval
    • DIMO Device License
      • Device Minting Certificates
    • Essential Documents
      • Hardware & Security Audit Checklist
      • Approved Hardware Auditors
      • DIMO Memorandum of Understanding (MOU)
  • Additional References
    • Developer License
    • DIMO GraphQL Basics
  • Deprecated Resources
    • Guides
      • Developer Journey
      • Quick Start Guide
      • Hello World
      • Code Exchange Flow
    • Data Availability
Powered by GitBook
On this page
  • Getting a JWT
  • Authentication Format
  • How it works
  • Step 1: Generate Challenge
  • Step 2: Sign Challenge
  • Step 3: Submit Challenge

Was this helpful?

  1. DEVELOPER GUIDE

Authentication

Getting authenticated as a developer

PreviousDeveloper ConsoleNextDIMO Developer SDKs

Last updated 4 months ago

Was this helpful?

DIMO Check-in

  1. Make sure you before authentication.

  2. The Developer SDKs have functions related to authentication that can expedite the process. You can likely skip this step if you are using the SDKs.

Getting a JWT

Before you go through authentication with DIMO, there are 3 types of JWT as described below:

JWT Type
What is this?
Expiration
How to get it?

User JWT

A user JWT contains your Developer License as the audience with the logged in user's account in the ethereum_address field. This JWT validates that the user is authenticated with DIMO.

14 days, user will need to re-authenticate again.

Developer JWT

A developer JWT contains your Developer License as both the audience and the ethereum_address. This JWT validates you as the app registered with DIMO.

14 days, developers will re-authenticate again programmatically.

Vehicle JWT

A secondary developer JWT to access vehicle private data. This JWT is specific to a vehicle (identified by token_id) and an array of permissions granted by the user to the developer. This JWT validates that your app has permissions to get vehicle data. This was previously called privilege_token.

10 minutes, developers will trigger another exchange programmatically.

Authentication Format

DIMO uses Bearer Authentication format.

How it works

Authentication for DIMO works in 3 steps:

  1. Generate Challenge: Generates a challenge and a state for a specific address.

  2. Sign Challenge: To sign in to obtain a to the API, the signer signs a cryptographic message, proving that they are the owner of the associated public key. This process is known as signing in with a digital signature.

  3. Submit Challenge: The public key is then used to verify the user's digital signature and grant or deny access to the resources with the permissions set.

DIMO's implementation of the web3 signature mechanism for a backend application can be completed with the 3 steps below:

Step 1: Generate Challenge

POST https://auth.dimo.zone/auth/web3/generate_challenge

Query Parameters

Name
Type
Description

client_id*

String

domain*

String

scope*

String

Space-separated list of scopes, this needs to be openid email

response_type*

String

This needs to be code.

address*

String

A hex-encoded, 0x-prefixed, 20-byte Ethereum address (case insensitive). This is the contract address of your Developer License as you are assuming the role of signer of the license. The value is essentially the same as the client_id.

{
  "state":"jot5csziknrzscg2wcbtgaofu",
  "challenge":"auth.dimo.zone wants you to sign in with your Ethereum account:\n<YOUR_ADDRESS>\n\n<host> is asking you sign in.\n\nURI: https://auth.dimo.zone\nVersion: 1\nChain ID: 1\nNonce: 4P8AfZTqj9QwDM8tKc2vfIqQogxpXK\nIssued At: 2024-01-08T15:31:15Z"
}

Step 2: Sign Challenge

You will need to format the challenge string from Step 1 to hex and prefix it with 0x, combine that with an apiKey obtained from the Developer Console, before signing the Ethereum transaction and obtaining a 65-byte signature.

To sign the challenge, you will need to use a library in your preferred programming language to sign Ethereum transactions and messages with local private keys. We have provided a few language examples as a starter:


const web3 = require('web3');

const msg = "<challenge>"
const apiKey = "<api_key>"
const formattedKey = '0x' + Buffer.from(apiKey, 'utf8');

console.log(web3.eth.accounts.sign(msg, formattedKey));
import siwe
from siwe import SiweMessage

from eth_account import Account
from eth_account.messages import encode_defunct
from eth_utils.curried import to_bytes

msg = "<challenge>"
apiKey = "<api_key>"

# No need to hexify when using siwe-py as the purpose of it is to help with formatting & verifying
# This is the pure Python way: hex_msg = '0x' + msg.encode().hex()

try:
    # Format the message
    message: SiweMessage = SiweMessage(message=msg)

    sn = encode_defunct(to_bytes(text=msg))
    acct = Account.from_key(apiKey)
    # Actual signing of the message
    sm = acct.sign_message(sn)
    print(sm)

except ValueError as e:
    # Invalid message
    print("Authentication attempt rejected - invalid message.")
except siwe.ExpiredMessage:
    print("Authentication attempt rejected - expired message.")
except siwe.DomainMismatch:
    print("Authentication attempt rejected - domain mismatch.")
except siwe.NonceMismatch:
    print("Authentication attempt rejected - nonce mismatch.")
except siwe.MalformedSession as e:
    # e.missing_fields contains the missing information needed for validation
    print("Authentication attempt rejected - malformed session.")
except siwe.InvalidSignature:
    print("Authentication attempt rejected - invalid signature.")
{
  message: 'auth.dimo.zone wants you to sign in with your Ethereum account:\n' +
    '0xf9D26323Ab49179A6d57C26515B01De018553666\n' +
    '\n' +
    'app.dimo.zone is asking you sign in.\n' +
    '\n' +
    'URI: https://auth.dimo.zone\n' +
    'Version: 1\n' +
    'Chain ID: 1\n' +
    'Nonce: EXVgxuxMiNfdWzwIcQU4XZ79zzwX6L\n' +
    'Issued At: 2024-01-22T15:34:47Z',
  messageHash: '0x293013bcae66e507384b791b35bd3701284b613887fc11d3a6debcde394c66db',
  v: '0x1c',
  r: '0xccd996ee0f2d18944034f29e5a9565158202d8d66194adcbe0c13eba96feb18e',
  s: '0x1783254ec656186cd1461693969c10aff0014f4690ee2f83781dbf8c4c657ef3',
  signature: '0xcbd996ee0f2d18944034f29e5a9565158202d8d66194adcbe0c13eba96feb18e1783254ec656186cd1461693969c10aff0014f4690ee2f83781dbf8c4a657ef31c'
}
SignedMessage(messageHash=HexBytes('0x629749f84ee0d301f8eb02f3ef897b0c0a4553d2fdxd1fa0ea5cbbb6ff8bdfd5'), r=48064598734910045938712268846365002327886250846331651560012768739017714013389, s=54468135635475555126928311975236101130284121664770021136367631881584318718503, v=27, signature=HexBytes('0x6a43994c94195bf873b1025ae5778768a6311fb846bc21f5aeffc71f058394cd786bdf4d27e43e9a2358a4a0018f1af0333cbbf6318d6dd2be929e5f3fc9a2271b'))

Step 3: Submit Challenge

POST https://auth.dimo.zone/auth/web3/submit_challenge

Use x-www-form-urlencoded for body parameters.

Request Body

Name
Type
Description

client_id*

String

state*

String

The state string returned from Step 1.

grant_type*

String

This needs to be authorization_code.

domain*

String

signature*

String

The 0x-prefixed signature obtained from Step 2.

{
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc4ZjVkNDk3ZjVjZDM3MzljYjNhYmZhZDExZjRhZWQ2ZWQxNmNhMWYifQ.eyJpc3MiOiJodHRwczovL2F1dGguZGV2LmRpbW8uem9uZSIsInByb3ZpZGVyX2lkIjoid2ViMyIsInN1YiI6IkNpb3dlR1k1UkRJMk16SXpRV0kwT1RFM09VRTJaRFUzUXpJMk5URTFRakF4UkdVd01UZzFOVE0zT0RjU0JIZGxZak0iLCJhdWQiOiJ2ZWhpY2xlLWdlbml1cyIsImV4cCI6MTcwNTkzNTg5MCwiaWF0IjoxNzA0NzI2MjkwLCJhdF9oYXNoIjoiQnBVZXJtcmJMMUlNVkxNdXpELW93USIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZXRoZXJldW1fYWRkcmVzcyI6IjB4ZjlEMjYzMjNBYjQ5MTc5QTZkNTddMjY1MTVCMDFEZTAxODU1Mzc4NyJ9.BrZeLozHwFxQoyTnpe9TVjoFFyqh3xs2xi6KQrguQGyyWoqFr03SjDCbY_Les6IUI9JD_xWf9bu04w82LD0NqsnO7nqrYwrVwriYUmh1cZskZPUDrL5_kMaN0FxQa-ea9g4ruVEXLU_aM206q2Wp7qqyjd5AhuPAgqAL6mDGviGXr2lJYfxrs0eclO9-w4Z4XO0hRkLO_ODhCDrBeKcwPHEmhTNH6Vw0ReI_05FwIFzz_biIpS6rj45F0nSLrMcJx-2UD9upaMDzLwA_9QPoXzoA3hfdPNKGPU0KEgMJF9thFa2K0daqXqAMXUkxwOSSYWdn58Z8NJGFWN6bzyJqC3",
    "token_type": "bearer",
    "expires_in": 1209599,
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc4ZjVkNDk3ZjVjZDM3MzljYjNhYmZhZDExZjRhZWQ2ZWQxNmNhMWYifQ.eyJpc3MiOiJodHRwczovL2F1dGguZGV2LmRpbW8uem9usSIsInByb3ZpZGVyX2lkIjoid2ViMyIsInN1YiI6IkNpb3dlR1k1UkRJMk16SXpRV0kwT1RFM09VRTJaRFUzUXpJMk5URTFRakF4UkdVd01UZzFOVE0zT0RjU0JIZGxZak0iLCJhdWQiOiJ2ZWhpY2xlLWdlbml1cyIsImV4cCI6MTcwNTkzNTg5MCwiaWF0IjoxdzA0NzI2MjkwLCJhdF9oYXNoIjoibGdyZGx5UXhWVWlMY0o1ZWxmTU1odyIsImNfaGFzaCI6IkZid2NTVUlJcnl0S2xVblZHWjE4Z3ciLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImV0aGVyZXVtX2FkZHJlc3MiOiIweGY5RDI2MzIzQWI0OTE3OUE2ZDU3QzI2ETE1QjAxRGUwMTg1NTM3ODcifQ.afO4QhbCfzWZpB_VQhTuJBONA8hYMc8Dw97kNdDBwbYWCIZ_PFzIRUPJe75k19Y0oKm8hNeadyzV36x4uvv4wagfjEPXcttqzoiRrnFjwX5tHZgNaRSznBf6W6PoNzkx7GyGWmeW_AtV3Y4g_fDhC2PKVZeWlw346Prchf_mLDuC5d6HSydu4LoSGHRVhMXlbbwoXGcc3Jui-wMxli8gYx1N__5DXiGvasZgmZefRq9DqPhd5Nlp0AV7bDSSLVJOUZJybbHT153les-_IzMlyqowxrAaJl9ENk5ME5ak4g_gHUpJzPQAf3oe61K-sYKNUYcguah73xfysmbWc_bFsg"
}
{
    "status": 400,
    "message": "Requested resource does not exist."
}

Developer Notes

  1. If you made it this far, you should have an access_token that you can use to access some DIMO API endpoints. For protected API endpoints such as Telemetry API, a Vehicle JWT described in Token Exchange API is required.

Utilize on the frontend.

Utilize your on the backend.

Use the Developer JWT on the .

Configured client identifier, this is the 0x client identifier received when you .

A valid redirect URI for the client, this is the domain that you set when you .

Configured client identifier, this is the 0x client identifier received when you issue a .

A valid redirect URI for the client, this is the domain that you set when you .

To use the access_token you received, please follow the to format your HTTP request headers. A typical format would look like { "Authorization": "Bearer <access_token>"}

Bearer Authentication Scheme
Developer License
configure a Developer License
Login with DIMO
Token Exchange API
JSON Web Token
obtain a Developer License via the Console
Developer License
issue a Developer License
configure a Developer License