Skip to main content
Status. Grant signing, verification, and revocation work end to end. The scope-native permissions contract (V2, DataPortabilityPermissions) is the current model; an earlier file-based permissions contract is still deployed on mainnet, and new grants do not use it. See Core contracts for addresses.
A grant is a signed permission that lets a builder access specific scopes of a user’s data. Grants are the access-control primitive of the protocol — no builder can read data without one, and every grant can be revoked by the user at any time. The grant is scope-native onchain: the onchain record carries the scopes and an expiry directly, so the chain expresses exactly what the Context Gateway and the Personal Server enforce — without resolving file IDs off-chain. A grant is scoped to specific data types, not a whole account — a user can share spotify.listening_history without exposing their messages — and can be time-bounded and revoked. To give an app a computed result instead of the records, see Derivative data. Grants can also carry economics. Rather than a one-off read, a user can grant a DataDAO / DLP the right to make decisions over their contributed data, and in return receive a VRC-20 token representing proportional rights over the pooled dataset — turning a permission into an ongoing stake in how that data is used and monetized.

How grants work

  1. A builder requests a set of scopes (e.g. instagram.profile, spotify.listening_history)
  2. The user reviews the request and approves it in their app
  3. The user’s wallet signs the grant (EIP-712), binding the grantee, the scopes, and an expiry
  4. The grant is recorded through the DP RPC and anchored onchain
  5. On every data request, the Personal Server checks the grant before releasing data

Requesting a grant (the Connect flow)

A builder does not implement grant signing itself. It asks the Vana SDK to create an access request; the user is sent to a Vana approval surface, signs the grant there, and the builder polls for the approved result:
  1. The builder’s backend calls createAccessRequest, which returns an approvalUrl and a requestId.
  2. The user opens the approval surface (a browser tab), reviews the app, source, and scopes, and approves — signing the grant with their wallet.
  3. The builder polls getAccessRequestStatus(requestId) until it resolves to approved, which returns the grantId, the user’s personalServerUrl, and the granted scope.
  4. The builder reads the approved data from the Personal Server, paying the protocol fee from escrow — see Payments & fees.
For the end-to-end integration — SDK setup, backend routes, and a React button — follow the Build a Vana App guide.

Grant format (EIP-712)

Grants use EIP-712 typed data so consent is cryptographically verifiable.
The example uses expiresAt: 0 (never expires) to show the case some integrations want — standing consent for a service the user keeps connected. For most grants, prefer a real expiry: a bounded expiresAt limits how long a single approval stays live, and is the safer default.

Grant lifecycle

  • Create — the user signs; the grant is recorded and anchored.
  • Active — the grantee may read covered scopes until expiry or revocation.
  • Revoked — the user can revoke at any time. The Personal Server checks grant state on every request, so the next read fails, and the revocation is anchored on-chain. Where the Context Gateway serves data, it stops serving immediately, before on-chain confirmation.
  • Expired — once expiresAt passes, the grant stops authorizing reads.

Verification

When a builder makes a data request, the Personal Server verifies the grant before serving data:
  1. Registered — the requester is a registered builder
  2. Not revoked — the grant has not been revoked
  3. Not expired — expiresAt is 0 or in the future
  4. Scope match — the requested scope and operation are covered by a granted scope entry (see Scope grammar)
  5. Signer match — the request recovers to the builder that matches the grant’s grantee
  6. Fee paid — the grant’s fee shows as paid (see Payments & fees)
If any check fails, the Personal Server returns an error:

Computing over a user’s data

A grant authorizes one of two operations per scope entry, encoded by the scope grammar: read (the default) or write (the entry carries a write: prefix). To give an app the result of a computation instead of the records, use derivative data: the user’s Personal Server answers a question over their own records, and the app reads only the answer, under a read grant on the answer’s scope. For jobs over data pooled from many users, see Confidential compute.

Onchain record

The permissions contract emits a single event capturing the grant’s substance whenever it is created or re-issued:
Because scopes and expiresAt live in the event itself, anyone can reconstruct who may access what, until when, directly from the chain — without resolving file IDs off-chain. The grantor, grantee, scopes and expiry of every grant are public. The data itself is not.