spotify.listening_history without exposing their messages — and is time-bounded and revocable, so consent stays narrow and reversible instead of an all-or-nothing login. The same primitive is designed to extend beyond “read this scope” to “run this specific operation over this subset of data” — authorizing a computation rather than raw access (see Operation-scoped grants below).
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
- A builder requests a set of scopes (e.g.
instagram.profile,spotify.listening_history) - The user reviews the request and approves it in their app
- The user’s wallet signs the grant (EIP-712), binding the grantee, the scopes, and an expiry
- The grant is recorded through the DP RPC and anchored onchain
- 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:- The builder’s backend calls
createAccessRequest, which returns anapprovalUrland arequestId. - The user opens the approval surface (a browser tab), reviews the app, source, and scopes, and approves — signing the grant with their wallet.
- The builder polls
getAccessRequestStatus(requestId)until it resolves toapproved, which returns thegrantId, the user’spersonalServerUrl, and the granted scope. - The builder reads the approved data from the Personal Server, paying the protocol fee from escrow — see Payments & fees.
Grant format (EIP-712)
Grants use EIP-712 typed data so consent is cryptographically verifiable.| Field | Description |
|---|---|
grantor | The user granting access |
granteeId | The builder receiving access (registered in DataPortabilityGrantees) |
scopes | Scope identifiers the grant covers — the unit of access |
expiresAt | Unix timestamp for expiration; 0 means it never expires |
nonce | Monotonically increasing value per user, prevents replay |
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 revokes at any time. Enforcement has two layers: where the Context Gateway serves data, it stops serving immediately, even before onchain confirmation, while the revocation is anchored on-chain as the durable record. Integrations that bypass the Context Gateway enforce against that onchain state.
- Expired — once
expiresAtpasses, the grant stops authorizing reads.
Verification
When a builder makes a data request, the Personal Server verifies the grant before serving data:- Registered — the requester is a registered builder
- Not revoked — the grant has not been revoked
- Not expired —
expiresAtis0or in the future - Scope match — the requested scope is within the granted scopes
- Signer match — the request recovers to the builder that matches the grant’s grantee
- Fee paid — the grant’s fee shows as paid (see Payments & fees)
| Code | Meaning |
|---|---|
401 | Invalid signature or unauthorized |
403 | Valid auth but not permitted |
410 | Grant revoked |
411 | Grant expired |
412 | Scope not granted |
Operation-scoped grants
Every grant today authorizes one implicit operation: return the scope — the grantee reads the covered data in plaintext. The designed extension is a grant that instead carries an operations pipeline: the user authorizes a specific computation over their data, the Personal Server decrypts the data and executes that pipeline locally, and the grantee receives only the result — never the raw data. The consent moment changes accordingly. Instead of“App X requests access to your Instagram posts”the user approves
“App X requests access to your anonymized Instagram posts”— or a summary, an aggregate, a redaction: whatever the pipeline the grant names actually produces. This is what an application should reach for when it wants a privacy-preserving operation over a user’s data — an LLM summary of a user’s chat history, say — where the application only needs the output, not the records themselves. Everything else about the grant stays as described above: the same EIP-712 format (plus the operations field), the same lifecycle, the same verification on the Personal Server, the same fee gating. The one piece expected to evolve with it is pricing — fees for an operation-scoped grant may need to be dynamic, reflecting the compute the pipeline requires, rather than a flat per-access fee.
Status. Operation-scoped grants are a design direction, not implemented — today every grant returns the scope’s data directly. Note the distinction from Confidential compute: operation-scoped grants run a computation on one user’s data, on that user’s own Personal Server; confidential compute runs jobs over pooled data from many users in a TEE network.
Onchain record
The permissions contract emits a single event capturing the grant’s substance whenever it is created or re-issued: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.
This is a deliberate choice, modelled on how public blockchains already work: just as a token transfer publicly shows this address sent this asset to that address, a grant publicly shows this address shared this kind of data with this grantee, until when — the transparency model the industry has broadly adopted. For deployments that prefer not to expose scope details on-chain, commitments or hashed scopes are available as an option.
Status. Grant signing, verification, and revocation work end to end. The scope-native permissions contract (V2,
DataPortabilityPermissions) is the current model; a previous file-based permission contract remains deployed on mainnet during migration. See Core contracts for addresses.Related
- Personal Servers — where grants are enforced
- Payments & fees — how a grant’s fee is funded and settled
- Scopes & schemas — what scopes are and how they’re defined
- Protocol — DP RPC — identity and the settlement path
- Build a Vana App — the end-to-end builder integration