Share Auth Tokens don't seem to work

I’m unable to use the auth token returned by /shares/auth endpoint, for regular endpoints: GET /items/collection, PATCH /items/collection/:id etc., no matter how.

I’ve tried using the token as a cookie, as a bearer token, but nothing seems to work.

Keep receiving 403 Forbidden errors.

Even in cases where the Admin role has been provided as the role for the share!

Are there some caveat(s) when using the Share auth tokens in this way, or is it actually not even possible (which would make it a bug) at this time?

Oh well, turns out that you basically have to set a Role with sufficient privileges for the shared item.

That’s the role assumed by the access_token. That way you could limit access to the shared item, by creating a role with limited access. Even in case you set it to Administrator, access_token still remains scoped to that single shared item.

After setting a role with sufficient privileges access works either using the share link to the Directus Studio App, or you can use the token returned by /shares/auth to access the resource at /items/collection/shared_item_id

Are you using a custom role named “Admin” or the builtin “Administrator”? Does Admin have Read/Update permission for the fields you wanna get/patch?

The role allocation is not an issue in this case.

Users from the target role (Role A) are able to access the data without issues →

Sep 01 10:34:14 [05:04:14.611] TRACE: [2.642ms] select "directus_users"."id", "directus_users"."role" from "directus_users" where "directus_users"."token" = $1 and "status" = $2 limit $3 [P2yW3CeJo7WfZ-RhMGhKQ5-T2Y7_91wZ, active, 1]
Sep 01 10:34:14 [05:04:14.663] TRACE: [39.017ms] select "form_responses"."id", "form_responses"."status", "form_responses"."sort", "form_responses"."user_created", "form_responses"."date_created", "form_responses"."user_updated", "form_responses"."date_updated", "form_responses"."form", "form_responses"."response_data", "form_responses"."started_on", "form_responses"."completed_on", "form_responses"."ip", st_astext("form_responses"."location") as "location", "form_responses"."session_id", "form_responses"."location_raw", "form_responses"."respondent_is_user", "form_responses"."respondent_user", "form_responses"."editing_allowed", "form_responses"."is_response_hidden" from "form_responses" order by "form_responses"."sort" asc limit $1 [100]
Sep 01 10:34:14 [05:04:14] GET /items/form_responses 200 63ms

It’s just that the Share (session/cookie) token, with the same role, is not able to access the data, and keeps running into 500 Internal Server Error

Sep 01 10:30:00 [05:00:00.018] TRACE: [5.546ms] SELECT 1 []
Sep 01 10:30:00 [05:00:00.075] TRACE: [3.574ms] select "directus_files"."modified_on", "directus_files"."tus_id", "directus_files"."tus_data", "directus_files"."id" from "directus_files" where "directus_files"."tus_id" is not null order by "directus_files"."id" asc limit $1 [100]
Sep 01 10:30:00 [05:00:00] GET /server/ping 200 24ms
Sep 01 10:30:03 [05:00:03.648] TRACE: [2.451ms] select 1 from "directus_sessions" where "token" = $1 and "user" is null and "share" = $2 and "expires" >= $3 limit $4 [qWqETNiQ4pTqf0DnAtZG-wAJ0m0u8Dufe7IXlirevnwMyOYwn7Deaocl361Bfgqp, 03e75f08-319a-4cd0-807f-b28aa3bd3613, Mon Sep 01 2025 05:00:03 GMT+0000 (Coordinated Universal Time), 1]
Sep 01 10:30:03 [05:00:03.663] ERROR: Cannot read properties of null (reading 'id')
Sep 01 10:30:03 err: {
Sep 01 10:30:03 "type": "TypeError",
Sep 01 10:30:03 "message": "Cannot read properties of null (reading 'id')",
Sep 01 10:30:03 "stack":
Sep 01 10:30:03 TypeError: Cannot read properties of null (reading 'id')
Sep 01 10:30:03 at getPermissionsForShare (file:///app/code/node_modules/@directus/api/dist/permissions/utils/get-permissions-for-share.js:23:28)
Sep 01 10:30:03 at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
Sep 01 10:30:03 at async fetchPermissions (file:///app/code/node_modules/@directus/api/dist/permissions/lib/fetch-permissions.js:22:20)
Sep 01 10:30:03 at async fetchAllowedFields (file:///app/code/node_modules/@directus/api/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js:13:25)
Sep 01 10:30:03 at async getAllowedSort (file:///app/code/node_modules/@directus/api/dist/database/get-ast-from-query/utils/get-allowed-sort.js:15:31)
Sep 01 10:30:03 at async getAstFromQuery (file:///app/code/node_modules/@directus/api/dist/database/get-ast-from-query/get-ast-from-query.js:39:28)
Sep 01 10:30:03 at async ItemsService.readByQuery (file:///app/code/node_modules/@directus/api/dist/services/items.js:385:19)
Sep 01 10:30:03 at async file:///app/code/node_modules/@directus/api/dist/controllers/items.js:68:18
Sep 01 10:30:03 }
Sep 01 10:30:03 [05:00:03] GET /items/form_responses 500 24ms

A sample JWT obtained from /shares/auth

The corresponding entry in the db (which does include the role) →

image

Isn’t it necessary for the above JWT to also have the role set?


Does this seem like a bug in Shares’ permissions system?

That’s definitely strange and on my first attempt when I thought I messed up, I ran into the same issue on a v11.8.0. After creating a new collection, that error was gone, but I did not figure out that i had not set a role, so i spun up a fresh v11.11.0 instance and continued there.

So yeah, possibly a bug which I could not reproduce on v11.11.0 yet .
What version are you running?

Alright, back with some more info from my v11.8.0.

  1. My cause for Cannot read properties of null (reading 'id')
    Pretty stupid but subtile failure on my side. For some reasons I named this collection with an capital initial letter which i usually don’t do. Since Directus capitalizes all collection names on the collection view it was not so obvious when i created the share. When I then tested access with Postman I ofc used lowercase for the collection slug. :winking_face_with_tongue:

  2. READ permission need to be set on the item’s ID field, even if you just want to grant UPDATE and I also assume DELETE permission for the shares role. So in fact I would say READ on ID is required in any case.

  3. My JWT has also no role claim.
    So I would think that’s ok.

  4. The 500 I was talking about
    Is caused when requesting /shares/auth for a password protected share without setting the password in the payload. This returns a INTERNAL_SERVER_ERROR and is logged as

[18:41:02.330] ERROR: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined

err: {

  "type": "TypeError",

  "message": "The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined",

  "stack":

      TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined

          at Function.from (node:buffer:325:9)

          at Object.verify (/directus/node_modules/.pnpm/argon2@0.41.1/node_modules/argon2/argon2.cjs:174:24)

          at SharesService.login (file:///directus/node_modules/.pnpm/@directus+api@file+api_@types+node@22.13.8_@unhead+vue@1.11.20_vue@3.5.13_typescript@5.8.2____jigekj2vspo2admkgggvl64evi/node_modules/@directus/api/dist/services/shares.js:70:53)

          at process.processTicksAndRejections (node:internal/process/task_queues:105:5)

          at async file:///directus/node_modules/.pnpm/@directus+api@file+api_@types+node@22.13.8_@unhead+vue@1.11.20_vue@3.5.13_typescript@5.8.2____jigekj2vspo2admkgggvl64evi/node_modules/@directus/api/dist/controllers/shares.js:30:52

  "code": "ERR_INVALID_ARG_TYPE"

}

[18:41:02] POST /shares/auth 500 3ms

That’s definitely a minor bug, but sure not related to your problem.

Conclusion

I would say it’s basically working for me, even on the older v11.8.0 and I hope your issue can be resolved by either 1. or 2.

Just reviewed you logs again. You are querying the whole collection

Sep 01 10:30:03 [05:00:03] GET /items/form_responses 500 24ms

The access token returned by /shares/auth is always scoped to a single item. So you have to query this specific item instead.

GET /items/form_responses/SHARED_ITEM_ID

That isn’t an issue at all. If only 1 item is permitted, then just that will be returned when querying the collection.

Btw, the root cause has been identified now, see: Share auth tokens not working · Issue #25774 · directus/directus · GitHub and a fix should be available soon (i hope).

Oh wow, good catch!

You are absolutely correct about that :zipper_mouth_face: