How to restrict users to upload and delete documents within their own resources?

I want to implement a security policy in Strapi to limit document upload and deletion actions only to resources owned by users. How can I configure this restriction in Strapi to ensure data confidentiality and security? Any help or suggestions would be greatly appreciated. Thank you!

I am working on the same functionality. From what I see, the best way is to delete files using cron job which are not related to any entities (we don’t give users a right to delete files at all, but we give a right to remove relation between file and entity).

I ended up implementing the solution below for a content type “company” that contains a media field. To restrict permissions so that each user can only modify their own logo, I extended the functionalities of the Upload plugin by adding two new methods: uploadCheck and destroyCheck. These methods will check if the user is attempting to modify a document linked to a resource they own. If so, the method will then call the upload or destroy method depending on the situation. Thus, at the role level, I removed permissions on the upload and destroy APIs, as they are now controlled by the uploadCheck and destroyCheck methods.

To upload a media now, I call: POST http://localhost:1337/api/upload/check
To delete a media, I call: DELETE http://localhost:1337/api/upload/check/:id

//src/extensions/upload/strapi-server.ts
export default (plugin) => {

    plugin.controllers['content-api'].hasPermission = async (type, id, user) => {
        let granted = false;
        let owner;
        switch (type) {
            case 'api::company.company':
                owner = await strapi.service('api::company.company').getUserOwner(id)
                if (owner.id == user.id) {
                    granted = true;
                }
                break;
            default:
                break;
        }

        return granted;
    }

    plugin.controllers['content-api'].destroyCheck = async (ctx) => {
        const {
            params: { id },
        } = ctx;
        const user = ctx.state.user;
        const file = await strapi.plugin('upload').service('upload').findOne(id, 'related');
        if (!file) {
            return ctx.notFound('file not found');
        }

        let canDelete = false;
        if (file.related.length == 1) {
            canDelete = await plugin.controllers['content-api'].hasPermission(file.related[0].__type, file.related[0].id, user);
        }

        if (canDelete) {
            await plugin.controllers['content-api'].destroy(ctx);
        }

        return {
            result: canDelete
        }
    }

    plugin.controllers['content-api'].uploadCheck = async (ctx) => {
        const body = ctx.request.body;
        const user = ctx.state.user;

        if (!body && body.length != 3) {
            return ctx.notFound('payload error');
        }

        let canCreate = await plugin.controllers['content-api'].hasPermission(body.ref, body.refId, user);
        if (canCreate) {
            await plugin.controllers['content-api'].upload(ctx);
        }

        return {
            result: canCreate
        }
    }

    plugin.routes['content-api'].routes.push(
        {
            method: 'DELETE',
            path: '/check/:id',
            handler: 'content-api.destroyCheck',
        },
        {
            method: 'POST',
            path: '/check',
            handler: 'content-api.uploadCheck',
        }
    );

    return plugin;
}