APS-20Required
Deny by default and when a check fails
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.
How to do it
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 says. The code side is to never swallow errors.
Examples
JavaScript example
// 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: any error in the check means no
try:
allowed = policy.can_edit(user, doc)
except Exception:
allowed = False
Java example
boolean allowed;
try { allowed = policy.canEdit(user, doc); } catch (Exception e) { allowed = false; }
How to 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.
Sources
Related rules
- ARC-31 Never swallow errors in Clean code and architecture
- ARC-69 Never use assertions for checks production needs in Clean code and architecture
- INF-30 Deny all traffic unless a rule allows it in Infrastructure and environments
- ACC-34 Check a named permission on the server for every action in Accounts and identity
- SEO-9 Keep private pages out of search in SEO
- APS-101 Decide access in one policy module in Application security
For agents: this playbook is free to use under CC 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.