For the complete documentation index, see llms.txt. This page is also available as Markdown.

Authentication

How an App verifies calls from VARIO Cloud and authenticates its own API requests.

An App authenticates in two directions, and it is important not to confuse them:

Direction
Token
Question it answers

VARIO Cloud → your App

appToken

Is this incoming request really from VARIO Cloud?

Your App → VARIO Cloud

accessToken (obtained from an offlineToken)

May this App read/write data in this tenant?

The VARIO App Framework handles both for you. This page explains what it does, so you can debug it — and so you can implement it yourself if you don't use the framework.


The client configuration

Your App is identified by the four values you receive when creating the App. The demo app keeps them in app-client.js, exporting them as a module:

// app-client.js
module.exports = {
  appIdentifier: '',
  clientId: '',
  clientSecret: '',
  appJWK: { keys: [ /* … */ ] },
};

You pass this object when constructing the App:

const VarioCloudApp = require('@vario-software/vario-app-framework-backend/app.js');
const client = require('../app-client.js');

const app = new VarioCloudApp(client);

app.port = 8443;
app.uiPath = path.resolve(__dirname, '../frontend');

app.offlineToken.init().then(() => app.start());

Inbound: verifying the appToken

Every request VARIO Cloud sends to your App carries an appToken — a JWT signed with ES256. The framework installs an authentication middleware on the App's API router, so all your /api/* routes are protected automatically.

Verification checks that:

  • the signature matches the public key in your appJWK,

  • the aud claim equals your appIdentifier,

  • the token has not expired.

If any check fails, the request is answered with 401 and never reaches your route.

The token is normally read from the Authorization: Bearer <appToken> header. There is one exception: for GET requests to /api/install and /api/uninstall, it is read from the appToken query parameter — this exists so Apps without a UI can be installed.

This is also how you verify webhooks: a webhook call into your App is authenticated the same way. If you handle webhooks through the framework's API router, verification already happened. See Webhooks.


Outbound: from offlineToken to accessToken

To call the VARIO Cloud API, your App needs an access token per tenant.

  1. During installation, VARIO Cloud hands your App an offlineToken for that tenant — long-lived, but not unlimited (see Lifetime).

  2. Your App stores it, keyed by tenant.

  3. On the first API call, the framework exchanges the offlineToken for a short-lived accessToken at the tenant's identity server.

  4. The accessToken is cached until shortly before it expires, then refreshed.

The framework also derives the tenant's API base URL from the offlineToken itself: the token's issuer (iss) points at the tenant's identity server, and stripping the sso. prefix yields the tenant host. Requests are then sent to https://<tenant-host>/api/vario.

→ See REST API Introduction for how base URLs are structured.

Bootstrap: the install call

The offlineToken arrives when VARIO Cloud installs your App in a tenant: it calls your install endpoint with the token in the request body:

A typical install service does three things in order:

Lifetime: 45 days, sliding

An offlineToken is valid for 45 days — but the clock restarts on every use. Each time your App exchanges it for an access token, its validity is extended to a fresh 45 days.

In practice that means a regularly active App never sees the token expire. It only becomes invalid after 45 consecutive days without a single API call for that tenant.

Renewal: the install call happens again

An offlineToken is not permanent — it expires if unused, and the customer can replace it deliberately. In the Admin-Center, on the installed App's page, the action "Offline-Token erneuern" issues a fresh token and then opens your App's installation page (pcInstallationUrl) again with the new token attached — which hands it to your install endpoint exactly as it does on a first install.

In other words: install is not a one-shot event. The same endpoint that bootstrapped the App is also the renewal channel.

Two consequences for your implementation:

  • Overwrite unconditionally. Store the incoming token even when you already have one — otherwise renewal silently keeps the dead token.

  • Keep install idempotent. It will run again on an already-provisioned tenant. Migration steps that already ran are skipped for you, but anything you do outside a migration step must tolerate repetition.

When a token has expired, the App instance is flagged accordingly and the customer is prompted to renew it. Your App cannot trigger renewal itself — so when API calls for one tenant start failing with 401, log the tenant clearly so the cause is recognisable.

Where the offlineToken is stored

Out of the box, app.offlineToken keeps tokens in a local JSON file (offlineToken.db) — convenient for development, but not suitable for a multi-instance production deployment. You can pass your own storage implementation (get, set, delete per tenant) via the App options and keep tokens in your own database or secrets store.

Changing or deleting a stored offlineToken also drops the cached accessToken for that tenant.


Making API calls

Once installed, you don't manage tokens at all — you use the ERP client on the App:

The framework attaches, on every request:

Header
Value

Authorization

Bearer <accessToken>

user-agent

your appIdentifier

Accept / Content-Type

application/json

The VARIO Cloud API rejects requests without a User-Agent with 403 Forbidden. The framework satisfies this by sending your appIdentifier — if you call the API without the framework, you must set the header yourself. See REST API Authentication.

If the API answers 401, the cached accessToken for that tenant is discarded so the next call fetches a fresh one.


Without the framework

Nothing here is magic — the App model sits on plain OAuth 2.0. If you implement it yourself, you must:

  1. Verify the inbound appToken (ES256, aud = appIdentifier, not expired) against your appJWK.

  2. Store the offlineToken you receive on install, per tenant.

  3. Exchange it for an accessToken using the refresh token grant with your clientId and clientSecret.

  4. Send Authorization: Bearer <accessToken> and a User-Agent on every request.

  5. Cache access tokens and refresh them before they expire.

The grant types and endpoints are documented in REST API Authentication.

Last updated

Was this helpful?