Clarion
Sign in Get started
Docs · API & developers

Build an embedded app for Clarion's sidebar

Add an embedded app in Clarion, run the clarion:ready handshake, and verify the signed HS256 identity token on your server before trusting the viewer.

An embedded app is your own web app shown inside Clarion, under Apps in the sidebar. Clarion passes it a short-lived signed token that says which company and person is viewing. This page covers adding the app and building the three security layers it needs. For the overview, see the embedded apps integration page.

Add the app in Clarion

You need to be an owner or admin.

  1. Go to Settings → Integrations and scroll to Embedded Apps.
  2. Click Add App.
  3. Enter a name (it’s the sidebar label) and the app’s URL. It must start with https://.
  4. Click Add App. It appears under Apps in the sidebar for everyone in the company.
  5. Click Secret next to the app and copy the signing secret (clrsec_…). Your server verifies tokens with it.

To take an app out of the sidebar, click Remove.

You’ll also need the app’s id, which tokens carry in their aud claim. It’s the last part of the app’s address in Clarion: https://app.onclarion.com/apps/<app id>.

1. Lock framing to Clarion

Send this response header on every page of your app, so browsers refuse to frame it anywhere else:

Content-Security-Policy: frame-ancestors https://app.onclarion.com

2. Ask Clarion for context in the browser

When your page loads, tell the parent window you’re ready, then pass the token it sends back to your own backend. The signing secret must never reach the browser.

const CLARION_ORIGIN = "https://app.onclarion.com";

// tell Clarion we're ready for context
window.parent.postMessage({ type: "clarion:ready" }, CLARION_ORIGIN);

window.addEventListener("message", async (e) => {
  if (e.origin !== CLARION_ORIGIN) return;            // only trust Clarion
  if (e.data && e.data.type === "clarion:context") {
    // relay to YOUR backend, which holds the secret and verifies
    const r = await fetch("/clarion-session", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ token: e.data.token }),
    });
    r.ok ? renderApp(await r.json()) : showLockedState();
  }
});

Clarion only answers clarion:ready messages from your app’s exact origin, and only sends the token back to that origin.

3. Verify the token on your server

The token is a compact HS256 JWT signed with your app’s secret. Verify it before trusting anything in it:

// Node.js — keep CLARION_SECRET server-side only
const crypto = require("crypto");

function verifyClarionToken(token, secret, appId) {
  const [h, p, sig] = token.split(".");
  if (!h || !p || !sig) throw new Error("malformed token");

  const expected = crypto.createHmac("sha256", secret)
    .update(h + "." + p).digest("base64url");
  const a = Buffer.from(sig), b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b))
    throw new Error("bad signature");

  const claims = JSON.parse(Buffer.from(p, "base64url").toString());
  if (claims.iss !== "clarion") throw new Error("bad issuer");
  if (claims.aud !== appId) throw new Error("token not for this app");
  if (claims.exp * 1000 < Date.now()) throw new Error("expired");
  return claims; // { companyId, teamId, userId, email, name, role, ... }
}

Any standard JWT library that supports HS256 works too, as long as you check iss, aud and exp.

The claims

ClaimMeaning
issAlways clarion
audThis app’s id
companyId, companySlug, companyNameThe company the viewer is in
teamIdThe app’s team, or null for a company-wide app
userId, email, nameThe viewer
roleThe viewer’s role in the company: OWNER, ADMIN, INTERNAL, ADVISOR or CONTRACTOR
iat, expIssued and expiry times; tokens last 5 minutes

Scope everything your app shows to the verified companyId and role. If no valid token arrives, the app wasn’t opened from Clarion: show a locked state and do nothing else. Since tokens expire after five minutes, have your backend create its own session once the token checks out.

Reading Clarion data

The token proves identity; it doesn’t grant API access. To read or write Clarion data, call the API from your backend with a company API key — for example, the read endpoints with metrics:read.

Building with an AI assistant

Under Securing your app (so it only runs inside Clarion) in the Embedded Apps card, Copy guide for LLM copies the handshake, token shape and all three layers as a single Markdown prompt.

08 — Get started

Ready to build unstoppable momentum?

Join teams that are aligned, accountable, and growing — with a business operating system built to be lived in every day.

Get started free Book a demo
No credit card required · Set up in minutes