Skip to content

security: speech-input example exposes provider API key in client code #422

Description

@mochafreddo

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

  1. Open skills/ai-elements/scripts/speech-input.tsx on main.
  2. Note that the file starts with "use client".
  3. Note the direct fetch("https://api.openai.com/v1/audio/transcriptions", ...) call.
  4. Note the Authorization header uses process.env.NEXT_PUBLIC_OPENAI_API_KEY.
  5. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions