How to prevent unauthorized access to Sanity data through Project ID?

2 replies
Last updated: Jul 4, 2023
Hello everyone,
I have a question regarding the security of my Sanity project data. I was wondering if there is a way to prevent unauthorized access to my data through the Project ID. I noticed that when I replace the Project ID in the Query URL (generated from the Vision Tool in Sanity Studio) with the Project ID from my other Sanity project, I am able to view the data. However, when I tried using a random Project ID I found online, I couldn't access their data (No result shown, just blank array). I'm curious to understand why this is the case.

This is a very beginner question, but I would appreciate any clarification. Thank you!
AI Update

Great question! This is actually about how Sanity's security model works with datasets and document visibility. Let me break this down for you.

Why You Can Access Your Other Project But Not Random Projects

When you query a Sanity project through the Vision Tool or API, you're accessing a dataset, and datasets have visibility settings that determine who can read from them. Here's what's happening:

Dataset Visibility Settings

Sanity datasets can be configured as either:

  • Public - Anyone can query content without authentication (great for public websites)
  • Private - Only authenticated users or requests with valid access tokens can read data

You can change this setting via the CLI (sanity dataset visibility set <datasetName> <public/private>) or through the management console at manage.sanity.io.

Why Your Setup Works the Way It Does

  1. Your own projects: Both of your projects likely have public datasets, which is why you can query them just by knowing the project ID
  2. Random project you found: That project probably has a private dataset, so unauthenticated queries return empty results

Important Security Notes

According to the Keeping your data safe documentation, there are some crucial points to understand:

  • Project IDs are not secret - They're meant to be public identifiers
  • Public datasets are truly public - Anyone with your project ID can query public datasets
  • Asset files are always public - Even in private datasets, uploaded images and files can be viewed by anyone who has the URL

How to Secure Your Data

If you need to restrict access to your content:

  1. Set your dataset to private in the management console
  2. Use access tokens for authenticated requests (but never expose tokens in client-side code!)
  3. Configure CORS origins in your project settings to control which domains can access your data from browsers
  4. Use custom roles (on higher-tier plans) for fine-grained access control

Documents with Periods in Their IDs

There's also a special consideration about document visibility: documents whose _id starts with a period (.) are considered "root path" documents and are only accessible to authenticated requests, even in public datasets. Regular documents (without a leading period) in public datasets are accessible to everyone. Drafts (with drafts. prefix) follow the same visibility rules as their published counterparts.

For public-facing websites, it's common and perfectly fine to have a public dataset - just make sure you're only storing content that's meant to be publicly accessible. If you need to keep certain documents private (like drafts or sensitive data), consider using a separate private dataset or implementing custom access control rules.

Does this clarify how the security model works? The key takeaway is that your project ID alone doesn't grant access - it's the dataset visibility setting that determines whether unauthenticated queries can read your data!

Show original thread
2 replies
Hi
user D
. It’s a good question. A dataset that’s public can be queried without authentication, meaning that any documents on a non-root path (i.e., without a period in the
_id
) are publicly viewable. Documents that are on a non-root path, which includes drafts, are not visible without authentication.
If you’d like to hide
all documents from a query, you can make your dataset private in Manage , though note that all queries would then require authentication (i.e., a token).
Got it, thank you!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?