Summary
The current speech-input client example demonstrates sending audio directly from a "use client" component to the OpenAI transcription endpoint with:
Authorization: `Bearer ${process.env.NEXT_PUBLIC_OPENAI_API_KEY}`
This encourages exposing an OpenAI API key to the browser if consumers copy the example as written.
Affected files
skills/ai-elements/scripts/speech-input.tsx
skills/ai-elements/references/speech-input.md
Expected behavior
Examples should be secure by default and avoid putting secret provider API keys in client-side code. A safer example would:
- send the audio to an application-owned server route / proxy, or
- use a short-lived scoped token mechanism explicitly documented as browser-safe
Actual behavior
The example is a client component and performs a direct browser-side request to https://api.openai.com/v1/audio/transcriptions using process.env.NEXT_PUBLIC_OPENAI_API_KEY for the Authorization header.
Why this is a problem
NEXT_PUBLIC_* values are exposed to the browser bundle. If a developer follows this example with a real OpenAI API key, the key can be exposed in client code and/or network traffic.
This is especially risky because this file lives in a reusable example skill, so it is likely to be copied into production applications.
Steps to reproduce
- Open
skills/ai-elements/scripts/speech-input.tsx on main.
- Note that the file starts with
"use client".
- Note the direct
fetch("https://api.openai.com/v1/audio/transcriptions", ...) call.
- Note the
Authorization header uses process.env.NEXT_PUBLIC_OPENAI_API_KEY.
- In a Next.js app, any real value assigned to that env var will be browser-exposed.
Suggested fix
- Replace the example with a server-mediated pattern, for example posting the recorded audio to
/api/transcribe.
- Keep the real provider key on the server only.
- Update the docs example in
skills/ai-elements/references/speech-input.md to match.
- Optionally add an explicit note warning against putting provider secrets in
NEXT_PUBLIC_* env vars.
Environment
- Repository:
vercel/ai-elements
- Branch checked:
main
- Observed on: 2026-04-07
References
skills/ai-elements/scripts/speech-input.tsx
skills/ai-elements/references/speech-input.md
.github/SECURITY.md (says to report vulnerabilities by opening a new issue)
Summary
The current
speech-inputclient example demonstrates sending audio directly from a"use client"component to the OpenAI transcription endpoint with:Authorization: `Bearer ${process.env.NEXT_PUBLIC_OPENAI_API_KEY}`This encourages exposing an OpenAI API key to the browser if consumers copy the example as written.
Affected files
skills/ai-elements/scripts/speech-input.tsxskills/ai-elements/references/speech-input.mdExpected behavior
Examples should be secure by default and avoid putting secret provider API keys in client-side code. A safer example would:
Actual behavior
The example is a client component and performs a direct browser-side request to
https://api.openai.com/v1/audio/transcriptionsusingprocess.env.NEXT_PUBLIC_OPENAI_API_KEYfor theAuthorizationheader.Why this is a problem
NEXT_PUBLIC_*values are exposed to the browser bundle. If a developer follows this example with a real OpenAI API key, the key can be exposed in client code and/or network traffic.This is especially risky because this file lives in a reusable example skill, so it is likely to be copied into production applications.
Steps to reproduce
skills/ai-elements/scripts/speech-input.tsxonmain."use client".fetch("https://api.openai.com/v1/audio/transcriptions", ...)call.Authorizationheader usesprocess.env.NEXT_PUBLIC_OPENAI_API_KEY.Suggested fix
/api/transcribe.skills/ai-elements/references/speech-input.mdto match.NEXT_PUBLIC_*env vars.Environment
vercel/ai-elementsmainReferences
skills/ai-elements/scripts/speech-input.tsxskills/ai-elements/references/speech-input.md.github/SECURITY.md(says to report vulnerabilities by opening a new issue)