Expiring offline access tokens explicitly disabled
Verifies React Router expiring offline-token configuration and refresh-metadata storage compatibility.
| Detail | Value |
|---|---|
| Check ID | EXPIRING_OFFLINE_TOKEN |
| Severity | Medium |
| How it runs | Deterministic scan and agent review |
Anchor to Vulnerable exampleVulnerable example
app/shopify.server.ts
import { shopifyApp } from "@shopify/shopify-app-react-router/server";
const shopify = shopifyApp({
// Turning this off keeps long-lived offline tokens that never
// rotate, so a leaked token stays valid until someone notices.
future: { expiringOfflineAccessTokens: false },
sessionStorage: new PrismaSessionStorage(prisma),
});
Anchor to How to fixHow to fix
Enable expiringOfflineAccessTokens and ensure session storage persists expiry and refresh metadata.
For more detail, see Migrate to expiring offline access tokens. Public apps must use expiring offline tokens for GraphQL Admin API requests from January 1, 2027.
app/shopify.server.ts
import { shopifyApp } from "@shopify/shopify-app-react-router/server";
const shopify = shopifyApp({
future: { expiringOfflineAccessTokens: true },
sessionStorage: new PrismaSessionStorage(prisma),
});
// Session storage has to persist the refresh metadata, or the
// tokens expire with nothing to renew them.
//
// // prisma/schema.prisma
// model Session {
// expires DateTime?
// refreshToken String?
// refreshTokenExpires DateTime?
// }
shopify app security check, the command that runs this check- All app security checks
Was this page helpful?