How to Enable Embed Subdomain and Secure Mode in WeKnora

To enable embed subdomain and secure mode in WeKnora, configure a dedicated subdomain for the embed UI in your reverse proxy, create an embed channel with an origin allow‑list, and switch from long‑lived publish tokens to short‑lived session tokens obtained via a server‑to‑server exchange.

WeKnora is Tencent’s open‑source agent framework that lets you deploy conversational AI agents on third‑party websites through embed channels. For production environments, you should isolate the chat interface on its own subdomain and enforce secure mode to prevent token theft. This guide walks through the configuration using the actual source paths and handlers found in the Tencent/WeKnora repository.

Understanding WeKnora's Embed Architecture

Before modifying configuration files, it helps to understand how the two safety mechanisms interact with the codebase.

What Is an Embed Subdomain?

The embed subdomain (e.g., embed.example.com) serves the chat UI from a dedicated host separate from the main WeKnora application. This isolation accomplishes two things: it bypasses X‑Frame‑Options: SAMEORIGIN restrictions so the iframe can load on external sites, and it allows you to apply a stricter CORS policy that only permits requests from domains listed in the channel’s allow‑list. The setup is documented in docs/embed-subdomain.md and referenced from the sample Nginx configuration at frontend/nginx.conf.

What Is Secure Mode?

Secure mode replaces the long‑lived publish token (prefix em_…) with a temporary session token (prefix ems_…). Instead of exposing the publish token in client‑side JavaScript, your backend exchanges it for a short‑lived token by calling the /api/v1/embed/:channel_id/exchange endpoint. The handler in internal/handler/embed_channel.go verifies the request’s Origin header against the channel’s allow‑list before issuing the session token, ensuring that only authorized domains can initialize the chat widget.

Configuring the Embed Subdomain

To serve the embed page from a dedicated subdomain, update your reverse proxy to route traffic to the WeKnora frontend build. The following Nginx excerpt from frontend/nginx.conf demonstrates the required server block:


# See docs/embed-subdomain.md

server {
    listen 443 ssl;
    server_name embed.example.com;

    location / {
        # Proxy to the embed HTML built by Vite/Vue

        proxy_pass http://localhost:3000;
        # Allow CORS from allowed origins defined in the embed channel

        add_header Access-Control-Allow-Origin $http_origin always;
        add_header Access-Control-Allow-Credentials true;
    }
}

Enable SSL certificates for embed.example.com and ensure DNS resolves to this server. The Access-Control-Allow-Origin directive uses the incoming $http_origin variable because the middleware in internal/middleware/embed_auth.go validates the origin against the channel’s stored allow‑list at request time.

Enabling Secure Mode for Token Exchange

Secure mode requires a handshake between your business backend and WeKnora’s API. You store the publish token server‑side and expose a custom endpoint that returns the temporary session token to the browser.

The Exchange Flow

  1. The frontend requests a token from your backend endpoint (e.g., /get-embed-token).
  2. Your server calls WeKnora’s exchange API with the publish token and its own origin.
  3. If the origin matches the channel’s allow‑list (validated by validateAllowedOrigins in internal/handler/embed_channel.go), WeKnora returns a session token valid for a brief window.
  4. Your backend forwards the session token to the frontend, which initializes the widget.

Backend Exchange Example

Run this curl command from your business server to obtain a session token:

curl -X POST https://weknora.example.com/api/v1/embed/ec-1/exchange \
     -H "Authorization: Embed $PUBLISH_TOKEN" \
     -H "Origin: https://backend.example.com"

A successful response contains the short‑lived ems_… token. According to the design documentation in docs/embed-secure-mode.md (line 155), both the embed frontend and your business backend must ensure CORS headers are present for this exchange to succeed in browser contexts.

Setting Up Embed Channels

Before secure mode can function, you must create an embed channel that defines the allowed origins.

Creating an Embed Channel

Use the following request to register a new channel for agent agent-1. Replace $TOKEN with your WeKnora API key:

curl -X POST https://weknora.example.com/api/v1/agents/agent-1/embed-channels \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
           "name":"MySite",
           "allowedOrigins":["https://app.example.com","*.example.com"],
           "rateLimitPerMinute":60,
           "rateLimitPerDay":1000,
           "description":"Embed for my site"
         }'

The allowedOrigins array supports exact URLs and wildcard subdomains (e.g., *.example.com). The handler stores these values and references them during the exchange validation described in internal/handler/embed_channel.go.

Rotating the Publish Token

If a publish token is compromised, rotate it without deleting the channel:

curl -X POST https://weknora.example.com/api/v1/embed-channels/ec-1/rotate-token \
     -H "Authorization: Bearer $TOKEN"

The new token is returned in the response; update your backend secrets store immediately.

Integrating the Widget

Once the subdomain and secure mode are configured, embed the widget on third‑party sites using the weknora-widget.js loader. The script fetches the session token from your designated endpoint before mounting the iframe.

<script src="https://embed.example.com/weknora-widget.js"
        data-channel-id="ec-1"
        data-token-endpoint="https://backend.example.com/get-embed-token">
</script>

The widget automatically requests /get-embed-token from your backend, receives the short‑lived ems_… token, and initializes the chat interface against the embed subdomain.

Summary

  • Embed subdomain: Isolate the chat UI on a dedicated host (e.g., embed.example.com) via Nginx configuration to avoid X‑Frame‑Options conflicts and tighten CORS policies.
  • Secure mode: Replace static publish tokens (em_…) with ephemeral session tokens (ems_…) obtained through the /api/v1/embed/:channel_id/exchange endpoint.
  • Origin validation: The validateAllowedOrigins function in internal/handler/embed_channel.go enforces domain restrictions during token exchange.
  • Token rotation: Use the rotate endpoint to invalidate leaked publish tokens without service disruption.

Frequently Asked Questions

How does secure mode prevent token theft?

Secure mode keeps long‑lived publish tokens server‑side. When a user loads your page, your backend calls the exchange endpoint with the publish token and an Origin header. WeKnora validates that origin against the channel’s allow‑list in internal/middleware/embed_auth.go and returns a short‑lived session token (ems_…) that expires quickly. Even if a malicious site scrapes the session token, it becomes useless within minutes.

Can I use wildcards in the allowed origins list?

Yes. The allowedOrigins field accepts exact URLs (e.g., https://app.example.com) or wildcard patterns such as *.example.com. The validation logic in internal/handler/embed_channel.go matches incoming Origin headers against these patterns before issuing tokens or serving the embed page.

What files must I edit to enable the embed subdomain?

You need to modify your reverse proxy configuration (e.g., frontend/nginx.conf) to route the subdomain to the WeKnora frontend build. Additionally, review docs/embed-subdomain.md for CORS header recommendations and ensure docs/embed-secure-mode.md guidelines are followed for backend token exchange integration.

Do I need to enable both subdomain and secure mode together?

While technically optional, Tencent recommends enabling both for production deployments. The subdomain isolates the embed frontend from the main application, while secure mode ensures that only origins you explicitly trust can obtain valid session tokens, preventing unauthorized embedding and token leakage.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →