Solved.
I am using the @shopify/koa-shopify-auth package, and turns out accessMode is by default set to “online”, and per the docs, online access token lifetimes match the lifetimes of the user’s web session.
The solution was to set accessMode to “offline” via the shopifyAuth middleware function.