Introduction
6 min
issues and verifies the jwt access tokens used across the upstart commerce platform — for shoppers browsing a storefront, for staff using management tools, and for the services that trust those tokens which half you are building for changes what you do with a token consumer traffic — storefronts, apps verify the signature locally and read the claims no call back to this service, and no permission lookup management traffic — admin and back office tools verify the same way, then resolve authorization against profile permissions svc because the token carries role references rather than a permission list, granting a role takes effect immediately, without reissuing anyone's token verifying a token fetch the signing keys from / well known/jwks json it needs no credentials, sends cors headers, and is cacheable for 24 hours — fetch once, cache, and refetch only when you meet a kid you do not recognise verify rs256 , then check that exp is in the future and that iss matches the issuer configured for the environment you are calling — auth svc by default, but it is a configurable value, so read it from your own config rather than hard coding the literal the claims you get back claim meaning sub user id type consumer or management — which model above applies lower case on the wire; compare case sensitively tenant the tenant this session is active for roles global and tenant level role names siteroles site id → role names, for site scoped access iat / exp issued at and expiry, as unix timestamps iss the issuer configured for the environment auth svc unless overridden tokens are deliberately thin ( 500 bytes) everything above is in the token; anything not in the token needs a lookup getting a token anonymous browsing needs no credentials curl x post https //api upstartcommerce com/api/v1/auth/guest \\ h 'x upstart tenant your tenant' signing a user in returns an access and refresh token curl x post https //api upstartcommerce com/api/v1/auth/login \\ h 'x upstart tenant your tenant' \\ h 'content type application/json' \\ d '{"username" "user\@example com","password" "…"}' then send it on every call authorization bearer \<accesstoken> login does not always return tokens if the account requires a second factor you get mfarequired true , an mfachallengeid , the delivery method, a masked destination and the challenge's own expiry — and no tokens finish with /auth/mfa/verify , or get a fresh code from /auth/mfa/resend treat it as a branch in your login flow, not an error keeping a session alive access tokens last one hour and refresh tokens seven days by default, both environment configurable — read expiresin from the response rather than hard coding either refresh rotates /auth/refresh returns a new pair and invalidates the one you presented, so persist the new refresh token every time /auth/logout revokes it there is also a ceiling on total session age — 30 days by default, and likewise configurable — that refreshing cannot extend when you reach it the error is session expired and the only way forward is a full login, so handle it distinctly from an ordinary expired access token tenant and site context the active tenant travels in the token , as the tenant claim, so a verified token already tells a service which tenant it is acting for the x upstart tenant header is how a caller selects that tenant when the user belongs to more than one /auth/tenants lists what the session can reach — use it to drive a tenant switcher — and /auth/refresh moves an existing session to a different tenant without asking for credentials again /auth/sites does the same for sites within the active tenant when calls fail errors carry a machine readable error , a human message and a code the ones worth branching on error what to do unauthorized bad credentials or a bad token re authenticate session expired session ceiling reached full login; refresh will not help tenant required multi tenant user, no tenant chosen send x upstart tenant unauthorized tenant / unauthorized site authenticated, but not for that scope site required / no authorized sites site context missing, or none available to this user account not verified real account, unverified email or phone account locked too many failed attempts temporary rate limited back off and retry invalid request malformed body or a missing field