Set initial value to current user and scope document access in Sanity Studio

6 replies
Last updated: Feb 27, 2023
I would like to set up a project to allow editors into Sanity Studio to create documents. However, I’d like to scope the documents they have access to, as well as save which user created the document. I have seen snippets online, but none work for me.
I’ve seen things like `

import userStore from 'part:@sanity/base/user'
but I get errors, such as
Failed to resolve import "part:@sanity/base/user

I’d like to set the value of the user as an initialValue in the document schema.
AI Update

The part:@sanity/base/user syntax you're seeing is from Sanity Studio v2 and no longer works in v3+. Here's how to properly handle user tracking and document access control in modern Sanity Studio.

Setting Initial Values with Current User

Unfortunately, field-level initialValue does NOT have access to currentUser context in schema definitions. The context with currentUser is only available in specific places:

The proper way to set user information when creating documents is through Initial Value Templates in your sanity.config.ts:

// sanity.config.ts
import {defineConfig} from 'sanity'

export default defineConfig({
  // ... other config
  document: {
    newDocumentOptions: (prev, context) => {
      const {currentUser} = context
      return [
        ...prev,
        {
          id: 'my-document',
          title: 'My Document',
          schemaType: 'myDocument',
          value: {
            createdBy: {
              _type: 'reference',
              _ref: currentUser?.id
            }
          }
        }
      ]
    }
  }
})

2. Using Conditional Fields Callbacks

You CAN access currentUser in conditional field callbacks like hidden and readOnly:

// In your schema
defineField({
  name: 'sensitiveField',
  type: 'string',
  readOnly: ({currentUser}) => {
    // currentUser has: id, name, email, roles
    return !currentUser?.roles.find(({name}) => name === 'administrator')
  }
})

The currentUser object includes:

  • id (string)
  • name (string)
  • email (string)
  • roles (array of objects with name, title, description)

Document-Level Permissions (Scoping Access)

To control which documents editors can access based on who created them, you need custom roles with content resources. This is an Enterprise plan feature and is configured through the Sanity Manage dashboard, not in your code.

How It Works

  1. Content Resources use GROQ filters to define subsets of documents
  2. Custom Roles apply permissions to those content resources
  3. You can filter based on Sanity's built-in _createdBy field or your own custom fields

Example content resource filter:

_createdBy == identity()

Where identity() represents the current user's ID.

Important Notes

  • Custom roles and content resources require an Enterprise plan
  • These are configured via the Sanity Manage web interface or the Roles API, not in your Studio code
  • Roles in Sanity are additive - if a user has multiple roles, they get the combined permissions
  • For filtered access to work properly, your dataset should typically be set to private (public datasets allow reading all documents regardless of authentication)

Complete Working Example

Here's a practical setup:

// schemas/myDocument.ts
import {defineField, defineType} from 'sanity'

export default defineType({
  name: 'myDocument',
  type: 'document',
  fields: [
    defineField({
      name: 'title',
      type: 'string'
    }),
    defineField({
      name: 'createdBy',
      type: 'reference',
      to: [{type: 'sanity.user'}],
      readOnly: true,
      // Note: initialValue here won't have access to currentUser
      // Use Initial Value Templates instead
    })
  ]
})
// sanity.config.ts
export default defineConfig({
  // ... other config
  document: {
    newDocumentOptions: (prev, {currentUser}) => [
      ...prev,
      {
        id: 'myDocument',
        title: 'My Document',
        schemaType: 'myDocument',
        value: {
          createdBy: {
            _type: 'reference',
            _ref: currentUser?.id
          }
        }
      }
    ]
  }
})

Then configure custom roles in Sanity Manage to filter documents based on the createdBy field or use the built-in _createdBy system field.

Show original thread
6 replies
Do you know if you're using sanity V2 or V3?
V3
V3 no longer uses
@sanity/base
as far as I know. So you are trying to resolve a V2 import
This sounds like it may be of use to you https://www.sanity.io/docs/roles-reference
Yes, seeing that now. For instance, how would I hide the “Vision” plugin for non-admin? Would I have to get currentUser in sanity.config.js and not load the vision plugin?
This answer should work for 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?