Skip to content

SMOODEV-1878: Embeddable-widget auth hook — origin allowlist + public-key authContext#2

Merged
brentrager merged 1 commit into
mainfrom
SMOODEV-1878-widget-auth
Jun 13, 2026
Merged

SMOODEV-1878: Embeddable-widget auth hook — origin allowlist + public-key authContext#2
brentrager merged 1 commit into
mainfrom
SMOODEV-1878-widget-auth

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

What

The gate for repointing the SmooAI dashboard embed off the legacy <smooai-chat-widget> to <smooth-agent-chat>. The public smooth-operator server had no agent resolution and no embed auth — any origin could drive any agent. This adds a pluggable hook so a host (SmooAI) can enforce a per-agent origin allowlist + public-key authContext, while standalone OSS stays open by default.

Design (the hook lives in the public code)

  • smooth_operator::widget_auth (lib):
    • WidgetAuthProvider async trait + AgentWidgetAuth { allowed_origins, public_key } policy.
    • PermissiveWidgetAuth (default — no policy → no enforcement) and StaticWidgetAuth (JSON map) impls.
    • origin_allowed (exact / scheme://*.suffix host wildcard / *) and verify_auth_context (HMAC-SHA256 over "{userId}:{timestamp}", constant-time, 60s replay window).
  • Server: captures the WS handshake Origin header and threads it ws_upgrade → connection_loop → handle_frame → handle_create_session, enforcing the agent's policy before a session is created — origin allowlist (fail closed) + optional authContext verification. AppState gains a widget_auth provider (with_widget_auth builder) and a WIDGET_AUTH_STRICT flag that rejects unknown agents.
  • A host plugs in a concrete provider backed by its agent DB; nothing SmooAI-specific lands in the OSS repo.

New error codes: ORIGIN_NOT_ALLOWED, AUTH_CONTEXT_INVALID, AGENT_NOT_AUTHORIZED.

Verification

  • 5 lib unit tests (origin matching incl. wildcard/scheme, HMAC valid/tampered/stale/garbage, providers) + 4 WS integration tests (allowed / disallowed / missing origin, unpolicied passthrough). 124 + 21 + 4 + 4 green.
  • cargo fmt --check clean; no new clippy warnings.
  • Changeset added (@smooai/smooth-operator minor).

Follow-up (SmooAI side, unblocks SMOODEV-1845)

Wire a concrete WidgetAuthProvider (agent allowed-origins + public key from the SmooAI agent store) into SmooAI's smooth-operator deployment with WIDGET_AUTH_STRICT=1, then repoint the dashboard generateInstallCode() to emit <smooth-agent-chat> and deprecate @smooai/ui-chat-widget.

🤖 Generated with Claude Code

…-key authContext

Adds a pluggable WidgetAuthProvider hook to the public smooth-operator server
that secures <smooth-agent-chat> embedding (the gate for repointing the SmooAI
dashboard embed off the legacy widget):

- smooth_operator::widget_auth (lib): the WidgetAuthProvider async trait +
  AgentWidgetAuth policy, a PermissiveWidgetAuth default (no enforcement) and a
  StaticWidgetAuth (JSON map) impl, plus origin_allowed (exact / host-wildcard /
  `*`) and verify_auth_context (HMAC-SHA256 over "{userId}:{timestamp}",
  replay-windowed) primitives.
- Server: capture the WS handshake Origin header, thread it through
  connection_loop → handle_frame → handle_create_session, and enforce the
  agent's policy before creating a session — origin allowlist (fail closed) +
  optional authContext verification. AppState gains a widget_auth provider
  (with_widget_auth builder, PermissiveWidgetAuth default) and a
  WIDGET_AUTH_STRICT config flag that rejects unknown agents.

A host (SmooAI) plugs in a concrete provider backed by its agent DB; the OSS
server stays open by default. New error codes: ORIGIN_NOT_ALLOWED,
AUTH_CONTEXT_INVALID, AGENT_NOT_AUTHORIZED.

Tests: 5 lib unit (origin matching, HMAC verify, providers) + 4 WS integration
(allowed/disallowed/missing origin, unpolicied passthrough). fmt + clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 221b16d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@smooai/smooth-operator Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@brentrager brentrager merged commit 715f79c into main Jun 13, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant