Skip to content

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

@mochafreddo

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions