Authorization & RLS

Row-level access in Rust — no magic ACL columns. Working demo: todo example (switch guest / alice / bob).

LIVE

Row-level checks (403)

Switch user (cookie), add tasks, toggle another user's task for 403 Forbidden, or Fail validation for 422.

Signed in as:guest

Production (RESUMA_ENV=production): validation returns Invalid request — not internal field names.

Check ownership in handlers

pub fn assert_owner(owner_id: &str, req: &FlowRequest) -> Result<()> {
    let uid = req.user_id().ok_or(ResumaError::Unauthorized)?;
    if owner_id != uid && !req.has_role("admin") {
        return Err(ResumaError::Forbidden("not your task".into()));
    }
    Ok(())
}

Default-deny checklist

  • Read user_id() from middleware — never trust client-sent ids
  • Every mutation checks ownership or admin role
  • Return Forbidden, not silent success
  • Admin secrets only in env, never in SSR payload

Postgres row-level security (optional)

Last line of defense when using a database:

ALTER TABLE todos ENABLE ROW LEVEL SECURITY;
CREATE POLICY todo_owner ON todos
  USING (owner_id = current_setting('app.user_id', true));

Set app.user_id on the DB connection from your auth middleware before queries.