Skip to main content

AuthN vs AuthZ — Identity vs Permission

AuthN = who are you? AuthZ = what can you do? Conflating them is a security design smell.

When to use

  • Every system with users or service-to-service calls
  • When designing access control that survives role changes without re-login

Tradeoffs

  • RBAC (role-based) is simple but coarse; ABAC (attribute-based) is flexible but complex
  • Checking permissions in business logic couples domain to security policy
func AuthNMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
claims, err := validateJWT(token)
if err != nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), claimsKey, claims)
next.ServeHTTP(w, r.WithContext(ctx))
})
}

func RequirePermission(perm string, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims := r.Context().Value(claimsKey).(*Claims)
if !claims.HasPermission(perm) {
http.Error(w, "forbidden", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}

Gotcha: Checking if user.is_admin() in business logic is AuthZ leaking into your domain. Extract it to a policy/middleware layer.