rulesને બદલે actor contextથી શરૂઆત કેમ કરવી?
ઘણી ટીમો જ્યારે તેમની trafficમાં AI agents જોય છે, ત્યારે પહેલા rule તરફ દોડે છે. user agent block કરો, challenge ઉમેરો, rate limit કડક કરો. સમસ્યા એ છે કે traffic સમજી લેતાં પહેલાં લખાયેલો rule ઘણીવાર ખોટા લોકોને અસર કરે છે. legitimate assistants block થઈ જાય છે, real users challenge થાય છે, અને જે automation વિશે ખરેખર ચિંતા હતી તે ચાલુ જ રહે છે કારણ કે તેણે શરૂઆતમાં પોતાને ઓળખાવ્યું જ નથી.
Actor context rules પહેલાંનો પગલું છે. દરેક request માટે તમે નોંધો છો કે તમારી application act કરનાર વિશે શું observe કરી શકે: એક interactive person, AI assistant સાથે કામ કરતી person, એક autonomous agent, અથવા કંઈક જે હજી તમે અલગ કરી શકતા નથી. તમે આ view પાછળનો evidence record કરો છો, અને તેને requestના outcomeની બાજુમાં રાખો છો. એક-બે અઠવાડિયા પછી તમારી પાસે એવી વસ્તુ હશે જે કોઈ rule template આપી શકતું નથી: તમારા પોતાના trafficનો નકશો. જો તમે હજી નક્કી કરી રહ્યા છો કે agents ખરેખર તમારી site સુધી પહોંચે છે કે નહીં, તો website traffic AI agentsમાંથી આવે છે કે નહીં તે કેવી રીતે જણાવવુંથી શરૂઆત કરો.
આ guide plain middlewareનો ઉપયોગ કરીને Node.js applicationમાં તે layer બનાવે છે. તે Express સાથે કામ કરે છે, અને એ જ વિચારો Fastify, Koa, Hono અથવા Next.js route handler પર પણ લાગુ પડે છે.
તમે શું બનાવશો
અંત સુધીમાં તમારી પાસે હશે:
- દરેક requestમાંથી actor evidence કાઢતું middleware.
- દરેક result માટે જણાવાયેલા basis સાથેનું નાનું, સ્પષ્ટ classification.
- structured observation logs જે request કેવી રીતે handle થાય છે તે ક્યારેય બદલતા નથી.
- resultને request સાથે જોડવાનો રસ્તો, જેથી પછીના handlers તેને વાંચી શકે.
અહીં કંઈ પણ request block કરતું નથી. એ જાણબૂઝીને છે.
Step 1: તમારો server ખરેખર કયો evidence જોઈ શકે છે?
Server લોકો માનતા હોય તેના કરતાં ઓછું જુએ છે. code લખતા પહેલાં, તમારી edge પર ઉપલબ્ધ signalsની યાદી બનાવો:
- Request signatures. કેટલાક automated clients HTTP Message Signatures (RFC 9421)નો ઉપયોગ કરીને requests sign કરે છે,
Signature-InputઅનેSignatureheaders મોકલે છે, અને ઘણીવારSignature-Agentheader સાથે operatorની published keys તરફ સંકેત કરે છે, જેમ કે IETFના Web Bot Auth protocol draftમાં વર્ણવાયું છે. - Declared identity. Clients પોતાને
User-Agentheaderમાં,Fromheaderમાં, અથવા MCP client નામ જેવી protocol metadata મારફતે નામ આપી શકે છે. MCP clients 2025-11-25 revisionના initialize requestમાં પોતે પસંદ કરેલુંclientInfoનામ report કરે છે, અને 2026-07-28 revision client identityને per-request metadata તરીકે carry કરે છે. આ declarations છે, અને કોઈપણ તેને copy કરી શકે છે. - Authentication context. requestમાં session cookie, bearer token અથવા API key છે કે નહીં, અને તે કયા પ્રકારનું credential છે.
- Protocol shape. Accept headers, client HTML અથવા JSON માંગે છે કે નહીં, તે page assets લોડ કરે છે કે નહીં, અને redirects તથા cookiesને કેવી રીતે handle કરે છે.
- Application declarations. તમારું પોતાનું product network જાણી ન શકે તેવી બાબતો જાણતું હોઈ શકે છે, જેમ કે userનું "AI assisted" option પસંદ કરવું, અથવા request તમારા built-in assistant featureમાંથી આવવી.
દરેક signalની strength અલગ છે. validated signature તપાસી શકાય છે. user agent string એક claim છે. missing cookie ફક્ત missing છે. આ બધાને અલગ રાખવું એ આ exerciseનો મુખ્ય હેતુ છે.
Step 2: પરિણામને સ્પષ્ટ રીતે model કરો
Detection logic લખતા પહેલાં actor resultનું shape define કરો. નાનું, typed model દરેકને classificationનો અર્થ શું છે એ અંગે સાચું રાખે છે. અહીં વપરાતી ચાર classes Human, AI-assisted or agent: application traffic માટેનું practical taxonomyમાં સમજાવવામાં આવી છે.
export type ActorClass = "human" | "human_ai" | "agent" | "unknown";
export type EvidenceBasis = "verified" | "declared" | "inferred" | "unknown";
export interface ActorEvidence {
signaturePresent: boolean;
signatureAgent?: string;
declaredClient?: string;
credentialType: "session" | "api_key" | "bearer" | "none";
acceptsHtml: boolean;
appDeclaredAssist: boolean;
}
export interface ActorResult {
actor: ActorClass;
basis: EvidenceBasis;
reasons: string[];
evidence: ActorEvidence;
observedAt: string;
}બે fields સૌથી વધુ મહત્વના છે. actor class છે. basis તમે કેમ માન્યો છો તે કહે છે. validated signature પર આધારિત agent result અને user agent string પર આધારિત agent result બંને "agent" છે, પણ પછી તેમની સાથે અલગ રીતે વર્તવું જોઈએ, તેથી તેમને ક્યારેય એકમાં ભેળવશો નહીં.
Step 3: middlewareમાં evidence કાઢો
Extraction પગલું headers અને request state વાંચે છે. તે હજી કંઈ નક્કી કરતું નથી.
import type { Request, Response, NextFunction } from "express";
const KNOWN_AGENT_TOKENS = ["bot", "crawler", "spider", "agent", "gpt", "claude"];
export function extractEvidence(req: Request): ActorEvidence {
const ua = (req.get("user-agent") || "").toLowerCase();
const auth = req.get("authorization") || "";
const hasSession = Boolean(req.cookies?.session);
let credentialType: ActorEvidence["credentialType"] = "none";
if (hasSession) credentialType = "session";
else if (auth.toLowerCase().startsWith("bearer ")) credentialType = "bearer";
else if (req.get("x-api-key")) credentialType = "api_key";
const declaredToken = KNOWN_AGENT_TOKENS.find((t) => ua.includes(t));
return {
signaturePresent: Boolean(req.get("signature") && req.get("signature-input")),
signatureAgent: req.get("signature-agent") || undefined,
declaredClient: declaredToken ? ua.slice(0, 200) : undefined,
credentialType,
acceptsHtml: (req.get("accept") || "").includes("text/html"),
appDeclaredAssist: req.get("x-app-assist") === "1",
};
}આ code વિશે થોડાં નોંધો:
signaturePresentફક્ત એટલું નોંધે છે કે signature headers હાજર છે. Validation એક અલગ પગલું છે, જે signed agent requests verify કરવાની guideમાં આવરી લેવાયું છે.- user agent token list જાણબૂઝીને simple રાખવામાં આવી છે. તે declaration આપે છે, verification કદી નથી.
x-app-assistતમારા પોતાના frontend દ્વારા જ્યારે user built-in AI feature મારફતે કામ કરે ત્યારે જે કંઈ મોકલવામાં આવે છે તેના માટે placeholder છે. તેને તમારી real mechanismથી બદલો.
Step 4: જણાવાયેલા basis સાથે classify કરો
હવે evidenceને resultમાં ફેરવો. rules નાના રાખો, strongest evidenceથી weakest સુધી ક્રમબદ્ધ રાખો, અને હંમેશા Unknown પર આવીને અટકો.
export async function classify(
evidence: ActorEvidence,
verifySignature: () => Promise<boolean>,
): Promise<ActorResult> {
const reasons: string[] = [];
const observedAt = new Date().toISOString();
if (evidence.signaturePresent && (await verifySignature())) {
reasons.push("request signature validated");
return { actor: "agent", basis: "verified", reasons, evidence, observedAt };
}
if (evidence.appDeclaredAssist) {
reasons.push("application reported its built-in assistant");
return { actor: "human_ai", basis: "declared", reasons, evidence, observedAt };
}
if (evidence.declaredClient) {
reasons.push("client declared itself as automated");
return { actor: "agent", basis: "declared", reasons, evidence, observedAt };
}
if (evidence.credentialType === "session" && evidence.acceptsHtml) {
reasons.push("interactive browser session");
return { actor: "human", basis: "inferred", reasons, evidence, observedAt };
}
reasons.push("insufficient evidence");
return { actor: "unknown", basis: "unknown", reasons, evidence, observedAt };
}આ શું નથી કરતી તે નોંધો. તે declarationને verificationમાં ક્યારેય upgrade કરતી નથી. તે કોઈ interactive signal ન ધરાવતી requestને Human આપતી નથી. જ્યારે તે નક્કી ન કરી શકે, ત્યારે Unknown કહે છે. Unknown એક માન્ય, ઉપયોગી જવાબ છે, અને તે તમને સ્પષ્ટ બતાવે છે કે તમારી visibility ક્યાં પૂરી થાય છે. આ સમગ્ર મુદ્દો અમે AI traffic માટે Unknown valid result કેમ છેમાં સમજાવીએ છીએ.
Step 5: તેને observation modeમાં wire કરો
Middleware વહેલું mount કરો, resultને request સાથે attach કરો, અને તેને log કરો. તેના આધારે branch ન કરો.
import express from "express";
import cookieParser from "cookie-parser";
const app = express();
app.use(cookieParser());
app.use(async (req, res, next) => {
try {
const evidence = extractEvidence(req);
const result = await classify(evidence, async () => false);
res.locals.actor = result;
res.on("finish", () => {
logActor({
route: req.route?.path ?? req.path,
method: req.method,
status: res.statusCode,
actor: result.actor,
basis: result.basis,
reasons: result.reasons,
});
});
} catch {
res.locals.actor = undefined;
}
next();
});આને safe બનાવતી ત્રણ વિગતો છે:
tryblock ખાતરી કરે છે કે detectionમાં failure ક્યારેય responseને અસર ન કરે. Observation fail open હોવી જોઈએ.- Logging
finishપર થાય છે, તેથી તમે સાચો status code capture કરો છો અને પછી classificationsને outcomes સાથે સરખાવી શકો છો. verifySignatureનેfalseતરીકે stub કરવામાં આવ્યું છે ત્યાં સુધી તમે real validation implement ન કરો. આ signed requestsને declared અથવા unknown bucketsમાં જ રાખે છે, વધારે દર્શાવ્યા વગર.
Step 6: ફક્ત debugging નહીં, analysis માટે log કરો
એવા logs લખો જેને તમે aggregate કરી શકો. દરેક request માટે એક structured line પૂરતી છે.
function logActor(entry: Record<string, unknown>) {
process.stdout.write(JSON.stringify({ type: "actor_observation", ...entry }) + "\n");
}આ logsમાંથી personal data દૂર રાખો. તમને route, class, basis, reasons અને outcome જોઈએ. તમારા traffic mixને સમજવા માટે તમને પૂરાં IP addresses, raw cookies અથવા request bodiesની જરૂર નથી. જો correlation માટે કોઈ identifier રાખો, તો તેને rotating salt સાથે hash કરો અને ટૂંકી retention period નક્કી કરો.
Step 7: act કરતા પહેલાં data વાંચો
Normal weekly patterns જોવા પૂરતો સમય observation modeમાં ચલાવો. પછી થોડાં પ્રશ્નોના જવાબ આપો:
- કયા routes પર agents વધારે આવે છે? Documentation, catalog અને search endpoints સામાન્ય રીતે આવે છે. Account અને checkout flows સામાન્ય રીતે ન આવવા જોઈએ.
- agent resultsમાં verified અને declaredનો હિસ્સો કેટલો છે? આ ratio તમને policies લખતી વખતે identity પર તમે કેટલો સુરક્ષિત રીતે આધાર રાખી શકો તે જણાવે છે.
- Unknown ક્યાં કેન્દ્રિત છે? કોઈ route પર Unknown rate ઊંચો હોય તો ઘણીવાર તેનો અર્થ થાય છે કે ત્યાં signal ખૂટે છે, જેમ કે એવું page જે ક્યારેય તમારો frontend code ચલાવતું નથી.
- શું outcomes class પ્રમાણે અલગ છે? Error rates, conversion steps અથવા abuse reports classesમાં સરખાવો. અહીંથી જ real policy ideas આવે છે.
જવાબો ઘણી વાર આશ્ચર્યજનક હશે. ટીમો નિયમિત રીતે શોધે છે કે તેમનો "bot problem"નો મોટો ભાગ વાસ્તવમાં legitimate automation હોય છે, જે જો structured endpoint હોત તો ખુશીથી તેનો ઉપયોગ કરત.
Step 8: પરિણામને તમારી appના બાકી ભાગ માટે ખુલ્લું કરો
એક વખત data વહેવાનું શરૂ થાય, ત્યારે non-enforcing ઉપયોગો માટે handlersને res.locals.actor વાંચવા દો: analytics tags, response format પસંદ કરવું, અથવા નોંધવું કે support ticket AI-assisted sessionમાંથી આવ્યો હતો. આવા ઉપયોગો કોઈને lock out થવાનો જોખમ લીધા વિના અનુભવ સુધારે છે.
app.get("/docs/:page", (req, res) => {
const actor = res.locals.actor as ActorResult | undefined;
if (actor?.actor === "agent" && req.accepts("text/markdown")) {
return res.type("text/markdown").send(renderMarkdown(req.params.page));
}
return res.render("doc", { page: req.params.page });
});Enforcement, જેમ કે challenges, rate limits અથવા step-up checks, પછી આવે છે, તમે false positives માપી લીધા પછી. actor-aware policies rollout કરવાની guide તે પ્રક્રિયાને આવરી લે છે.
કઈ ભૂલો ટાળવી જોઈએ?
- user agentને identity માનવી. આ બદલવા માટેનું સૌથી સરળ header છે. તેને declaration તરીકે નોંધો. AI operators પણ એવું જ કહે છે: Anthropicની તેના hosted browser agent માટેની guidance નોંધે છે કે કોઈપણ એ જ User-Agent header મોકલી શકે છે અને trafficને genuine માનતા પહેલાં તેના published IP addresses તપાસવાની ભલામણ કરે છે.
- ડિફોલ્ટ Human પર જવું. જો તમારો code bot signals ન મળે ત્યારે Human કહે છે, તો તમારા Human numbers inflate થશે અને તમારી policies ખોટા traffic પર વિશ્વાસ કરશે.
- class અને basisને ભેળવવું. હંમેશાં બંને સંગ્રહો. ફક્ત "Agent" બતાવતું dashboard verified operator અને copied string વચ્ચેનો ફરક છુપાવે છે.
- observation દરમિયાન blocking કરવું. તાત્કાલિક block પણ તમારી measurementsને અમાન્ય બનાવે છે, કારણ કે blocked clients પોતાનું વર્તન બદલે છે.
Proof of Actor ક્યાં બંધબેસે છે
ઉપરનું middleware એક મજબૂત શરૂઆત છે, અને તે core model બતાવે છે: પહેલા evidence, દરેક result માટે સ્પષ્ટ basis, Unknown દેખાતું રાખવું, અને નિર્ણયો તમારી application પર છોડવા. Proof of Actor એ જ model પર વધુ ઊંડા signal coverage સાથે બનેલું છે, server, edge, browser અને MCP contextsમાં, અને એવી analytics સાથે જે તમને વિશ્વાસપૂર્વક Detect, Understand અને Route કરવા દે છે.
જો તમે production app પર આને આગળ વધારવામાં મદદ ઇચ્છો, તો early access માટે apply કરો. સંપૂર્ણ decision flow જોવા માટે Proof of Actor કેવી રીતે કામ કરે છે વાંચો.
Sources
- RFC 9421: HTTP Message Signatures: signed requests પાછળનો standard
- draft-ietf-webbotauth-httpsig-protocol: IETF Web Bot Auth draft જે
Signature-Agentheader define કરે છે (November 2026 સુધી work in progress) - RFC 9110: HTTP Semantics, User-Agent and From: self-reported client identification headers
- MCP specification 2025-11-25: Lifecycle:
initializerequest અનેclientInfo - MCP specification 2026-07-28: Versioning and Compatibility: per-request version, identity અને capability metadata
- Anthropic: how Anthropic-hosted browsers identify themselves: user agent token, published IP addresses અને header copy કરી શકાય છે એવી ચેતવણી