Every company has a few tools that don’t belong anywhere: an ad-spend dashboard, a capacity planner, a client report generator. They live behind their own logins, and people forget they exist.
An embedded app puts that tool in Clarion’s sidebar, next to the scorecard and milestones the team already checks every week. Clarion tells your tool who’s looking, which company, which user and what role, so it can show the right data without a second login.
The responsibility is security. An app that trusts whoever opens it is a data leak waiting to happen. This guide covers how the trust handshake works and the three layers that make it safe.
Adding the app
An Owner or Admin adds it in Settings → Integrations → Embedded Apps → Add App, with a name and an https:// URL. Only HTTPS is accepted. The app then appears in the sidebar for everyone in the company.
Each app has its own signing secret, revealed with the Secret button. That’s what your backend uses to verify Clarion’s tokens. See build an embedded app.
How the handshake works
Clarion loads your app in an iframe. Then:
- Your app posts
{ type: "clarion:ready" }to its parent window, targeting Clarion’s origin. - Clarion checks the message came from your app’s origin and from your iframe, then replies to your app’s exact origin with
{ type: "clarion:context", token }. - Your frontend sends the token to your backend, which verifies it and starts a session.
The token is a compact JWT signed with HS256 using your app’s secret. Its claims are:
iss: alwaysclarion.aud: your app’s id.companyId,companySlug,companyName.teamId: null for company-wide apps, which is what the Settings screen creates.userId,email,name,role: the viewer.iatandexp: it expires five minutes after it’s issued.
If your app needs a fresh token, post clarion:ready again.
The three layers of trust
1. Refuse to be framed anywhere else. Send this response header from your app:
Content-Security-Policy: frame-ancestors https://app.onclarion.com
Browsers will then refuse to load your app inside any other site.
2. Only trust messages from Clarion. In your frontend’s message listener, ignore any message whose origin isn’t https://app.onclarion.com.
3. Verify the token on your server. The signing secret must never reach the browser. Your backend checks the signature in constant time, then checks iss is clarion, aud is your app’s id, and exp hasn’t passed. The aud check ties each token to your app, so a token issued for a different app is never accepted, even if your backends are shared.
No valid token means the app wasn’t opened from Clarion. Render a locked state and stop.
The Embedded Apps section in Settings includes copy-ready snippets for each layer, and a button to copy the whole integration brief as one Markdown document, handy if you’re building with an AI coding assistant.
Getting Clarion data into your app
The token tells you who is viewing, not what’s in Clarion. If your app needs to show the company’s metrics, milestones or action items, call the Integration API from your backend with a company-scoped API key that has only the read scopes you need. Use the companyId from the verified token to make sure you’re showing the right company’s data. See create API keys and read data with the API.
To keep that data fresh without polling, subscribe to webhooks and update your copy when things change. See reacting to changes with webhooks. To write numbers back to the scorecard, see pushing metrics from your systems.
Using the viewer’s role
The token includes the viewer’s Clarion role: OWNER, ADMIN, INTERNAL, ADVISOR or CONTRACTOR. You can use it to decide what your app shows, for example limiting an editing screen to Owners and Admins. Inside Clarion, Owners and Admins are the ones who manage settings and integrations; the other three roles get the same access to the teams they belong to. Your app can draw finer lines if it needs to.
A launch checklist
frame-ancestorsheader set on every response.- Message listener checks the origin.
- Token verified server-side: signature,
iss,aud,exp. - Signing secret stored server-side only.
- Locked state when there’s no valid token.
- API key, if used, has read scopes only.
Common mistakes
Verifying in the browser. It means shipping the signing secret to every viewer. Anyone could then mint tokens.
Skipping the aud check. It’s one line, and it’s what binds a token to your app. Check it every time.
Treating the token as a long session. It’s valid for five minutes. Exchange it for your own session on first load.
No frame-ancestors header. Without it, someone could embed your app in their own page.
Using the token as an API credential. It proves who’s viewing; it doesn’t grant access to Clarion’s API. Use an API key for that, kept on your server. See the embedded apps integration for an overview.