How to prevent unauthorized access to Sanity data through Project ID?
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
- Your own projects: Both of your projects likely have public datasets, which is why you can query them just by knowing the project ID
- 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:
- Set your dataset to private in the management console
- Use access tokens for authenticated requests (but never expose tokens in client-side code!)
- Configure CORS origins in your project settings to control which domains can access your data from browsers
- 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 thread2 replies
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.