How can I make some attributes of the File resource private?

When querying a REST endpoint of, for example, /api/authors?populate[0]=portrait&fields[0]=name&fields[1]=slug it responds with something like this:

{
  "attributes": {
    "name": "John Doe",
    "portrait": {
      "data": {
        "attributes": {
          "alternativeText": null,
          "caption": null,
          "createdAt": "2024-06-19T04:31:42.233Z",
          "ext": ".png",
          "formats": {
            "thumbnail": {
              "ext": ".png",
              "hash": "thumbnail_John_Doe_c92f92d636",
              "height": 156,
              "mime": "image/png",
              "name": "thumbnail_John_Doe.png",
              "path": null,
              "size": 0,
              "sizeInBytes": 0,
              "url": "/uploads/thumbnail_John_Doe_c92f92d636.png",
              "width": 156
            }
          },
          "hash": "John_Doe_c92f92d636",
          "height": 256,
          "mime": "image/png",
          "name": "John_Doe.png",
          "previewUrl": null,
          "provider": "local",
          "provider_metadata": null,
          "size": 0,
          "updatedAt": "2024-06-19T04:31:42.233Z",
          "url": "/uploads/John_Doe_c92f92d636.png",
          "width": 256
        },
        "id": 27
      }
    },
    "slug": "john-doe"
  },
  "id": 4
}

However, I’d like it to only respond with certain attributes of the File resource. So, the response will look like this:

{
  "attributes": {
    "name": "John Doe",
    "portrait": {
      "data": {
        "attributes": {
          "formats": {
            "thumbnail": {
              "url": "/uploads/thumbnail_John_Doe_c92f92d636.png"
            }
          },
          "url": "/uploads/John_Doe_c92f92d636.png"
        },
        "id": 27
      }
    },
    "slug": "john-doe"
  },
  "id": 4
}

Just to be clear, I’m not asking on how to omit those fields through the qury parameters. But rather, I want those fields to be inaccessible for anyone who queries the API.

This topic has been created from a Discord post (1252870356172148756) to give it more visibility.
It will be on Read-Only mode here.
Join the conversation on Discord

At first I thought maybe I can extend the upload controller to achieve this (@see Controllers | Strapi Documentation), I didn’t really understand it, but I think it’s related to extending the endpoints themselves, and not modify attribute settings.

For now, I was able to quickly achieve this using the register method in ./src/index.ts.

  const fileSchema = strapi.contentTypes['plugin::upload.file']
  const publicAttributes = ['url']
  // make all attributes private except for specified ones
  fileSchema.attributes = Object.keys(fileSchema.attributes).reduce((attributes, attributeKey) => {
    return {
      ...attributes,
      [attributeKey]: {
        ...fileSchema.attributes[attributeKey],
        ...(publicAttributes.indexOf(attributeKey) === -1 && { private: true }),
      }
    }
  }, {} as Schema.Attributes)

Summary: I’m overriding the file schema to make all attributes private except for the ones I need.

Maybe you can make use of privateAttributes? API calls configuration | Strapi Documentation

Thanks! Seems like what I wanted. Will give it a try!