# How to Enable Embed Subdomain and Secure Mode in WeKnora

> Learn how to enable embed subdomain and secure mode in WeKnora by configuring your reverse proxy, creating an embed channel, and switching to short-lived session tokens.

- Repository: [Tencent/WeKnora](https://github.com/tencent/WeKnora)
- Tags: how-to-guide
- Published: 2026-09-13

---

**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`](https://github.com/Tencent/WeKnora/blob/main/docs/embed-subdomain.md) and referenced from the sample Nginx configuration at [`frontend/nginx.conf`](https://github.com/Tencent/WeKnora/blob/main/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`](https://github.com/Tencent/WeKnora/blob/main/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`](https://github.com/Tencent/WeKnora/blob/main/frontend/nginx.conf) demonstrates the required server block:

```nginx

# 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`](https://github.com/Tencent/WeKnora/blob/main/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`](https://github.com/Tencent/WeKnora/blob/main/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:

```bash
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`](https://github.com/Tencent/WeKnora/blob/main/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:

```bash
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`](https://github.com/Tencent/WeKnora/blob/main/internal/handler/embed_channel.go).

### Rotating the Publish Token

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

```bash
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`](https://github.com/Tencent/WeKnora/blob/main/weknora-widget.js) loader. The script fetches the session token from your designated endpoint before mounting the iframe.

```html
<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`](https://github.com/Tencent/WeKnora/blob/main/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`](https://github.com/Tencent/WeKnora/blob/main/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`](https://github.com/Tencent/WeKnora/blob/main/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`](https://github.com/Tencent/WeKnora/blob/main/frontend/nginx.conf)) to route the subdomain to the WeKnora frontend build. Additionally, review [`docs/embed-subdomain.md`](https://github.com/Tencent/WeKnora/blob/main/docs/embed-subdomain.md) for CORS header recommendations and ensure [`docs/embed-secure-mode.md`](https://github.com/Tencent/WeKnora/blob/main/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.