Access control
Allow, deny or rate-limit AI agents on your own site with the gateway’s access policy. Rules that name a platform are enforced with Web Bot Auth verification.
Last updated
Set a policy
Access control is off by default: with access unset, every agent is served as usual. Add a policy to the same GatewayConfig every adapter uses:
import type { GatewayConfig } from '@rebilder/gateway'
export const gatewayConfig: GatewayConfig = {
storeId: 'store_123',
sources: { /* … */ },
verification: { keys: myRegistry }, // required for platform-named rules
access: {
default: 'allow',
rules: [
{ subject: 'chatgpt', action: 'allow' },
{ subject: 'unverified', action: 'limit', limit: { requests: 60, windowSeconds: 60 } },
{ subject: '*', action: 'allow' },
],
},
}Subjects, most specific first
- A platform id (
chatgpt,claude,gemini,perplexityand the others in Classification) matches a verified agent of that platform. unverifiedmatches any agent that presented no verifiable identity.*matches every agent.- When nothing matches,
defaultapplies. It isallowunless you set it.
What a denied agent receives
- A denial answers
403, and a rate limit answers429withRetry-After, each with a small JSON body. - The policy runs before any source, protocol handler or rendering, so refusing a request costs less than serving one.
- Denied requests still emit an event on the
deniedpath, so your reports show the effect of the policy. See Events. - Search crawlers are not agents: Googlebot receives your canonical HTML even under
default: "deny".
Rate limits and policy updates
The rate limiter counts per process. Separate server or edge instances keep separate counts, so put a shared limiter upstream if you need one global cap.
access takes a policy or a synchronous getter; it is never fetched per request. To change the policy at runtime, fetch and verify it on your own schedule and have the getter return the latest one. Counters survive a policy swap.
import type { AccessPolicy, GatewayConfig } from '@rebilder/gateway'
let current: AccessPolicy = BOOT_POLICY
setInterval(async () => { current = await fetchAndVerifyPolicy() }, 300_000)
export const gatewayConfig: GatewayConfig = { /* … */, access: () => current }Validate where you edit the policy
compileAccessPolicy is exported so the screen where someone edits a policy can show which rules would be rejected, and why, before it is saved:
import { compileAccessPolicy } from '@rebilder/gateway'
const compiled = compileAccessPolicy(draft, { verificationConfigured: true })
// Show compiled.rejected to the person editing the policy before you save it.