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. |
A plan is not a permission
Section titled “A plan is not a permission”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", }));Choose freshness and failure policy
Section titled “Choose freshness and failure policy”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.