Complete "Designing and Consuming APIs as Agent Tools" first to unlock this lesson.Go to previous lesson

Why Agents Need Authentication

When an AI agent calls an external service — a database, a third-party API, a cloud function — it must prove who it is. That proof comes in two common shapes: a static API key (a long random string the service issues to you once) or a short-lived token issued through OAuth 2.0 (a protocol where the agent exchanges credentials for a time-limited access token). Both serve the same purpose: the remote server checks the credential, then decides whether to honor the request.

The danger is not the credential itself — it is what happens when the credential leaks. A leaked API key in a chat log, an error trace, or a prompt sent to an LLM can be scraped and abused within minutes. Treating secrets as carefully as you would treat a production database password is the baseline expectation.

sơ đồ so sánh 2 luồng xác thực — API key tĩnh gắn liền mỗi request, và OAuth token được cấp qua handshake rồi dùng tạm thời

Where to Store Secrets

Never hard-code credentials in source files. Never paste them into a prompt template. The standard pattern is to load them from environment variables at runtime, so the secret lives in the deployment environment, not the codebase.

python
import os
import requests
api_key = os.environ["WEATHER_API_KEY"]
response = requests.get(
"https://api.weather.example.com/v1/current",
headers={"Authorization": f"Bearer {api_key}"}
)

In this snippet the key is read from the environment, attached as a Bearer token in the HTTP header, and never written to disk or logged. If the environment variable is missing, the agent should fail fast with a clear startup error — not silently fall back to a placeholder that masks the misconfiguration.

For local development, a `.env` file (a plain text file holding key=value pairs, excluded from version control via `.gitignore`) works well. For production, the orchestrator or secret manager injects the values. Either way, the rule is the same: secrets belong outside the code.

OAuth Tokens and Refresh Flow

Static keys are simple but inflexible. OAuth tokens are better when the agent acts on behalf of a user — for example, reading their calendar or posting to their account. The flow looks like this:

bash
# Step 1: agent receives an authorization code after user consent
# Step 2: exchange code for access token + refresh token
curl -X POST https://auth.example.com/oauth/token \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "client_id=AGENT_ID" \
-d "client_secret=AGENT_SECRET"
# Step 3: use the access token until it expires, then refresh

The agent should store the access token in memory only, and the refresh token in a secure store. When the access token expires (usually signaled by a 401 response), the agent silently swaps in a fresh one using the refresh token — the user never re-consents. Cramming the refresh logic into a small helper function keeps the calling code clean.

Avoiding Leaks in Prompts and Logs

The single most common credential leak in agent systems is accidental echo: the agent includes the secret inside a prompt it sends to the LLM, or a logger prints the full request including headers. Both are easy to prevent once you know to look.

python
def build_prompt(user_query: str, context: dict) -> str:
# Never inject credentials into the prompt
safe_context = {k: v for k, v in context.items() if not k.startswith("secret_")}
return f"Context: {safe_context}\nUser: {user_query}"
def safe_log_request(method, url, headers):
# Strip Authorization header before logging
redacted = {k: ("***" if k.lower() == "authorization" else v) for k, v in headers.items()}
print(f"{method} {url} headers={redacted}")

The first function filters out any context field whose name signals a secret. The second redacts the Authorization header before printing. Apply the same scrubbing to tracebacks, error reports, and any user-facing error message — if a stack trace contains a token, you have already lost.

Tổng kết

Three rules cover most of the surface area. First, load credentials from the environment, not from code or prompts. Second, prefer short-lived tokens over long-lived keys whenever the service supports OAuth, and refresh them automatically. Third, treat every log line, error message, and prompt as a potential leak vector — redact before you write. Following these three rules does not make a system bulletproof, but it closes the doors attackers actually walk through.

Lesson practice

Lesson Checkpoint

Review what you learned and get feedback on your work.

0/1
Answered · 0/1
Authentication, Tokens, and Secure Credential Handling