Skip to main content

Authentication

info

Authentication ensures that all communication between Scompler and your app is secure and trusted.

Your app must validate requests at different stages of the lifecycle, including installation, runtime interactions and webhooks.

App secret

The app secret is a private credential generated for your app.

It is used to verify that requests and tokens issued by Scompler are authentic and have not been modified.

You can find the app secret in the app configuration.

warning

Keep your app secret secure. Never expose it in frontend code or share it publicly.

Tokens

Scompler issues different types of tokens depending on the stage of the app lifecycle.

Each token serves a specific purpose.

How it works

Session tokenAccess token
Issued byApp Bridge (runtime)Scompler (on install)
Used forApp Frontend → App BackendApp Backend → Scompler API
Lifetime60 secondsLong-lived
StorageNever storedSecurely on the backend

Session token

The session token is a JWT (JSON Web Token) issued at runtime via App Bridge. It is used by the frontend to authenticate requests to the App Backend.

The session token:

  • Is valid for 1 minute (short-lived). It must be refreshed via App Bridge once expired.
  • Is included in App Frontend → App Backend requests.
  • Must be validated by the App Backend using the app secret.
  • Is not used for calling Scompler API.

Session token payload

FieldDescription
issThe domain that issued the token (e.g. pro.scompler.com).
account_idThe ID of the account associated with the session.
subThe ID of the current user in the app.
audThe ID of the app.
iatTimestamp when the token was created (Unix time).
expTimestamp when the token expires (Unix time).

Example payload:

{
"iss": "pro.scompler.com",
"account_id": 12345,
"sub": "67890",
"aud": "e3b0c442-98fc-4f12-9cde-1a2b3c4d5e6f",
"iat": 1676620800,
"exp": 1676620860
}

Access token

Issued during app installation and used by App Backend to call Scompler API.

The access token:

  • Is stored in the App Backend.
  • Is associated with a specific account.
  • Must never be exposed to the frontend.

Authentication flows

Authentication in Scompler occurs at four key stages throughout an app's lifecycle. Understanding each stage is crucial for building a secure application.

FlowMethod
Installation (auth callback)HMAC SHA256 (X-Signature header)
App launchHMAC SHA256 (query params)
Runtime requests (App Frontend → App Backend)Session token (JWT via App Bridge)
App Backend → Scompler APIAccess token
WebhooksHMAC SHA256 (X-Signature header)

Installation

When a user installs or re-authenticates your app, Scompler sends an HTTP POST request to your callback URL containing the access token.

Request headers:

X-Signature: <hmac>

Verify the X-Signature header by computing HMAC SHA256 of the raw request body using your app secret, then compare it to the header value.

const crypto = require('crypto')

function verifyCallbackSignature(rawBody, signature, appSecret) {
const expected = crypto.createHmac('sha256', appSecret).update(rawBody).digest('hex')
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
}
// Express.js example
app.post('/callback', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.headers['x-signature']
if (!verifyCallbackSignature(req.body, signature, process.env.APP_SECRET)) {
return res.status(401).send('Invalid signature')
}
const { account_id, access_token, expires_at } = JSON.parse(req.body)
// Store the access token securely
await saveAccessToken({ account_id, access_token, expires_at })
res.sendStatus(200)
})
note

Pass the raw request body bytes to the HMAC function — not the parsed JSON object. Parsing may alter whitespace or key ordering.

App launch

When a user opens your app, Scompler loads it in an iframe with signed query parameters. You must verify the hmac parameter before rendering any content.

Query parameters:

ParameterDescription
account_idThe account identifier
hostBase64 URL-safe encoded URL
timestampUnix timestamp of the request
languageThe current language
hmacHMAC SHA256 signature of the other parameters

To verify the hmac:

  1. Collect all query parameters except hmac.
  2. Sort them alphabetically by key.
  3. Serialize as a query string: key=value&key=value.
  4. Compute HMAC SHA256 using your app secret as the key.
  5. Compare the result to the hmac parameter.
const crypto = require('crypto')

function verifyLaunchHmac(query, appSecret) {
const { hmac, ...rest } = query
const message = Object.keys(rest)
.sort()
.map((key) => `${key}=${rest[key]}`)
.join('&')
const expected = crypto.createHmac('sha256', appSecret).update(message).digest('hex')
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(hmac))
}
warning

Always use a timing-safe comparison (e.g. crypto.timingSafeEqual) to prevent timing attacks.

Runtime requests (App Frontend → App Backend)

App Frontend authenticates requests to App Backend using session tokens obtained from App Bridge.

Use App Bridge to make authenticated requests to your backend:

import { createAppBridge } from '@scompler/app-bridge'

const app = createAppBridge({ appId: 'my-app' })

// Recommended: use authFetch — handles token lifecycle automatically
const response = await app.authFetch('/api/data')

// Or get the token directly for custom HTTP clients
const token = await app.getSessionToken()

Verify the token on your backend:

const jwt = require('jsonwebtoken')

function verifySessionToken(token, appSecret, appId) {
return jwt.verify(token, appSecret, {
algorithms: ['HS256'],
audience: appId,
})
}

Handle token expiry: Session tokens expire after 60 seconds. Rather than pre-emptively refreshing on a timer, the recommended pattern is to retry the request once if the server responds with 401.

Webhooks

Webhook event payloads are signed the same way as the auth callback. Verify the X-Signature header using HMAC SHA256 of the raw body before processing any event.

See Webhooks for details on event types and payload structure.