---
title: "Deny by default · Agent Wranglers"
url: https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/deny-by-default
updated: 2026-10-20
licence: "All rights reserved"
---

# Deny by default

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Access and accounts](https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts)
- Rule: Make every route need a login unless it is marked public on purpose.
- How: Apply the login check to the whole app, then list the public routes by name. A new route is then private until someone decides otherwise. Review the public list in each change.
- Check: List every route the server answers. Call each one without a token. Only the routes on the public list return 200.

Example:

```js
const PUBLIC_ROUTES = new Set(['/', '/login', '/healthz']);
app.use((req, res, next) => PUBLIC_ROUTES.has(req.path) || req.user ? next() : res.sendStatus(401));
```

```python
# Python with Flask
PUBLIC_ROUTES = {"/", "/login", "/healthz"}

@app.before_request
def require_login():
    if request.path not in PUBLIC_ROUTES and g.user is None:
        abort(401)
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers security testing playbook: https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/deny-by-default`.

- Previous: [Check roles on every action](https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/function-access)
- Next: [Slow down password guessing](https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/login-guessing)
- [Access and accounts](https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts)
