Skip to content

Responsibility boundary

Three systems own three different decisions:

Owner Responsibility
Stripe Which plans you sell (products and prices) and what each customer is subscribed to.
Strent What each customer currently has in Stripe, and whether Strent has read the customer yet, so it can answer.
Your application What each product grants, which user belongs to which customer, which resources they may access, and what to do when a dependency fails.

Suppose the customer’s active products grant the entitlement advancedExports. That tells you what the Stripe customer’s active subscriptions grant. It does not tell you that the signed-in user:

  • belongs to that customer;
  • has an exporter role;
  • may access the requested workspace;
  • may export the requested data;
  • satisfies any application-specific compliance rule.

Your application combines those facts:

const canExport =
membership.customerId === stripeCustomerId &&
membership.role === "admin" &&
(await strent.entitlements.has({
customer: stripeCustomerId,
entitlement: "advancedExports",
}));

The Node SDK reuses a saved list that confirms a positive check for less than 5 minutes by default. During a timeout, network error, HTTP 5xx or 429, or invalid successful response, it can answer from a saved list less than 1 hour old. It emits a warning for each fallback. A negative check always goes to Strent; a negative fact is never inferred from a failure.

This trades immediate revocation for continuity: removing access may take up to 5 minutes to affect a cached check while Strent is healthy, or until the saved value’s 1-hour limit during an outage. For paths that need immediate revocation, use cache: false and decide how your application handles errors. Serverless memory is private to each instance and disappears on replacement, so fallback cannot guarantee access during every outage.

Invalid credentials, not-ready projections, caller abort, other non-429 4xx, and failures without eligible saved facts remain typed errors. Your application owns the final authorization decision and any policy beyond these fixed windows. A successful refresh clears the customer’s cache only in the same client.

Configure reuse, fallback, and warnings →

Product and price mapping stays in your application

Section titled “Product and price mapping stays in your application”

Strent reports which products and prices are active; what they grant lives in your application. Declare it as an entitlements mapping the SDK resolves, or derive plan facts from activeItems.list yourself.

The SDK’s activeItems.hasProduct({ customer, product }) reads the fact that the customer has an active item for that product, using the same active-item list. Your application decides which plan that product represents and what the user may do. The HTTP API keeps one list operation; price-specific checks and checks across several plans read the list once in application code.