**Conference example:** ✓ You're a speaker (correct role) ✗ But you can't take MY backpack! Just because you can access `/api/backpacks/` doesn't mean you can access `/api/backpacks/mine`
// Vulnerable: Only checks if user is a sitter
GET /api/cats/romeo/health-updates
Authorization: Bearer
// Anne is a sitter, but is she Romeo's sitter? 🤔
**Conference example:** ✓ You're a speaker (correct role) ✗ But it's NOT your time slot (wrong context) *"Hey, I'm also a speaker!" waves from audience* Audience: "Wait, two speakers?"
// Anne tries to post updates at 3 AM when her sitting ended at 6 PM
POST /api/sittings/123/updates
Authorization: Bearer
// Is Anne an ACTIVE sitter right now?
**Setup:** Bob owns Romeo, Anne is a sitter
// Vulnerable endpoint
app.get('/api/cats/:catId', authenticateUser, async (req, res) => {
const { catId } = req.params;
// ❌ Only checks if user is authenticated, not if they own this cat
const cat = await db.cats.findById(catId);
res.json(cat);
});
user:bob → owner → cat:romeo
user:anne → sitter → cat:romeo
user:jenny → admin → system
type cat
relations
define owner: [user]
define admin: admin from system
define active_sitter: [cat_sitting#sitter with is_active]
define can_update: owner or admin or active_sitter
const canUpdate = await fga.check({
user: `user:${userId}`,
relation: 'can_update',
object: `cat:${catId}`,
context: { current_time: new Date().toISOString() }
});
*"Raise your hand if you'd rather debug 6 lines than 127 lines at 3 AM 🙋"*