नियमांऐवजी actor context ने सुरुवात का करावी?
तुमच्या trafficमध्ये AI agents दिसू लागल्यावर बहुतेक टीम्स थेट नियमाकडे वळतात. user agent block करा, challenge जोडा, rate limit कडक करा. समस्या अशी की traffic समजण्यापूर्वी लिहिलेला नियम अनेकदा चुकीच्या लोकांवर परिणाम करतो. वैध assistants block होतात, खरे users challenge होतात, आणि प्रत्यक्षात चिंतेचा विषय असलेली automation पुढे चालूच राहते कारण तिने स्वतःची ओळख सुरुवातीलाच दिलेली नसते.
Actor context ही rulesच्या आधीची पायरी आहे. प्रत्येक request साठी, तुमचे application कोण किंवा काय कृती करत आहे याबद्दल काय observe करू शकते ते नोंदवा: एक interactive व्यक्ती, AI assistantसोबत काम करणारी व्यक्ती, autonomous agent, किंवा सध्या वेगळे ओळखता न येणारे काहीतरी. त्या viewमागील evidence नोंदवा, आणि ते 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 वापरून request sign करतात (RFC 9421), आणि
Signature-InputतसेचSignatureheaders पाठवतात, अनेकदाSignature-Agentheaderसोबत, जो operatorच्या प्रकाशित keysकडे निर्देश करतो, असे IETF Web Bot Auth protocol draft मध्ये वर्णन केले आहे. - Declared identity. Clients स्वतःचे नाव
User-Agentheaderमध्ये,Fromheaderमध्ये, किंवा protocol metadataद्वारे देऊ शकतात, जसे MCP client name. MCP clients 2025-11-25 revisionच्या initialize request मध्ये self-chosenclientInfoname report करतात, आणि 2026-07-28 revisionमध्ये client identity per-request metadata म्हणून येते. ही घोषणाआहेत, आणि कोणीही ती copy करू शकते. - Authentication context. Requestमध्ये session cookie, bearer token किंवा API key आहे का, आणि credentialचा प्रकार कोणता आहे.
- Protocol shape. Accept headers, client HTML की JSON मागतो का, तो page assets load करतो का, आणि redirects तसेच cookies कसे हाताळतो.
- Application declarations. तुमच्या स्वतःच्या productला networkला न दिसणाऱ्या गोष्टी माहीत असू शकतात, जसे userने "AI assisted" पर्याय निवडणे, किंवा request तुमच्या built-in assistant featureमधून येणे.
प्रत्येक signalची ताकद वेगळी असते. 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: a practical taxonomy for application traffic मध्ये समजावले आहेत.
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 step 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 मुद्दाम साधी ठेवली आहे. ती declaration तयार करते, verification नाही.
x-app-assistतुमच्या स्वतःच्या frontendने user built-in AI featureमधून काम करत असताना जे काही पाठवते त्यासाठी placeholder आहे. ते तुमच्या प्रत्यक्ष mechanismने बदला.
Step 4: स्पष्ट basisसह वर्गीकरण करा
आता evidenceला resultमध्ये बदला. नियम छोटे ठेवा, 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 हा वैध result का आहे याचा संपूर्ण मुद्दा आम्ही Unknown हा AI trafficसाठी वैध result का आहे मध्ये मांडतो.
Step 5: Observation modeमध्ये ते जोडा
Middleware लवकर mount करा, result requestला जोडा, आणि ते 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();
});ही व्यवस्था सुरक्षित ठेवणाऱ्या तीन गोष्टी:
tryblock हमी देतो की detectionमध्ये अपयश आले तरी responseवर परिणाम होत नाही. Observation नेहमी fail open असले पाहिजे.- Logging
finishवर होते, त्यामुळे तुम्ही खरी status code capture करता आणि नंतर classificationsची outcomesशी तुलना करू शकता. verifySignatureतुम्ही वास्तविक validation implement करेपर्यंतfalseम्हणून stub केले आहे. त्यामुळे signed requests overstating न होता declared किंवा unknown bucketsमध्ये राहतात.
Step 6: फक्त debuggingसाठी नाही, analysisसाठी log करा
एकत्रित करता येतील असे logs लिहा. प्रत्येक 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 कालावधी लहान ठेवा.
Step 7: कृती करण्यापूर्वी data वाचा
सामान्य साप्ताहिक pattern दिसेल इतका वेळ observation modeमध्ये चालू ठेवा. मग काही प्रश्नांची उत्तरे द्या:
- कोणते routes agentsना आकर्षित करतात? Documentation, catalog आणि search endpoints सहसा तसे करतात. Account आणि checkout flows सहसा करू नयेत.
- Agent resultsपैकी verified आणि declared यांचा वाटा किती? Policy लिहिताना identityवर तुम्ही कितपत सुरक्षितपणे अवलंबून राहू शकता ते हे प्रमाण सांगते.
- Unknown कुठे केंद्रित आहे? एखाद्या routeवर Unknown rate जास्त असेल तर तिथे signal कमी पडत आहे, उदाहरणार्थ असा page जो तुमचा frontend code कधीच चालवत नाही.
- Classनुसार outcomes वेगळे आहेत का? Error rates, conversion steps किंवा abuse reports classesमध्ये तुलना करा. इथूनच खऱ्या policy कल्पना येतात.
उत्तरं अनेकदा आश्चर्यकारक ठरतात. Teamsना वारंवार आढळते की त्यांच्या "bot problem"चा मोठा भाग प्रत्यक्षात वैध 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 });
});Challenge, rate limits किंवा step-up checksसारखी enforcement नंतर येते, false positives मोजल्यानंतर. Actor-aware policies roll out करण्याच्या guideमध्ये ती प्रक्रिया कव्हर केली आहे.
कोणत्या चुका टाळाव्यात?
- User agentला identity मानणे. तो बदलायला सर्वात सोपा header आहे. त्याला declaration म्हणून नोंदवा. AI operatorsही तसेच सांगतात: Anthropicच्या its hosted browser agentसाठीच्या guidance मध्ये नमूद आहे की कोणीही तोच User-Agent header पाठवू शकतो आणि traffic genuine मानण्यापूर्वी त्यांचे प्रकाशित IP addresses तपासण्याची शिफारस केली आहे.
- Default Humanवर जाणे. तुमचा code bot signals सापडले नाहीत म्हणून नेहमी Human म्हणत असेल, तर तुमचे Human numbers वाढलेले दिसतील आणि policies चुकीच्या trafficवर विश्वास ठेवतील.
- Class आणि basis मिसळणे. दोन्ही नेहमी साठवा. फक्त "Agent" दाखवणारे dashboard verified operator आणि copied string यांमधला फरक लपवते.
- Observationदरम्यान block करणे. तात्पुरता block सुद्धा तुमची measurements अवैध करतो, कारण blocked clients त्यांचे वर्तन बदलतात.
Proof of Actor कुठे बसते
वरील middleware एक मजबूत सुरुवात आहे, आणि ते core model दाखवते: आधी evidence, प्रत्येक resultसाठी स्पष्ट basis, Unknown visible ठेवलेले, आणि निर्णय तुमच्या applicationकडे सोपवलेले. Proof of Actor हाच model पुढे नेते, server, edge, browser आणि MCP contextsमध्ये अधिक सखोल signal coverageसह, तसेच analyticsसह जे तुम्हाला Detect, Understand आणि Route आत्मविश्वासाने करू देतात.
जर production appवर हे पुढे नेण्यासाठी मदत हवी असेल, तर early accessसाठी अर्ज करा. संपूर्ण decision flow पाहण्यासाठी, Proof of Actor कसे काम करते वाचा.
स्रोत
- RFC 9421: HTTP Message Signatures: signed requestsमागील standard
- draft-ietf-webbotauth-httpsig-protocol:
Signature-Agentheader define करणारा IETF Web Bot Auth draft (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: Anthropic-hosted browsers स्वतःची ओळख कशी देतात: user agent token, published IP addresses आणि header copy केला जाऊ शकतो हा इशारा