Yak Docs

Security

Yak is designed with security as a priority. The widget runs in an isolated iframe, all communication is origin-validated, and your tool calls execute in your own server context with your existing authentication.

Key Security Features

  • Origin isolation — The widget iframe is sandboxed from your application's DOM
  • Origin validation — All messages are validated against expected origins; unexpected origins are rejected
  • Tool allowlisting — Only explicitly allowed tools can be executed
  • Server-side execution — Tool calls run on your server with your auth and access controls
  • Identity verification — Persist conversations per end-user with HMAC-signed user identities
  • Redirect protection — Built-in protection against open redirect attacks

Tool Security

Restricting Exposed Procedures

When using the tRPC adapter, control which procedures are available:

import { createTRPCToolAdapter } from "@yak-io/trpc";

const toolAdapter = createTRPCToolAdapter({
  router: appRouter,
  createContext,
  allowedProcedures: [
    "orders.list",
    "orders.getById",
    "products.search",
  ],
});

Always restrict procedures to the minimal set needed by the assistant. Avoid exposing destructive operations without safeguards.

Authentication

Tool calls receive the original Request object, so your existing auth works automatically:

const toolAdapter = createTRPCToolAdapter({
  router: appRouter,
  createContext: async ({ req }) => {
    const session = await getSession(req);
    if (!session) throw new Error("Unauthorized");
    return { user: session.user };
  },
  allowedProcedures: ["..."],
});

Input Validation

Tool inputs are validated against the JSON Schema derived from your Zod schemas. Always validate on the server side as well:

export const ordersRouter = router({
  list: protectedProcedure
    .input(z.object({
      limit: z.number().min(1).max(100).default(10),
      status: z.enum(["pending", "shipped", "delivered"]).optional(),
    }))
    .query(async ({ ctx, input }) => {
      return db.orders.findMany({
        where: { userId: ctx.userId, status: input.status },
        take: input.limit,
      });
    }),
});

User Identity Verification

When you want to persist conversations against a specific end-user (so they can resume past chats from the widget), the widget needs a tamper-proof way to know who's chatting. Yak uses the same HMAC pattern as Intercom and similar tools:

  1. Your application gets an apiSecret (revealable from your dashboard).
  2. Your backend signs the user id: hash = HMAC-SHA256(apiSecret, userId).
  3. The browser passes { id, hash } into <YakProvider user={...}>.
  4. Every Yak endpoint that touches user data re-verifies the hash with a constant-time comparison.
// Backend
import crypto from "node:crypto";

const userHash = crypto
  .createHmac("sha256", process.env.YAK_API_SECRET!)
  .update(currentUser.id)
  .digest("hex");
// Browser
<YakProvider
  appId={appId}
  user={{ id: currentUser.id, hash: userHash }}
/>

Never expose YAK_API_SECRET to the browser. Compute the hash on your server and send only the resulting hex string to the client.

Only the user id is HMAC-protected. A holder of the secret can produce a valid identity for any id, so keep the secret on the server.

If you suspect the secret has leaked, rotate it from the dashboard. Rotation invalidates every previously signed hash, so plan it alongside a deploy of your server code.

See End-user identity for the full guide and language-specific signing snippets.

Redirect Protection

The SDK validates all redirect paths:

  • Allowed: Relative paths (/dashboard, /settings), hash paths (#section), query paths (?tab=profile)
  • Blocked: External domain URLs, protocol-relative URLs (//evil.com)

To customize redirect behavior:

<YakProvider
  appId="your-app"
  onRedirect={(path) => {
    if (isAllowedPath(path)) {
      router.push(path);
    }
  }}
/>

Content Security Policy

If your application uses CSP headers, allow the widget iframe:

frame-src https://chat.yak.io;

Production Checklist

Before deploying to production, verify:

  • Tool allowlist — Only necessary procedures are exposed
  • Authentication — Tool requests require valid auth
  • Rate limiting — Consider rate limiting your tool endpoint
  • HTTPS — All endpoints use HTTPS
  • CSP headers — Allow frame-src chat.yak.io if using CSP
  • Logging — Tool invocations are logged for audit
  • Allowed origins — Restrict which domains can embed the widget (configure in your dashboard)
  • User identity — If you persist conversations per end-user, the apiSecret is server-only and the hash is computed on every page load (never cached client-side)

Reporting Security Issues

If you discover a security vulnerability, please report it responsibly:

  1. Do not create a public GitHub issue
  2. Email security@yak.io with details
  3. Include steps to reproduce if possible

On this page