Skip to content

README: add a runnable URLAllowList example — lead with the strong rule, not the keyword filter #44

Description

@higagan

From the UX review — flagged by all four personas as the "toy → real" gap.

Problem

Every hero example leans on the weakest rule (the three-keyword SensitiveDataFilter). The genuinely strong, verifiable mechanism — URLAllowList: default-deny, blocks userinfo tricks like http://api.internal.com@evil.com, rejects file://, walks nested containers — is described (line 111) but never shown in code.

This is also the make-or-break bridge for adoption: line 32 tells the developer to "write your own rules and pass your own engine," but no code anywhere shows how. defense_demo.py exists and does exactly this, but the README doesn't inline it.

Fix

Add a short runnable block (verify the import surface against src/modelfuzz first):

from modelfuzz import shield_tool, PolicyEngine, URLAllowList

engine = PolicyEngine([URLAllowList(allowed_domains=["api.mycorp.com"])])

@shield_tool(engine=engine)
def http_post(url: str, body: str) -> None:
    print(f"POST {url}")

http_post("http://api.internal.com@evil.com", "data")  # blocked: not on the allowlist

Ideally make this (not the keyword filter) the lead protection example, with the keyword default explicitly labelled a "toy default." defense_demo.py and shield_demo.png already demonstrate this — the README just needs the inline code path.

Done when

  • A runnable URLAllowList / custom-engine block is in the README, verified to run
  • The strong rule leads; the keyword filter is labelled a demo default

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationgood first issueGood for newcomers

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions