Allowlist vs. Blocklist (Warum Default-Deny gewinnt) + Code

Blocklists verrotten. Allowlists skalieren. Ein Tool-Policy-Modell, das nicht aus Versehen das nächste gefährliche Tool erlaubt.
Auf dieser Seite
  1. Problem (aus der Praxis)
  2. Warum das in Production bricht
  3. 1) Du kannst „alle gefährlichen Tools“ nicht vorab aufzählen
  4. 2) Blocklists scheitern an Naming und Indirection
  5. 3) Default-Allow lässt Blast Radius leise wachsen
  6. 4) Allowlists erzwingen eine explizite Entscheidung
  7. Implementierungsbeispiel (echter Code)
  8. Echter Incident (mit Zahlen)
  9. Abwägungen
  10. Wann du es NICHT nutzen solltest
  11. Checkliste (Copy/Paste)
  12. Sicheres Default-Config-Snippet (JSON/YAML)
  13. FAQ (3–5)
  14. Verwandte Seiten (3–6 Links)
Interaktiver Ablauf
Szenario:
Schritt 1/3: Execution

Action is proposed as structured data (tool + args).

Problem (aus der Praxis)

Du fängst mit einer Blocklist an, weil’s schnell geht: „Wir verbieten halt das gefährliche Zeug.“

Dann shippt jemand ein neues Tool. Du vergisst, die Blocklist zu updaten. Der Agent findet es.

Und plötzlich bist du on-call, weil „deny dangerous stuff“ nur eine Story war, die du dir selbst erzählt hast.

Blocklists fühlen sich nach Kontrolle an. In Agent-Systemen sind sie meistens eine Falle. Und sie verrotten schnell: zwei Wochen später weiß niemand mehr, wovor die Liste eigentlich „schützen“ sollte.

Warum das in Production bricht

1) Du kannst „alle gefährlichen Tools“ nicht vorab aufzählen

Heute ist es db.delete_user. Morgen ist es crm.merge_accounts. Nächste Woche ist es tickets.close_all.

Das Tool, das du vergisst zu blocken, ist das, das dich beißt.

2) Blocklists scheitern an Naming und Indirection

Wenn du db.write blockst, shippt jemand db.patch. Wenn du email.send blockst, shippt jemand email.send_bulk.

Noch schlimmer: Wrapper. Der Agent ruft workflow.run("close_ticket") auf und deine „Blocklist“ sieht den echten Side Effect nie.

3) Default-Allow lässt Blast Radius leise wachsen

Wenn die Policy sagt „alles erlaubt außer…“, shipst du Permission-Expansion by default. Jedes neue Tool ist ein Incident, der nur auf Timing wartet.

4) Allowlists erzwingen eine explizite Entscheidung

Allowlists sind nervig. Gut so. Sie zwingen dich zu sagen: „Ja, der Agent darf dieses Tool unter diesen Bedingungen callen.“

Implementierungsbeispiel (echter Code)

Ein kleiner Policy-Evaluator:

  • default-deny
  • optionale Blocklist für Notfälle (Incident Mode)
  • „write tools brauchen Approval“
PYTHON
from dataclasses import dataclass


WRITE_TOOLS = {"email.send", "db.write", "ticket.close"}


@dataclass(frozen=True)
class Policy:
  allow: set[str]
  deny: set[str] = None  # for incident mode
  require_approval_for_writes: bool = True


class Denied(RuntimeError):
  pass


def evaluate(policy: Policy, tool: str) -> str:
  deny = policy.deny or set()
  if tool in deny:
      raise Denied(f"denied: {tool} (incident mode)")
  if tool not in policy.allow:
      raise Denied(f"not allowed: {tool}")
  if policy.require_approval_for_writes and tool in WRITE_TOOLS:
      return "approve"
  return "allow"
JAVASCRIPT
const WRITE_TOOLS = new Set(["email.send", "db.write", "ticket.close"]);

export class Denied extends Error {}

export function evaluate(policy, tool) {
const deny = new Set(policy.deny || []);
if (deny.has(tool)) throw new Denied("denied: " + tool + " (incident mode)");
if (!policy.allow.includes(tool)) throw new Denied("not allowed: " + tool);
if (policy.requireApprovalForWrites && WRITE_TOOLS.has(tool)) return "approve";
return "allow";
}

Echter Incident (mit Zahlen)

Wir haben ein Team gesehen, das einen Agenten mit „deny dangerous tools“-Policy shipped hat.

Dann kam ein neues Tool dazu: ticket.close_bulk. Es stand nicht in der Deny-Liste. Der Agent hat’s benutzt, weil es der kürzeste Weg zu „resolve“ war.

Impact:

  • ~200 Tickets falsch geschlossen
  • ~5 Engineer-Stunden zum Reopen, Erklären und Patchen
  • Agent war eine Woche aus, weil niemand ihm vertraut hat

Fix:

  1. default-deny allowlist
  2. write tools hinter Approvals
  3. deny list nur für Incident Mode (temporär)

Blocklists sind okay als Notbremse. Sie sind schlecht als Lenkrad.

Abwägungen

  • Allowlists bremsen „just ship it“-Velocity. In Prod ist das ein Feature.
  • Du brauchst Tooling für Allowlists (nicht in 12 Stellen hardcoden).
  • Devs werden versuchen, es mit Wrappern zu umgehen. Lass es nicht zu.

Wann du es NICHT nutzen solltest

  • Für lokale Prototypen kannst du lockerer starten — aber nimm das nicht mit nach Prod.
  • Auch wenn alle Tools read-only sind, lohnt sich eine kleine Allowlist (verhindert „versehentliche“ Exposure).
  • Wenn dein „Tool“ ein generisches RPC ist, das alles kann: fix das zuerst. Splitte Tools nach Capability.

Checkliste (Copy/Paste)

  • [ ] Default-deny allowlist (explizite Tool-Namen)
  • [ ] Tools nach Capability trennen (read vs write)
  • [ ] Approvals für irreversible Writes
  • [ ] Deny-Liste nur für Incident Mode (temporär)
  • [ ] Denied Tool Attempts loggen (Signal)
  • [ ] Keine generischen „do anything“-Tools exposen

Sicheres Default-Config-Snippet (JSON/YAML)

YAML
policy:
  default: "deny"
  allow: ["search.read", "kb.read", "http.get"]
  require_approval_for_writes: true
incident_mode:
  deny: ["browser.run"] # temporary brake
logging:
  log_denies: true

FAQ (3–5)

Sind Blocklists jemals sinnvoll?
Ja: für Incident Mode und temporäre Disables. Sie sind eine Bremse, kein Permission-Modell.
Kann ich Wildcards in Allowlists nutzen?
Vorsicht. Wildcards driften schnell zu Default-Allow. Wenn du Patterns brauchst, mach sie eng und review regelmäßig.
Was ist mit Tools wie ‘workflow.run’?
Sie verstecken Side Effects. Bevorzuge explizite Tools für explizite Actions, damit Policy darüber entscheiden kann.
Was ist die minimal sichere Policy?
Default-deny allowlist + read-only Tools. Writes später hinter Approvals.

Q: Sind Blocklists jemals sinnvoll?
A: Ja: für Incident Mode und temporäre Disables. Sie sind eine Bremse, kein Permission-Modell.

Q: Kann ich Wildcards in Allowlists nutzen?
A: Vorsicht. Wildcards driften schnell zu Default-Allow. Wenn du Patterns brauchst, mach sie eng und review regelmäßig.

Q: Was ist mit Tools wie ‘workflow.run’?
A: Sie verstecken Side Effects. Bevorzuge explizite Tools für explizite Actions, damit Policy darüber entscheiden kann.

Q: Was ist die minimal sichere Policy?
A: Default-deny allowlist + read-only Tools. Writes später hinter Approvals.

Nicht sicher, ob das dein Fall ist?

Agent gestalten ->
⏱️ 5 Min. LesezeitAktualisiert Mär, 2026Schwierigkeit: ★★★
In OnceOnly umsetzen
Budgets + permissions you can enforce at the boundary.
In OnceOnly nutzen
# onceonly guardrails (concept)
version: 1
budgets:
  max_steps: 25
  max_tool_calls: 12
  max_seconds: 60
  max_usd: 1.00
policy:
  tool_allowlist:
    - search.read
    - http.get
writes:
  require_approval: true
  idempotency: true
controls:
  kill_switch: { enabled: true }
Integriert: Production ControlOnceOnly
Guardrails für Tool-Calling-Agents
Shippe dieses Pattern mit Governance:
  • Budgets (Steps / Spend Caps)
  • Tool-Permissions (Allowlist / Blocklist)
  • Kill switch & Incident Stop
  • Idempotenz & Dedupe
  • Audit logs & Nachvollziehbarkeit
Integrierter Hinweis: OnceOnly ist eine Control-Layer für Production-Agent-Systeme.
Autor

Diese Dokumentation wird von Engineers kuratiert und gepflegt, die AI-Agenten in der Produktion betreiben.

Die Inhalte sind KI-gestützt, mit menschlicher redaktioneller Verantwortung für Genauigkeit, Klarheit und Produktionsrelevanz.

Patterns und Empfehlungen basieren auf Post-Mortems, Failure-Modes und operativen Incidents in produktiven Systemen, auch bei der Entwicklung und dem Betrieb von Governance-Infrastruktur für Agenten bei OnceOnly.