In the previous chapter, Security & Permission Guardrails, we built a "Border Control" agent. This agent stops the AI from visiting any website unless the user says "Yes."
While this is safe, it can be annoying. Imagine if you had to show your passport every time you walked into your own kitchen!
The Use Case: You are a developer asking the AI to help you write Python code. The AI needs to check the official Python documentation five times in one hour.
docs.python.org instantly, but still asks permission for unknown blogs.We solve this using a Preapproved Domain List.
Think of this like the "TSA Pre-Check" or "Global Entry" lane at an airport.
We don't let just anyone into the fast lane. The list in preapproved.ts is carefully curated. It consists almost entirely of Documentation and Reference sites.
Here is a snippet of what the list looks like in code:
// preapproved.ts
export const PREAPPROVED_HOSTS = new Set([
'docs.python.org', // Python Documentation
'react.dev', // React Documentation
'developer.mozilla.org', // MDN Web Docs
'stackoverflow.com', // Coding answers
'npmjs.com', // Node packages
// ... many others
])
Why these sites?
When the WebFetchTool wants to visit a URL, it runs a quick check before bothering the user.
Let's look at how we implement this in preapproved.ts. We need a system that is fast (O(1) lookup) and handles tricky paths.
For 99% of cases, we just want to match the domain name (like google.com).
We optimize this by splitting our list into two buckets. The first bucket is for simple domains.
// preapproved.ts (Simplified logic)
// 1. Exact matches only
const HOSTNAME_ONLY = new Set([
'react.dev',
'docs.python.org',
'en.cppreference.com'
])
When a request comes in, we check this set first.
Sometimes, a domain is too big to trust completely.
Take GitHub.
github.com/anthropics (The makers of Claude) -> Safe/Trusted.github.com/random-hacker/malware -> Not Trusted.
We cannot simply allow github.com. We need to allow specific folders (paths) on that domain.
// preapproved.ts
// 2. Domains where we only trust specific sub-folders
const PATH_PREFIXES = new Map()
// We map "github.com" to specific allowed paths
PATH_PREFIXES.set('github.com', [
'/anthropics', // Allow Anthropic's code
'/microsoft' // Allow Microsoft's code
])
isPreapprovedHost Function
Now we combine these two checks into one main function. This is the function the WebFetchTool calls.
First, we check the simple list:
export function isPreapprovedHost(hostname: string, pathname: string): boolean {
// 1. Fast check: Is the exact hostname in our safe list?
if (HOSTNAME_ONLY.has(hostname)) {
return true
}
// ... continued below
If that fails, we check if the domain has specific path rules:
// 2. Check if this host has specific path restrictions
const prefixes = PATH_PREFIXES.get(hostname)
if (prefixes) {
for (const p of prefixes) {
// Check if the URL starts with the allowed path
if (pathname === p || pathname.startsWith(p + '/')) {
return true
}
}
}
return false
}
Beginner Explanation:
hostname ("github.com") and pathname ("/anthropics/project")./anthropics/project starts with /anthropics.true (Allowed).You might wonder: "If we trust these domains, why can't the AI do anything it wants there?"
We only allow Fetching (reading). We do not inherently allow sending data.
Some trusted domains, like kaggle.com or huggingface.co, allow users to upload files. If we gave the AI unrestricted access, a bad actor could trick the AI into:
By restricting the WebFetchTool to simple GET requests (downloading only) and using this list, we prevent data exfiltration.
Back in Security & Permission Guardrails, we saw checkPermissions. Now we understand exactly what happens in that first few lines of code:
// WebFetchTool.ts
async checkPermissions(input, context) {
const { url } = input
const parsedUrl = new URL(url)
// This calls the function we just wrote!
if (isPreapprovedHost(parsedUrl.hostname, parsedUrl.pathname)) {
return {
behavior: 'allow', // Instant access!
decisionReason: { type: 'other', reason: 'Preapproved host' },
}
}
// ... otherwise ask user
}
In this chapter, we improved the user experience significantly by creating a "Fast Lane" for trusted documentation sites.
react.dev) and complex paths (github.com/anthropics).Now the AI can browse documentation as fast as it can "think," without bothering you.
But what if the AI needs to check the same documentation page twice in one minute? Downloading the page again is slow and wasteful.
In the next chapter, we will give the tool a "Short-Term Memory" so it remembers what it just read.
Generated by Code IQ