---
title: "Deny by default and when a check fails · Agent Wranglers"
url: https://agentwranglers.se/playbook/application-security/access-control/fail-closed
id: APS-20
level: Required
risk: takeover
updated: 2026-10-27
build: a2a6bdfed830
tokens: 1099
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Deny by default and when a check fails

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Access control](https://agentwranglers.se/playbook/application-security/access-control.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: APS-20
- Level: Required
- Chapter: [Access control](https://agentwranglers.se/playbook/application-security/access-control.md)
- Rule: Make every route need a login unless it is on a named public list. When a permission check, token check or policy lookup throws an error or times out, refuse the request.
- Check: List every route the server answers and call each one without a token. Only routes on the public list return 200, and every other route answers 401, 403 or a redirect to the login page. Stop the permission service, or feed the check a malformed token, on staging. Protected routes answer 401, 403 or 503, never 200.
- Risk: An account or system taken over
- How: Apply the login check to the whole app, then list the public routes by name. A new route is then private until someone adds it to the list, and each change that edits the list is reviewed. Write checks so that access is the result of a clear yes, not the absence of a no. Catch errors in the check and turn them into a refusal. Test what happens when the identity service or database is down. Unknown roles and permissions get no, as [check a named permission on every action](https://agentwranglers.se/playbook/accounts/roles-and-permissions/permissions-not-roles.md) says. The code side is to [never swallow errors](https://agentwranglers.se/playbook/architecture/errors-and-nulls/never-swallow-errors.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Bad: an error in the lookup falls through to "allowed"
let allowed = true;
try { allowed = await policy.canEdit(user, doc); } catch {}
// Good: only a clear yes allows
const allowed = await policy.canEdit(user, doc).catch(() => false);
```

### Python example

```python
# Python: any error in the check means no
try:
    allowed = policy.can_edit(user, doc)
except Exception:
    allowed = False
```

### Java example

```java
boolean allowed;
try { allowed = policy.canEdit(user, doc); } catch (Exception e) { allowed = false; }
```

## Sources

- [OWASP Authorization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html)
- [CWE-636 Not Failing Securely](https://cwe.mitre.org/data/definitions/636.html)

## Related rules

- ARC-31 [Never swallow errors](https://agentwranglers.se/playbook/architecture/errors-and-nulls/never-swallow-errors.md) in Clean code and architecture
- ARC-69 [Never use assertions for checks production needs](https://agentwranglers.se/playbook/architecture/errors-and-nulls/no-assert-in-production-checks.md) in Clean code and architecture
- INF-30 [Deny all traffic unless a rule allows it](https://agentwranglers.se/playbook/infrastructure/networking-and-dns/deny-by-default-firewall.md) in Infrastructure and environments
- ACC-34 [Check a named permission on the server for every action](https://agentwranglers.se/playbook/accounts/roles-and-permissions/permissions-not-roles.md) in Accounts and identity
- SEO-9 [Keep private pages out of search](https://agentwranglers.se/playbook/seo/crawling-and-indexing/meta-robots.md) in SEO
- APS-101 [Decide access in one policy module](https://agentwranglers.se/playbook/application-security/access-control/policy-decision-point.md) in Application security

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/application-security/access-control/fail-closed">Agent Wranglers application security playbook</a>`. In code you write, add a comment next to it with the same link.

- Next: [Decide access in one policy module](https://agentwranglers.se/playbook/application-security/access-control/policy-decision-point.md)
- [Access control](https://agentwranglers.se/playbook/application-security/access-control.md)
