In the previous chapter, Remote Feature Gating (GrowthBook), we learned how to install a "Smart Fuse" to disable features remotely.
Now that we know the feature is safe to use, we face a different problem: Does the user have the right key to open the door?
Imagine you are trying to enter an exclusive VIP lounge. You reach into your pocket and pull out a gym membership card. The bouncer stops you. "Sorry," they say, "that card works at the gym, but it doesn't work here."
In our application, we support many AI providers (Anthropic, Google Vertex, Amazon Bedrock). However, the Voice Mode feature is very specific. It relies on a special technology called voice_stream which is exclusively available via claude.ai.
If a user tries to use Voice Mode while logged in with an Amazon Bedrock key, the system will fail. We need a way to filter out users who have the wrong "membership card" before they try to connect.
We use a concept called Provider-Specific Authentication. This is a strict check that ensures:
We wrap this logic in a function called hasVoiceAuth().
As a developer, you use this function to decide if the user is "logged in" for Voice purposes.
import { hasVoiceAuth } from './voiceModeEnabled';
// Simple check: Do they have the specific VIP card?
if (hasVoiceAuth()) {
console.log("Allowed: User has Anthropic OAuth tokens.");
enableMicrophone();
} else {
console.log("Denied: User might be logged out OR using Bedrock/Vertex.");
}
What happens here:
true only if the user is logged into claude.ai via OAuth.
The hasVoiceAuth function performs a two-step verification process. Think of it like a bouncer checking an ID.
Here is the flow:
Let's break down the implementation in voiceModeEnabled.ts.
First, we check if the user is even looking at the right provider. Standard API keys or other cloud providers (like Azure or Bedrock) do not support the voice_stream endpoint.
export function hasVoiceAuth(): boolean {
// 1. Check provider type.
// Voice works ONLY with Anthropic OAuth.
// API Keys, Bedrock, and Vertex are strictly forbidden here.
if (!isAnthropicAuthEnabled()) {
return false
}
// ... continued below
Explanation:
isAnthropicAuthEnabled(): Checks the user's settings. If they are configured for Amazon Bedrock, this returns false, and hasVoiceAuth immediately says "No".If the provider is correct, we need to make sure the user is actually logged in. We look for the "Access Token" (the digital key).
// ... continued from above
// 2. Retrieve the tokens from secure storage.
const tokens = getClaudeAIOAuthTokens()
// 3. Convert to boolean (true if token exists, false if null/empty).
return Boolean(tokens?.accessToken)
}
Explanation:
getClaudeAIOAuthTokens(): This fetches the credentials from the computer's secure password storage (Keychain on macOS, Credentials Manager on Windows).Boolean(tokens?.accessToken): This is a fancy way of saying: "Is there text inside the token variable?" If it is undefined or empty, it returns false.You might wonder: doesn't reading from the secure keychain take time?
Yes, it does! On some computers, asking for a password takes 20-50 milliseconds. That is fast for a human, but slow for a computer trying to render a button 60 times a second.
If we ran this check every single frame, the app would stutter. We need a way to make this check faster. We will solve this in the next chapter using caching strategies.
You have learned about Provider-Specific Authentication.
This completes our "Readiness Logic." We have a fuse (GrowthBook) and a bouncer (Auth). But our bouncer is currently a bit slow at checking IDs.
In the next chapter, we will learn how to speed up this process so our UI stays buttery smooth.
Next Chapter: Performance-Aware Token Access
Generated by Code IQ