sajad torkamani

In a nutshell

The API Platform security layer is built on top of the Symfony Security component which means you can use features like global access control directives. API Platform lets you apply access control expressions at the resource or operation level like so:

<?php
// api/src/Entity/Book.php

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Secured resource.
 *
 */
 #[ORM\Entity]
 #[ApiResource(
    attributes: ["security" => "is_granted('ROLE_USER')"],
    collectionOperations: [
        "get",
        "post" => ["security" => "is_granted('ROLE_ADMIN')"],
    ],
    itemOperations: [
        "get",
        "put" => ["security" => "is_granted('ROLE_ADMIN') or object.owner == user"],
    ],
)]
class Book
{
    #[ORM\Id, ORM\Column, ORM\GeneratedValue]
    private ?int $id = null;

    #[ORM\Column]
    #[Assert\NotBlank]
    public string $title;

    #[ORM\ManyToOne]
    public User $owner;

    // ...
}

Access control checks in the security attribute are executed before the denormalization step. This means that for PUT or PATCH requests, object will be the value stored in the persistence layer, not the value submitted by the user.

Sources