Ga naar hoofdinhoud
GIDS

Hoe u gevoelige acties beschermt zonder legitieme agents te blokkeren

Een praktisch model om accountwijzigingen en operaties met hoge impact veilig te houden, terwijl legitieme geautomatiseerde clients nuttig werk in uw app blijven doen.

Toshendra Sharma

Door Toshendra SharmaOprichter & CEO, AgentCredia · Updated November 13, 2026

Geavanceerd · 10 min leestijd

Waarom niet gewoon agents blokkeren voor gevoelige acties?

Sommige acties in uw applicatie zijn belangrijker dan andere. Een wachtwoord wijzigen, een teamlid toevoegen, data exporteren, een project verwijderen, een order goedkeuren: als een van deze acties gebeurt zonder de juiste bevoegdheid, is de schade reëel.

Tegelijkertijd wordt steeds meer legitiem werk in uw app uitgevoerd door automatisering. Een gebruiker vraagt een assistent om zijn instellingen bij te werken. Een partnerintegratie maakt volgens een schema records aan. Een interne agent dient supporttickets in. Elke geautomatiseerde client blokkeren van gevoelige routes breekt dat werk en duwt mensen terug naar handmatig werk of naar omwegen die moeilijker te beveiligen zijn.

Het antwoord is niet "agents blokkeren" of "agents vertrouwen". Het is een model waarin het risico van de actie, de bevoegdheid achter het verzoek en het bewijs over de actor elk een eigen rol spelen. Deze gids bouwt dat model op. Voor de bredere gedachte erachter, zie beleid op app-niveau ontwerpen voor mensen en AI-agents.

Stap 1: Deel uw routes in op risico

Begin met het classificeren van acties, niet van clients. Een eenvoudig schema met drie niveaus werkt voor de meeste applicaties:

Niveau Voorbeelden Standaardvereiste
Laag Openbare data lezen, zoeken, eigen dashboard bekijken Normale authenticatie, als die er is
Middel Eigen content aanmaken of bewerken, een viewer uitnodigen Geauthenticeerd, geautoriseerd voor het object
Hoog Credentials wijzigen, eigenaarschap wijzigen, bulkexport, verwijderen, goedkeuren Geautoriseerd plus step-up of review

Leg het niveau vast in de routeconfiguratie, zodat het zichtbaar is in code review:

TS
type Tier = "low" | "medium" | "high";

export const routeTier: Record<string, Tier> = {
  "GET /projects": "low",
  "POST /projects": "medium",
  "POST /projects/:id/members": "medium",
  "POST /account/password": "high",
  "POST /exports": "high",
  "DELETE /projects/:id": "high",
};

Niveaus veranderen langzaam en zijn eenvoudig te beredeneren. Alles in deze gids hangt ervan af.

Stap 2: Hoe verschillen identiteit, credentials en autorisatie?

Drie vragen worden vaak door elkaar gehaald:

  1. Wie of wat handelt? Dit is actor-evidence: een interactieve persoon, een persoon met AI-ondersteuning, een agent of Unknown, met een basis zoals Verified of Declared.
  2. Welke credential is aangeboden? Een sessiecookie, een API key, een OAuth access token.
  3. Mag deze credential deze actie op dit object uitvoeren? Dit is autorisatie.

Een geverifieerde agentsignatuur (RFC 9421) beantwoordt de eerste vraag goed. Het zegt niets over de derde vraag, een punt dat uitgebreid wordt behandeld in wat ondertekende AI-agentverzoeken bewijzen, en wat niet. Een OAuth token met de juiste scope beantwoordt de derde vraag. Het zegt weinig over de eerste. Uw beslissing voor een actie op hoog niveau heeft altijd een goed antwoord op de derde vraag nodig, en gebruikt de eerste om te bepalen hoeveel extra zekerheid u moet vragen.

TS
interface Context {
  actor: { actor: "human" | "human_ai" | "agent" | "unknown"; basis: "verified" | "declared" | "inferred" | "unknown" };
  credential: { type: "session" | "oauth" | "api_key"; scopes: string[]; subject: string };
}

function authorized(ctx: Context, action: string, resourceOwner: string): boolean {
  return ctx.credential.subject === resourceOwner && ctx.credential.scopes.includes(action);
}

Autorisatie wordt nooit versoepeld vanwege een gunstig actorresultaat. Actor-context voegt alleen vereisten toe of kiest tussen even veilige paden.

Stap 3: Gebruik gedelegeerde bevoegdheid voor agents die namens mensen handelen

Wanneer een agent namens een gebruiker handelt, geef het dan een eigen credential met beperkte bevoegdheid in plaats van het de sessie van de gebruiker te laten hergebruiken. OAuth 2.0 is de standaardtool: de gebruiker keurt specifieke scopes goed voor een specifieke client, en het token legt die client vast. RFC 9700, de OAuth 2.0 Security Best Current Practice, beschrijft hoe u dit veilig implementeert. MCP servers volgen hetzelfde patroon: de MCP authorization specification behandelt een beveiligde MCP server als een OAuth 2.1 resource server. Onze post wie roept uw MCP server aan? past dit toe op tool calls.

Dit levert precies op wat u nodig hebt voor gevoelige acties:

  • Het token vertelt u welke client handelt en namens wie.
  • Scopes begrenzen wat het kan doen. Een planningsagent met calendar:write kan geen wachtwoord wijzigen.
  • De gebruiker kan de grant intrekken zonder zijn eigen credentials te wijzigen, en OAuth 2.0 Token Revocation (RFC 7009) definieert hoe een client aan de authorization server meldt dat een token niet langer geldig mag zijn.
  • Auditlogs laten zien dat de agent, niet de gebruiker, de actie heeft uitgevoerd.

Als uw app gedelegeerde credentials nog niet ondersteunt, geef hier prioriteit aan voor de acties die agents het vaakst nodig hebben. Dit is de meest effectieve controle voor geautomatiseerde toegang.

Stap 4: Wanneer moet u om een step-up check vragen?

Step-up betekent dat u extra zekerheid vraagt op het moment van een gevoelige actie. Voor met OAuth beveiligde APIs definieert RFC 9470 hoe een resource server een client laat weten dat het huidige token qua authenticatie niet sterk genoeg of niet recent genoeg is. De juiste step-up hangt af van wie handelt:

  • Interactieve persoon (Human, Human + AI): re-authenticatie (zie de reauthentication requirements in NIST SP 800-63B), een passkey-prompt op basis van WebAuthn, of een eenmalige code.
  • Agent met gedelegeerde credential: een scope die is bedoeld voor de actie op hoog niveau, expliciet toegekend door de gebruiker, of een bevestiging die buiten de bandbreedte om naar de gebruiker wordt gestuurd.
  • Unknown: de bestaande sterke check van de route, ongewijzigd.
TS
type Requirement = "none" | "reauth" | "explicit_scope" | "user_confirmation" | "review";

function stepUp(tier: Tier, ctx: Context): Requirement {
  if (tier !== "high") return "none";
  const { actor } = ctx.actor;
  if (actor === "human" || actor === "human_ai") return "reauth";
  if (actor === "agent" && ctx.credential.type === "oauth") return "explicit_scope";
  if (actor === "agent") return "user_confirmation";
  return "reauth";
}

Merk op dat een Human-resultaat step-up niet overslaat. Het selecteert de step-up die past bij een interactieve persoon. Inferences kunnen onjuist zijn, dus ze moeten de vorm van de check veranderen, niet de check verwijderen.

Stap 5: Routeer naar menselijke review waar oordeel nodig is

Sommige acties zijn zeldzaam, hebben veel impact en zijn moeilijk veilig te automatiseren: bulkexports van klantdata, account recovery na verloren credentials, of het verwijderen van een organisatie. Voor deze gevallen is een reviewqueue vaak beter dan welke geautomatiseerde regel ook.

Actor-context maakt review sneller en eerlijker door de reviewer het bewijs te geven: de klasse, de basis, de gebruikte credential, de historie van vergelijkbare verzoeken. De reviewer beslist. De classificatie geeft richting.

TS
function shouldReview(route: string, ctx: Context): boolean {
  const reviewRoutes = new Set(["POST /exports", "POST /account/recover"]);
  if (!reviewRoutes.has(route)) return false;
  return !(ctx.credential.type === "oauth" && ctx.credential.scopes.includes("export:bulk"));
}

Stap 6: Kies per niveau hoe fouten zich gedragen

Actor-evaluatie kan time-outen of aan bewijs ontbreken. Bepaal vooraf wat er dan gebeurt.

  • Laag niveau: fail open. Het verzoek wordt normaal voortgezet.
  • Middel niveau: fail open, met normale autorisatie op zijn plaats.
  • Hoog niveau: fail closed naar de bestaande sterke check. Ontbrekend actorbewijs verzwakt de bescherming nooit, en blokkeert ook nooit een verzoek dat anders wel door uw normale checks zou zijn gekomen.

De sleutel is symmetrie. Een fout in actor-evaluatie moet de actie precies even veilig, en precies even beschikbaar, laten als vóór u actor-context toevoegde.

Stap 7: Neem geen verstrekkende beslissingen over mensen op basis van inferences

Een inferred classificatie is bewijs over een interactie, niet over een persoon. Weiger iemand geen sollicitatie, kredietbeslissing, examenuitslag, huisvesting of toegang tot een essentiële dienst omdat een sessie geautomatiseerd of AI-ondersteund leek. Gebruik in die processen actor-context om een proces te kiezen, zoals menselijke review of een alternatief verificatiepad, en zorg dat de persoon het kan afronden.

Dit is zowel een eerlijkheidsprincipe als een praktisch principe. Inferences hebben false positives, en de kosten van een false positive in deze processen komen terecht bij iemand die niets verkeerd heeft gedaan.

Stap 8: Rol uit met observation first

Voordat iets hiervan echte verzoeken beïnvloedt, laat u het draaien in observation en preview mode:

  1. Leg niveau, actor class, basis, credential type en de step-up vast die uw beleid zou vereisen.
  2. Bekijk samples van verzoeken op hoog niveau per klasse. Gebruiken legitieme agents gedelegeerde credentials, of hergebruiken ze gebruikerssessies?
  3. Los de hiaten die u vindt op, vaak door scoped credentials aan te bieden, voordat u gaat enforcen.
  4. Enforce op een klein deel van één route, meet completion rates, en breid daarna uit.

Stap 9: Houd een audit trail bij die "wie en namens wie" beantwoordt

Leg voor elke actie op hoog niveau genoeg vast om later te reconstrueren wat er gebeurde:

  • de actor class en basis op het moment van het verzoek,
  • het type credential, de client waaraan die is uitgegeven en het subject dat die vertegenwoordigt (OAuth 2.0 Token Exchange, RFC 8693, definieert een act claim om precies dit soort "handelt namens"-relatie vast te leggen),
  • de scopes die de actie hebben geautoriseerd,
  • de toegepaste step-up of reviewvereiste en het resultaat daarvan.
TS
audit.write({
  action: "project.export",
  actor: ctx.actor,
  client: ctx.credential.type === "oauth" ? clientIdFromToken(req) : undefined,
  subject: ctx.credential.subject,
  scopes: ctx.credential.scopes,
  requirement,
  outcome: "approved",
  at: new Date().toISOString(),
});

Met dit spoor heeft een vraag als "heeft een persoon of een assistent dit project verwijderd, en wie heeft dat goedgekeurd" een duidelijk antwoord. Dat maakt incident response sneller en geeft gebruikers vertrouwen dat geautomatiseerde hulp in uw app aantoonbaar is.

Een uitgewerkt voorbeeld

Een projectmanagementapp ziet een assistent die vervaldatums van taken voor gebruikers bijwerkt en af en toe probeert volledige projecten te exporteren.

  • Een taak bijwerken is middel niveau. De assistent gebruikt een OAuth token met tasks:write. Geautoriseerd, geen step-up. Toegestaan.
  • Een project exporteren is hoog niveau. Het token van de assistent mist export:bulk. De app stuurt de gebruiker een bevestigingsverzoek. De gebruiker keurt goed, en de app geeft de scope voor die client vrij.
  • Een Unknown client probeert dezelfde export met een hergebruikte sessiecookie. De bestaande re-authenticatieprompt wordt toegepast, precies zoals voorheen.

Niemand werd geblokkeerd omdat het een agent was. Elke actie met hoge impact had expliciete bevoegdheid.

Waar Proof of Actor past

Proof of Actor levert de actorzijde van dit model: wie of wat handelt en op welke basis. Uw applicatie houdt de authenticatie, autorisatie en de eindbeslissing. Detecteer de actor, Understand hoe elke klasse uw gevoelige routes gebruikt, en Route elk verzoek naar het juiste niveau van zekerheid.

Om dit voor uw applicatie samen met ons team te ontwerpen, meld u aan voor vroege toegang. Voor SaaS-scenario's in meer detail, zie SaaS Apps & Websites.

Bronnen

Bouw het met ons.

Sluit u aan bij het Proof of Actor founding developer program.

Eerst liever even praten? Spreek met de oprichters