Embedded authorization and the Authorization Gap
Objective
Explain why authorization embedded in application code is a problem, and name the categories of embedded checks Zift looks for.
Concept
Authentication proves who a caller is. Authorization decides what that identity may do, on which resource, in what context, at runtime. EnforceAuth calls the space between the two the Authorization Gap: you can know exactly who someone is and still have the "what may they do" decision scattered, inconsistent, and invisible.
That scattering is the problem. In a typical service, authorization is not one component. It shows up as:
- Inline role checks such as
if user.role == "admin", buried in a request handler. - Permission guards such as
if not user.can("documents:delete"), checked in one handler and forgotten in the next. - Middleware such as
requireRole("editor")wrapping some routes but not others.
When the rules live in code like this, three things go wrong. You cannot see the full policy without reading every file. You cannot change a rule without a code deploy. And you cannot prove the rules are consistent, because two handlers that should enforce the same thing often drift apart. That is an audit and a security problem at the same time.
The EnforceAuth operating model is Define, Enforce, Audit. Embedded authorization fails at Define (there is no single definition) and at Audit (you cannot inspect or replay decisions). Zift, the assess product, is the first step: it scans a codebase and finds these embedded checks so they can be pulled out into policy. Later products in the fabric govern (Writ), evaluate (Herald), and defend (Verdict), but none of that is possible until you know where the authorization actually lives.
Hands-on lab
No new commands in this lesson. Open the extracted policy in
../lab/policy.rego and read the header comment. It names
the three embedded checks Zift found in the source service: a requireRole(...)
middleware, an inline if user.role == "admin" check, and an ownership guard
if doc.owner_id == user.id. Keep this file open; the rest of the course builds
on it.
Check for understanding
- Give two reasons that authorization embedded across handlers is harder to audit than a single policy file.
- Which stages of the Define, Enforce, Audit model does embedded authorization break, and why?
- List the three categories of embedded checks Zift is built to find.