Skip to main content
verifyGrant() is the entry gate every Glide MCP tool handler calls before touching money or reading sensitive vault state. It implements the F3 IRON RULE from the Glide money-safety contracts: re-read the grant row and the (principal, entity, vault) tenant graph from the database on every invocation. A JWT grant that was valid at issue time is treated as untrusted until the DB confirms it still is. Bearer tokens are point-in-time snapshots. Between issue and use the principal’s entity membership can be revoked, transferred, or suspended; the grant itself can be superseded by a policy refresh. Trusting ambient server state — or the cached grant alone — leaves a window where a revoked principal can still move funds. This package closes that window at the cost of one DB read per tool call.

Install

npmjs.com/package/@glideco/grant-wrapper

Why two fresh reads?

The grant DB row answers “has this token been revoked or superseded since issue?” The tenant graph answers “does (principal, entity, vault) still hold?” Both are necessary. A grant row that isn’t revoked still doesn’t authorize a call if the principal was removed from the entity between issue and use. Checking only one leaves an IDOR path; checking both closes it. Clock-skew tolerance (clockSkewSeconds, default 0) absorbs the 10–30 second drift measured in the Privy spike between Vercel pods, Hydra/Ory, and agent devices. The production default is 60 seconds — wide enough to absorb drift without meaningfully extending the effective grant lifetime.

API

Verifying a grant in a tool handler

Error codes

GrantError carries a typed code so callers can route errors precisely:

Narrowing detection

For policy refreshes, the companion isNarrowingOrUnchanged export from @glideco/policy-engine determines whether a refresh broadens or only tightens the policy. verifyGrant handles liveness and IDOR checks; narrowing detection is a separate concern in the policy engine.

Reading list