ai newsMo., 19. Okt.
EilmeldungSumming Claude Code's Transcript Usage? One API Response Can Appear Several Times

Secure your OpenAI API key (and your Claude and Gemini keys): a checklist

On October 17, OpenCode posted on X that it "had a security breach last night" affecting 1.4% of OpenCode Console users , "a subset of users who had external providers linked", and that it was working with Anthropic, OpenAI and Google to remediate. The email those users received, as reported by The

dev.toMontag 11:48 · 19.10.6 Min. Lesezeit
Bild: dev.to

Posted on Oct 19 • Originally published at joancomadran.dev

On October 17, OpenCode posted on X that it "had a security breach last night" affecting 1.4% of OpenCode Console users, "a subset of users who had external providers linked", and that it was working with Anthropic, OpenAI and Google to remediate. The email those users received, as reported by The Hacker News, says provider keys saved in Console workspaces may have been exposed. Within hours, Anthropic's Lydia Hallie said Anthropic had revoked the Claude API keys it believes were affected, and Google's Evan Otero said Google had blocked the exposed Gemini keys. As of October 19, 2026, OpenCode calls the incident ongoing and hasn't said how it happened. I'm not going to guess.

What matters for the rest of us is simpler. An LLM API key is a bearer credential: whoever has the string can spend your money until the provider revokes it. Securing it means fewer places where the string lives, and less damage when one of them leaks anyway.

Provider details below come from OpenAI's, Anthropic's and Google's own docs as of October 19, 2026. They change often.

If every script, agent and SaaS shares one key, any leak means revoking the key production runs on. With one key per consumer you revoke one thing, and the usage page tells you which consumer was abused.

A key that never expires stays valid for as long as anyone has a copy.

OpenAI and Google describe the same rotation order: create the replacement, deploy it, verify it works, then revoke the old one. Rehearse it on a quiet day to learn where the key actually lives (production, previews, CI, that cron job) before you have to do it under pressure. OpenAI and Anthropic also document workload identity federation, which swaps the stored key for short-lived tokens on supported cloud workloads: rotation with nothing to rotate.

OpenAI's article says it plainly: "Spend alerts alone don't stop API traffic." An email at 3 a.m. is a receipt for money that's already gone.

Same for auto-reload: Anthropic's key best practices treat auto-reload limits as a safeguard against leaked keys, and Google's Prepay plan has a monthly auto-charge limit. Uncapped auto-reload is an uncapped card.

For agents you build yourself, add a cap in code too. In Claient, when an account uses the platform's key, the webhook reserves budget atomically before each turn and stops replying when the monthly cap is hit. I described the same kill-switch idea in keeping Claude's token bill from ruining your month, and how to set caps for coding agents in Claude Code cost per month.

// lib/llm.ts import ' server-only '; // importing this from a Client Component fails the build import Anthropic from ' @anthropic-ai/sdk '; export const anthropic = new Anthropic ({ apiKey: process. env. ANTHROPIC_API_KEY }); Enter fullscreen mode Exit fullscreen mode // app/api/chat/route.ts import { anthropic } from ' @/lib/llm '; export async function POST ( req: Request ) { // Authenticate and rate-limit first: a public route that proxies // your key is still your key. const { message } = await req. json (); const res = await anthropic. messages. create ({ model: MODEL, // whatever you pin in config max_tokens: 512, messages: [{ role: ' user ', content: message }], }); return Response. json ( res. content ); } Enter fullscreen mode Exit fullscreen mode That's the pattern in Claient: the platform's key is read from ANTHROPIC_API_KEY in the server-side engine config, and the only key with a NEXT_PUBLIC_ prefix is Supabase's anon key, which is meant to be public. More on that split in the Next.js + Supabase pre-launch security checklist and in shipping an AI product in a weekend.

If your backend has fixed egress IPs, restrict by IP too. OpenAI's IP allowlist works per organization or project for all API customers and rejects other IPs with a 401 ip_not_authorized, valid key or not. Google lets you restrict a key to IP addresses under Application restrictions in the Cloud console. Anthropic's help center lists IP allowlisting for Enterprise plans, set up through support.

Anthropic's help center has the most honest sentence on this: when you upload your API key to a third-party tool, "you are giving the developer of that tool access to your Claude Console account." That isn't a comment on OpenCode. It's how every hosted tool that calls a model with your key works, including the one I build. And deleting a key inside the tool doesn't revoke it. Only the provider can.

Claient accepts customers' own Claude keys (BYOK), so I'm on the other side of this. In its code the key goes into Supabase Vault and the settings table keeps only the secret's id. The function that returns the decrypted key can only be executed by the service_role the webhook uses, so no dashboard user, owner included, can read it back, and the UI never shows it again. If a customer's key gets revoked, the bot falls back to the platform key and notifies the business instead of going quiet. That limits what a dashboard bug can leak. It doesn't make a key unstealable from a compromised server; nothing does.

So on the customer side: give each hosted tool a dedicated key in its own project or workspace, with a low cap and an expiry, and ask the vendor where the key is stored, whether it's encrypted, and what can decrypt it.

Building an agent that holds customer API keys and want the storage, caps and fallbacks right from day one?

Keep it on the server (environment variables or a secrets manager, never in client code or git), use one key per tool and project, create project keys with an expiration date, set a monthly spend limit with hard enforcement, and use IP allowlisting if your backend has fixed IPs. All of it is in OpenAI's key safety article as of October 2026.

Create a new key in the Claude Console with an expiration, deploy it everywhere the old one is used, confirm it works, then disable (reversible) or delete (permanent) the old key. Expiration is chosen at creation and can't be changed later.

No. An alert tells you money is being spent; it doesn't stop it. Use hard caps: OpenAI spend limits with hard enforcement, Anthropic workspace spend limits, Google AI Studio project spend caps. None are instant, but a cap turns an open-ended bill into a bounded one.

Only if you'd trust that vendor with your provider account, because that's what you're giving them. If you do, give the tool its own key in its own project or workspace, with a low cap and an expiry. Deleting the key inside the tool doesn't revoke it; only the provider can.

None of this is exciting, which is the point: the boring setup is what keeps a breach somebody else's headline instead of your invoice. If you want an AI product built that way from the start, here's how I work.

Originally published on joancomadran.dev. I'm Joan, an AI engineer in Barcelona — work with me.

Quelle: dev.to (dev.to). Original öffnen