SSO & embedding integration

Integration guide for Prometheus Pro Hub and other clients. As of April 2026, XFuel SSO uses token introspection — no shared secret required.

1. Overview

To sign a user into XFuel, pass their existing Hub session token to POST /sso/validate. XFuel verifies the token by calling Hub's /api/pm/user and /api/pm/units, resolves which XFuel customers the user has access to, and returns a scoped XFuel JWT.

Supported hardware: Geometris and Geotab. Users without any supported-hardware units receive 403.

2. Authentication methods

3. Token introspection — step by step

Step 1 — Hub sends user's session token to XFuel:

POST https://fleet-ai.prometheuspro.us/xfuel/sso/validate
Content-Type: application/json

{
  "hub_token": "<Hub session token, same one accepted by /api/pm/*>"
}

Note: body may optionally include customer_id to pin the active tenant. If omitted, XFuel auto-resolves from the user's accessible units.

Response (200):

{
  "xfuel_token": "eyJ...",
  "customer_id": "tmodal",
  "carrier_name": "T Modal",
  "expires_in": 28800,
  "role": "user",
  "accessible_customers": [
    { "id": "tmodal", "name": "T Modal", "role": "user" }
  ]
}

Error responses:

Step 2 — Hub loads XFuel with the token:

<iframe
  src="https://xfuel.prometheuspro.us/dashboard.html"
  id="xfuel-frame"
  width="100%" height="100%"
  style="border:none">
</iframe>

<script>
var frame = document.getElementById('xfuel-frame');
frame.contentWindow.postMessage({
  type: 'xfuel_auth',
  token: '<xfuel_token_from_step_1>'
}, 'https://xfuel.prometheuspro.us');
</script>

Step 3 — Hub listens for XFuel ready signal:

window.addEventListener('message', function(e) {
  if (e.origin !== 'https://xfuel.prometheuspro.us') return;
  if (e.data.type === 'xfuel_ready') {
    console.log('XFuel loaded, customer:', e.data.customer_id);
  }
  if (e.data.type === 'xfuel_auth_ack') {
    console.log('XFuel accepted auth token');
  }
});

4. URL token method (deep links)

Append ?token=<xfuel_token> to any XFuel URL. The bundled script stores the token in localStorage under xfuel_token and removes the query string without a full navigation.

https://xfuel.prometheuspro.us/dashboard.html?token=eyJ...

5. Iframe mode

When window.self !== window.top, XFuel sets data-iframe-mode="true" on the document element and hides sidebar/topbar chrome via CSS. Theme sync from Hub:

frame.contentWindow.postMessage({ type: 'xfuel_theme', theme: 'light' }, 'https://xfuel.prometheuspro.us');

6. Environment setup

Set on the XFuel API host:

# Required
JWT_SECRET=<xfuel_jwt_signing_secret>

# Optional (with defaults)
HUB_API_BASE_URL=https://api.prometheuspro.us
HUB_TIMEOUT_SECS=5.0

No shared secret with Hub is required — we verify tokens by calling Hub's API.

7. XFuel JWT payload

Returned in xfuel_token, signed with JWT_SECRET (HS256):

{
  "sub": "carlo@tmodal.com",
  "customer_id": "tmodal",
  "carrier_name": "T Modal",
  "name": "T Modal",
  "email": "carlo@tmodal.com",
  "hub_user_id": 5867,
  "accessible_customers": [{ "id": "tmodal", "name": "T Modal", "role": "user" }],
  "source": "prometheus_hub_sso",
  "iat": 1776878647,
  "exp": 1776907447
}

8. Testing SSO

Full round-trip:

# 1. Get an XFuel token from a Hub session token
curl -X POST https://fleet-ai.prometheuspro.us/xfuel/sso/validate \
  -H "Content-Type: application/json" \
  -d '{"hub_token":"<Hub_session_token>"}'

# 2. Use the xfuel_token for API calls
curl -H "Authorization: Bearer <xfuel_token>" \
  https://fleet-ai.prometheuspro.us/xfuel/sso/status

# 3. Fetch the fleet dashboard data
curl -H "Authorization: Bearer <xfuel_token>" \
  "https://fleet-ai.prometheuspro.us/xfuel/fleet/overview-cached?year=2026&quarter=1"

OpenAPI reference: API Documentation.