Skip to content

authenticate.webhook() should support opting out of session storage lookup #3127

@fabregas4

Description

@fabregas4

Summary

authenticate.webhook() unconditionally performs a session storage lookup (loadSession) on every webhook request, even when the handler never uses session or admin. For high-volume webhook topics this is unnecessary overhead that can saturate database connection pools under burst load.

Current behaviour

In authenticate/webhooks/authenticate.js:

const sessionId = api.session.getOfflineId(check.domain);
const session = await config.sessionStorage.loadSession(sessionId); // always runs

This DB query runs after HMAC validation on every webhook request, regardless of whether the caller uses the returned session or admin context.

Problem

Some webhook topics never need to call back to the Shopify Admin API. For example, a PRODUCTS_UPDATE subscription may only need to read the payload and write to its own database — admin and session are never touched.

Under burst conditions (e.g. a merchant bulk-updating 50–200 products), this produces 50–200 concurrent loadSession DB queries purely to build an admin client that will never be used. On a typical deployment with a connection pool of 5–15, those queries queue up and starve the rest of the application.

Proposed API

An optional flag (or separate method) that skips the session lookup and returns only the HMAC-verified context:

// Option A — flag
const { shop, topic, payload } = await authenticate.webhook(request, { 
  loadSession: false 
});
// session and admin would be undefined/absent on the return type

// Option B — separate method
const { shop, topic, payload } = await authenticate.webhookHmacOnly(request);

The HMAC verification itself must still run — this is only a request to make the session storage call opt-in (or opt-out) rather than unconditional.

Workaround

It is possible to replicate the HMAC check manually using Node's createHmac and skip authenticate.webhook() entirely for these topics, but this requires re-implementing validation logic that the library already owns and should not be the responsibility of app developers.

Impact

Any app with high-volume webhook topics that do not call the Admin API. Unless some pre-filtering using request headers can be done prior to auth, the full auth overhead including db connection is required every time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions