Skip to content

VAP15-80 docs: document public-key model URL rejection - #1404

Merged
jeffrey-hoekman-vapi merged 4 commits into
mainfrom
jeffhoekman/vap15-80-document-that-public-key-calls-and
Nov 9, 2026
Merged

jeffrey-hoekman-vapi merged 4 commits into
mainfrom
jeffhoekman/vap15-80-document-that-public-key-calls-and

Conversation

@jeffrey-hoekman-vapi

Copy link
Copy Markdown
Contributor

Summary

VAPSEC-618 changed a documented contract. A web call or chat (POST /call/web, /chat/web, /chat/web/responses) authenticated with a public API key or a public JWT now gets a 403 if model.url appears anywhere in the request body. No page explained this, and the cohort email needs a stable URL to link to.

  • fern/assistants/concepts/transient-vs-permanent-configurations.mdx: new Model URLs on public-key requests section (anchor #model-urls-on-public-key-requests). It covers scope, the request-body locations, who is unaffected, the literal 403 body, and two fixes: save the assistant and pass assistantId, or start the call server-side with a private key.
  • fern/customization/custom-llm/using-your-server.mdx: a Note under the Custom LLM URL step that links to that section.

Notes for reviewers

  • The 403 message is quoted verbatim from CALLER_MODEL_URL_REJECTION_MESSAGE so support can search for it.
  • Scope is "public API key or public JWT". The enforced auth paths are api-key-public, customer-jwt-public and customer-jwt-untagged. VAPSEC-618 deliverable 4 keeps both JWT paths enforced, because Origin is caller-controlled and the token type is the only boundary an attacker can't forge. Org JWT and dashboard (workos-jwt) callers are not enforced.
  • The flag-gated ramp is deliberately not described.

Merge gate

Merge before the VAPSEC-618 cohort email is sent (the email links to this anchor) and before the VAPSEC-906 creation cutoff.

Test plan

  • fern check: 0 errors, no warnings on the edited pages
  • Preview: the section renders and the anchor link from the custom LLM page resolves

Refs VAP15-80, VAPSEC-618, VAPSEC-906

🤖 Generated with Claude Code

VAPSEC-618 changed a documented contract: a web call or chat
(POST /call/web, /chat/web, /chat/web/responses) authenticated with a
public API key or a public JWT now gets a 403 if model.url appears
anywhere in the request body. The docs still presented transient
assistants and assistantOverrides as interchangeable with saved
configuration from the browser, so a customer hitting the 403 had no
page explaining it. The cohort email needs a stable URL to link to.

- transient-vs-permanent-configurations.mdx: a "Model URLs on
  public-key requests" section covering scope, the request-body
  locations, who is unaffected, the literal 403 body, and the two
  fixes (save the assistant and pass assistantId, or start the call
  server-side with a private key).
- using-your-server.mdx: a Note under the Custom LLM URL step pointing
  to that section.

The 403 message is quoted verbatim from
CALLER_MODEL_URL_REJECTION_MESSAGE so support can search for it.

Scope says "public API key or public JWT", not "public key". The
enforced auth paths are api-key-public, customer-jwt-public and
customer-jwt-untagged; VAPSEC-618 deliverable 4 settled that both JWT
paths stay enforced, since Origin is caller-controlled and the token
type is the only boundary an attacker can't forge. org-jwt and
workos-jwt (dashboard) callers are not enforced and are excluded. The
ramp is deliberately not described.

fern check: 0 errors, no warnings on the edited pages.

Refs VAP15-80, VAPSEC-618, VAPSEC-906

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

@stephenvapiai stephenvapiai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this reads clearly. A few small editorial suggestions inline, none blocking.

@stephenvapiai stephenvapiai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with some comments.

- Use "stored assistant" throughout, matching the page and the 403 body
- Name the Custom LLM URL field next to model.url
- List squad.membersOverrides as its own location
- Clarify private keys and private JWTs are unaffected on POST /call and /chat
- Add a phased-rollout Note
- Note variableValues is the only override on the public chat routes
- Add private JWT to the server-side fix; fold the Warning into it
- Trim the custom LLM Note per review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

@jeffrey-hoekman-vapi
jeffrey-hoekman-vapi merged commit ea940e6 into main Nov 9, 2026
6 checks passed
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.

2 participants