security: speech-input example exposes provider API key in client code
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 283
- Avg merge
- 32m
- Merged PRs (30d)
- 1
Description
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.tsxskills/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.tsxonmain. - Note that the file starts with
"use client". - Note the direct
fetch("https://api.openai.com/v1/audio/transcriptions", ...)call. - Note the
Authorizationheader usesprocess.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.mdto 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.tsxskills/ai-elements/references/speech-input.md.github/SECURITY.md(says to report vulnerabilities by opening a new issue)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with skills/ai-elements/scripts/speech-input.tsx and skills/ai-elements/references/speech-input.md, tracing the client-side fetch and the documented usage. Replace the direct provider request with a server-mediated pattern, keep the provider key server-side, and update the documentation to match; verify that no NEXT_PUBLIC_* provider secret is used by the example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, typescript
- Domain
- api, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100