Securing Operations with the security Attribute
Securing Operations with the security Attribute
~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
The access_control rule from chapter 49 blanket-secures the ENTIRE /api area – the security attribute on an operation allows for FINER-GRAINED, resource-specific rules.
Restricting an operation to a role
use ApiPlatform\Metadata\Delete;
#[ApiResource(
operations: [
new GetCollection(),
new Get(),
new Post(),
new Put(),
new Patch(),
new Delete(security: "is_granted('ROLE_ADMIN')"),
],
// ...
)]
security accepts a SYMFONY EXPRESSION LANGUAGE expression – is_granted('ROLE_ADMIN') checks EXACTLY the same role as #[IsGranted] in a classic Symfony controller.
Testing the behavior
curl -k -i -X DELETE https://localhost/api/projects/1 \
-H "Authorization: Bearer $TOKEN"HTTP/2 403
{
"hydra:description": "Access Denied."
}Status 403 Forbidden – IMPORTANT: NOT 401. The token IS valid (the identity is KNOWN), but the ROLE isn't sufficient. 401 means "who are you?", 403 means "I know who you are, but you're NOT allowed to do this".
security on the whole resource
#[ApiResource(
security: "is_granted('IS_AUTHENTICATED_FULLY')",
operations: [ /* ... */ ]
)]
security at the RESOURCE level applies EQUALLY to ALL operations, IN ADDITION to any operation-specific rules – BOTH must be SATISFIED.
securityMessage for custom error messages
new Delete(
security: "is_granted('ROLE_ADMIN')",
securityMessage: 'Only administrators are allowed to delete projects.',
),EXACTLY like notInRangeMessage on constraints (chapter 21), securityMessage REPLACES the generic "Access Denied" message with a more DESCRIPTIVE, custom wording.
Tipp: object is available in security expressions to refer to the ENTITY in question, e.g. is_granted('ROLE_ADMIN') or object.getOwner() == user – chapter 52 explores this approach FURTHER with a custom voter instead of an INLINE expression.