Skip to content
← BlogDeveloper

How to authenticate an AI coding agent against the Norbelys API safely

Never hand a coding agent your production API key. A guide to scoped dev keys, auth.md, and why credential discipline matters more with an agent in the loop.

By Gabriel Lara, Developer Relations, Norbelys

Founder-reviewed ·How we research and correct articles

Before a coding agent writes a single line against the Norbelys API, it needs a credential — and the credential you hand it is the actual security boundary for everything that happens in that session. This guide is about getting that one decision right: which kind of credential to use while an AI agent is doing the calling, and why the answer isn’t “the same key you’d use yourself.”

The two ways to authenticate

Norbelys supports two authentication paths, and they’re built for different callers:

  • An org-scoped API key (ak_…), sent as Authorization: Bearer ak_…, for headless and CI callers — scripts, servers, and, relevantly here, the terminal session a coding agent is running in.
  • OAuth 2.1, discovered via the metadata at /.well-known/oauth-protected-resource, for interactive agents that can complete a consent flow — a chat client with a UI a human is watching in real time.

The full walkthrough of both, with the exact discovery and token flow, is published at norbelys.com/auth.md — written specifically for agents to read, not just developers. For a coding-agent session running in a terminal, doing local development, the API key is almost always the right path: there’s no human present to click through an OAuth consent screen for every tool call, and a key is the credential type CI, scripts, and terminal-driven sessions have always used.

Why this needs its own rule with an agent in the loop

A human developer typing curl commands has a mental firewall most of us don’t think about consciously: you don’t paste a production secret into a Slack message, you don’t commit a .env file, you glance at a diff before you push it. An AI coding agent doesn’t have that firewall by default — not because it’s careless, but because it optimizes for finishing the task in front of it, and printing a value to confirm “yes, the request went through” is often the fastest way to do that.

Concretely, a coding agent can expose a credential in ways a careful human wouldn’t, without any malicious intent anywhere in the chain:

  • It logs to move faster. A console.log(apiKey) “just to check it loaded” is a completely reasonable debugging step for anyone — human or agent — except the output ends up in a transcript, a terminal scrollback, or a screenshot you share to ask for help.
  • It writes convenience scripts. Asked to “quickly test this,” an agent may write a throwaway script with the key inline as a literal string rather than reading it from the environment, because that’s fewer moving parts for the immediate task.
  • Its context is persistent and shareable. A chat transcript, unlike a terminal session that scrolls away, is something you might paste into an issue, a support ticket, or hand to a teammate to continue the session — and a secret sitting in that transcript travels with it.

None of this requires the agent to do anything wrong. It requires the credential in scope to be one you can afford to have end up somewhere unintended — which is a property of which key you handed it, not of how carefully you supervise the session.

The practice: a scoped key for agent-assisted development

The discipline is simple to state and easy to skip under deadline pressure: create a separate API key exclusively for agent-assisted development, distinct from whatever key your production integration uses. That gives you three things a shared key can’t:

  1. A blast radius you can name. If it leaks, you know exactly which sessions were exposed and exactly what to revoke — nothing else in production is affected.
  2. A key you rotate freely. Because nothing production-critical depends on it, you can cycle it after every significant build session without coordinating a deploy.
  3. A trail that tells you what happened. Traffic from the dev key is unambiguously “something I was building,” which makes any anomaly easier to spot than sifting it out of your real send volume.

Setting this up before your next Claude Code or Cursor session

  1. Create a dedicated key

    Generate a new API key in the dashboard specifically for agent-assisted work — don't reuse the one wired into your production app or campaigns.

  2. Store it as an environment variable

    Export it in your shell (NORBELYS_API_KEY is the conventional name) rather than typing it into a prompt or a file. The agent reads the variable; it never needs to see the literal value.

  3. Tell the agent not to print it

    State this explicitly at the start of the session, and again if you notice a script it wrote reads the key directly instead of through the environment.

  4. Keep it out of anything committed

    Make sure .env or equivalent is in .gitignore before the agent starts writing files — a generated script that quietly writes its config to a tracked file is an easy thing to miss in a fast-moving session.

  5. Rotate it when the project's done

    Treat the key as scoped to the build, not to you personally. When the integration ships and starts using its own production key, retire the dev key rather than letting it live on indefinitely.

This isn’t about distrusting the agent

None of the above is a claim that coding agents are careless or that Claude Code specifically mishandles secrets. It’s a claim about surface area: a session where the agent reads files, writes files, runs commands, and produces a transcript you might share has more places for a value to end up than a session where a human alone types every command and never saves the scrollback. The right response isn’t “supervise the agent more closely” — attention is exactly the resource that doesn’t scale across a long session — it’s “make the credential in scope one that’s cheap to expose.” A scoped dev key achieves that by construction; watching every line an agent writes does not, and shouldn’t be the plan.

The same logic is why a well-built AGENTS.md states the rule outright rather than leaving it to be re-explained per session — see why Norbelys ships one for the broader case. If your own project’s agent guide doesn’t yet say “never load the production key into a coding-agent session,” that’s a one-line addition worth making before your next build, not after an incident makes it obvious in hindsight.

If you’re building something that runs unattended

A scoped API key is the right fit for development — a human is present, sessions are bounded, and you can rotate on a whim. If what you’re building will eventually run as a persistent, user-facing agent with nobody watching each call, that’s a different shape of problem, and OAuth 2.1’s consent flow is the more appropriate mechanism at that point; auth.md covers the discovery and token exchange for that path in full. For the day-to-day of writing and testing code with an agent at the keyboard, the discipline above — a scoped key, an environment variable, an explicit instruction — is the whole story.

Once your credential is sorted, the Claude Code integration guide walks a real build end to end, and the agent kit overview covers the context that makes that build go smoothly in the first place. For anyone issuing keys to agents at a larger scale than one developer’s laptop, scoping API keys to least privilege is the deeper treatment of the same principle.