How to Add Authentication to an Embedded AI Widget Using Your Existing Auth Stack
The Short Version
If your users already log in somewhere else, you do not need to force them through a second login flow inside your AI widget. Orckai widgets can reuse the identity system your product already has.
The widget asks your backend for a short-lived proof of identity, Orckai exchanges that proof for a widget session, and the end user gets authenticated chat history, memory, and MCP access.
Mental model: widget auth is identity handoff, not a second identity provider. Your app stays in charge of login. Orckai turns that trusted identity into a widget session.
Why Add Authentication to an AI Widget
Public widgets are great for marketing sites and anonymous support. But authenticated widgets unlock a different class of experiences:
Persistent History
Conversations follow the actual user instead of staying tied to a single browser session.
Per-User Memory
The widget can remember context across sessions instead of starting cold every time.
Authenticated MCP Access
Connect tools and MCP servers to the actual end user, not an anonymous session placeholder.
Known User Identity
Your team can understand who is chatting instead of only seeing a random session ID.
How The Runtime Flow Works
User Opens Page
The customer app already knows who the user is from its normal login flow.
Widget Requests Identity
The widget calls getUserToken() on the host page.
Backend Signs Assertion
The customer backend signs a short-lived JWT describing the current user.
Orckai Exchanges It
Orckai verifies the JWT and returns a widget session token.
Widget Uses Session
Chat, history, memory, and MCP now run as that end user.
This is why the model works across many different auth stacks. Orckai only needs a signed assertion from your backend, not a direct integration with every identity provider on the market.
Embed Pattern
On the page, the widget looks like a normal embed with one extra piece: getUserToken.
<script>
window.ORCHESTRAI_CONFIG = {
widgetKey: "wk_your_widget_key_here",
apiUrl: "https://orckai.app/api",
getUserToken: async () => {
const res = await fetch("/api/orckai-widget-token", {
method: "POST",
credentials: "include"
});
const data = await res.json();
return data.token;
}
};
</script>
<script src="https://orckai.app/orchestrai-widget.min.js" defer></script>
If the widget is configured for optional auth, it can still fall back to anonymous chat when no token is available. If it is configured as required, chat stays locked until sign-in succeeds.
Examples By Customer Auth Stack
All of the following patterns produce the same outcome in Orckai. The only thing that changes is how the customer backend resolves the current user before signing the assertion.
Custom Login + App Session
Best for SaaS apps and customer portals with their own email/password auth. The backend reads the current app session and signs the assertion.
Auth0 or Okta
Best for hosted login deployments. Your app still handles the primary login, then your backend turns that user session into the widget assertion.
NextAuth, Clerk, or WorkOS
Best for modern web apps. Your server route resolves the signed-in user and returns a short-lived widget assertion.
SAML-Only Enterprise
Best for employee portals and enterprise customer apps. The widget never needs to talk SAML directly; it only needs the post-login app session.
Example: Custom App Session
app.post('/api/orckai-widget-token', requireLogin, (req, res) => {
const token = jwt.sign(
{
sub: req.user.id,
email: req.user.email,
name: req.user.name,
aud: 'orckai-widget'
},
Buffer.from(process.env.ORCKAI_WIDGET_SECRET, 'hex'),
{ algorithm: 'HS256', expiresIn: '5m' }
);
res.json({ token });
});
Example: Auth0 or Okta
app.post('/api/orckai-widget-token', requireAuthSession, (req, res) => {
const token = jwt.sign(
{
sub: req.user.sub,
email: req.user.email,
name: req.user.name,
aud: 'orckai-widget'
},
Buffer.from(process.env.ORCKAI_WIDGET_SECRET, 'hex'),
{ algorithm: 'HS256', expiresIn: '5m' }
);
res.json({ token });
});
Example: Next.js with a Server Session
export async function POST() {
const session = await auth();
if (!session?.user) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
const token = jwt.sign(
{
sub: session.user.id,
email: session.user.email,
name: session.user.name,
aud: 'orckai-widget'
},
Buffer.from(process.env.ORCKAI_WIDGET_SECRET, 'hex'),
{ algorithm: 'HS256', expiresIn: '5m' }
);
return Response.json({ token });
}
Example: SAML-Backed Enterprise Portal
app.post('/api/orckai-widget-token', requireSamlSession, (req, res) => {
const token = jwt.sign(
{
sub: req.user.employeeId,
email: req.user.email,
name: req.user.displayName,
aud: 'orckai-widget'
},
Buffer.from(process.env.ORCKAI_WIDGET_SECRET, 'hex'),
{ algorithm: 'HS256', expiresIn: '5m' }
);
res.json({ token });
});
What If The Customer Has No Backend?
Then the widget should stay anonymous in this phase. That is still a supported and valid deployment model for public websites, documentation sites, and simple lead-gen pages.
In other words, authenticated widget sessions are an upgrade path, not a requirement.
Security Best Practices
- Sign assertions on the backend only — never expose the shared secret or private key in browser code.
- Use short-lived assertions — five minutes is a good default because the assertion is only meant to be exchanged once.
- Include audience and issuer claims when configured — that reduces replay and configuration mistakes.
- Use the right HS256 key format — if your secret is stored as hex, decode it before signing in Node.js.
- Choose required auth intentionally — public websites usually want optional auth, while logged-in portals usually want required auth.
Good default: for public support sites, keep auth optional so the widget can fall back to anonymous mode. For customer portals and internal apps, require auth so history, memory, and tools always stay tied to a known user.
Getting Started
If your product already has login, you are closer than you think. The only new step is a small backend endpoint that signs a short-lived assertion JWT for the currently signed-in user.
From there, Orckai handles the widget session, conversation identity, memory, and authenticated MCP access. Your users keep the same login they already know, and your widget becomes far more personal and useful.