In the previous chapter, Message Routing & Data Flow (The "Dispatcher"), we built a smart system to sort and route messages. But there is a catch: you can't just walk up to a cloud server and start sending commands. You need permission.
Welcome to Authentication & Security, or "The Keycard."
Imagine you work in a high-security building.
Here is the twist: The Visitor Badge self-destructs every hour.
If you are in the middle of a 3-hour meeting (a long coding session) and your badge expires, the security guards (the server) will throw you out. Your connection drops, and your work is lost.
The Goal: We need a robot assistant that watches your badge. Five minutes before it expires, the robot runs to the front desk, gets a fresh badge, and swaps it on your shirtβwithout you ever noticing.
This is your long-term identity. It proves you are you (e.g., "User: Alice"). You get this when you log in.
This is a short-lived token (JSON Web Token). It grants access to one specific session for a short time. We use this for the actual connection because it is safer; if stolen, it expires quickly.
For extra security, the system checks if the request is coming from a "known laptop." This acts like Two-Factor Authentication behind the scenes.
This is a timer that calculates exactly when the JWT will expire and triggers a renewal sequence beforehand.
Let's say a user starts a session that stays open for 24 hours.
How does the system know when to wake up?
Let's look at the code that manages these keys.
bridgeConfig.ts)Before we can get any keys, we need to find the user's primary OAuth token.
// bridgeConfig.ts
import { getClaudeAIOAuthTokens } from '../utils/auth.js'
export function getBridgeAccessToken(): string | undefined {
// 1. Check if we are in a special Dev mode override
const devToken = getBridgeTokenOverride();
// 2. If not, get the real token from the system keychain
return devToken ?? getClaudeAIOAuthTokens()?.accessToken;
}
Explanation: This function acts as the wallet. It checks if you have a developer override (useful for testing); otherwise, it grabs the real production credentials stored securely on your computer.
trustedDevice.ts)This ensures your specific computer is authorized.
// trustedDevice.ts
export async function enrollTrustedDevice(): Promise<void> {
// 1. Send computer details to the server
const response = await axios.post(`${baseUrl}/api/auth/trusted_devices`, {
display_name: `Claude Code on ${hostname()}`
});
// 2. Get the specific device token
const token = response.data?.device_token;
// 3. Save it to the secure keychain
getSecureStorage().update({ trustedDeviceToken: token });
}
Explanation: When you first log in, this runs once. It registers "My Macbook Pro" with the server. Future requests will include this token in the header, proving the request comes from this specific physical machine.
jwtUtils.ts)We need to know when the badge expires. The expiration date is hidden inside the "payload" of the JWT string.
// jwtUtils.ts
export function decodeJwtExpiry(token: string): number | null {
// 1. Decode the middle part of the token (base64)
const payload = decodeJwtPayload(token);
// 2. Look for the "exp" (expiry) field
if (payload && typeof payload.exp === 'number') {
return payload.exp; // Unix timestamp
}
return null; // Could not read it
}
Explanation: JWTs are just strings separated by dots. This function cracks open the string to read the exp number, which tells us the exact second the token becomes invalid.
jwtUtils.ts)This is the logic that prevents the session from dying.
// jwtUtils.ts
export function createTokenRefreshScheduler({ onRefresh }) {
function schedule(sessionId, token) {
// 1. Find out when the token dies
const expiry = decodeJwtExpiry(token);
// 2. Calculate delay: Expiry - Now - Buffer (e.g., 5 mins)
const delayMs = expiry * 1000 - Date.now() - 300_000;
// 3. Set the alarm
setTimeout(() => {
// Time's up! Call the refresh function.
onRefresh(sessionId);
}, delayMs);
}
return { schedule };
}
Explanation:
delayMs. If the token expires in 60 minutes, and our buffer is 5 minutes, we set the timer for 55 minutes.onRefresh. This callback (defined in the Core) fetches a new token and restarts the cycle.The Authentication & Security layer acts as the invisible guardian of the connection.
Without this layer, long-running tasks would fail, and users would constantly have to re-login.
Now that we have a secure, robust, and intelligent connection, there is only one piece left. How does the user actually see what is happening? It's time to build the interface.
Next Chapter: Bridge UI & Feedback (The "Dashboard")
Generated by Code IQ