nepada / security-annotations v4.1.0

Security annotations for Nette presenters and components.

download-cloud-line composer require nepada/security-annotations

Security Annotations

Build Status Coverage Status Downloads this Month Latest stable


Via Composer:

$ composer require nepada/security-annotations

Register the extension in config.neon:

    securityAnnotations: Nepada\Bridges\SecurityAnnotationsDI\SecurityAnnotationsExtension

The package relies on doctrine/annotations for parsing annotations. It's up to you to choose and set up the integration, the recommended package to do the job is nettrine/annotations.


This package builds on top of the standard access authorization of Nette components, namely Nette\Application\UI\Component::checkRequirements() method. This method is called before invoking any of component/presenter signal handlers, and before presenter startup, action<> and render<> methods.

With this package you can specify the access rules via annotations on any of the mentioned methods, or on presenter class. To enable this feature simple use SecurityAnnotations trait in any presenter or component and make sure RequirementsChecker service gets injected via injectRequirementsChecker() - with default Nette configuration this should work on presenters out of the box, but you need to take care of components, e.g. by enabling inject calls.


use Nepada\SecurityAnnotations\Annotations\Allowed;
use Nepada\SecurityAnnotations\Annotations\LoggedIn;
use Nepada\SecurityAnnotations\Annotations\Role;

 * @LoggedIn
 * To access this presenter the user must be logged in.
class SecuredPresenter extends Nette\Application\UI\Presenter

    use Nepada\SecurityAnnotations\SecurityAnnotations;

     * @Role({"admin", "superadmin"})
    public function actionForAdmins(): void
        // Only users with role admin or superadmin are allowed here.

     * @Allowed(resource="world", privilege="destroy")
    public function handleDestroyWorld(): void
        // Only users with specific permission are allowed to call this signal.


The annotations and rules they enforce are completely customizable (see below), however the default setup comes with three predefined rules:

  • @LoggedIn - checks whether the user is logged in.
  • @Role({"admin", "superadmin"}) - checks whether the user has at least one of the specified roles. If you use Nette\Security\Permission as your authorizator, then role inheritance is taken into account, i.e. users that have at least one role that inherits from at least one of the specified roles are allowed as well.
  • @Allowed(resource="world", privilege="destroy") - checks whether the user has at least one role that is granted the specified privilege on the specified resource.

Securing components

Properly securing components is a tricky business, take a look at the following example:

use Nepada\SecurityAnnotations\Annotations\LoggedIn;

class SecuredPresenter extends Nette\Application\UI\Presenter

    use Nepada\SecurityAnnotations\SecurityAnnotations;

     * @LoggedIn
    public function actionDefault(): void
        // ...

    protected function createComponentForm(): Nette\Application\UI\Form
        $form = new Nette\Application\UI\Form();
        $form->addSubmit('Do something dangerous');
        $form->onSuccess[] = function (Nette\Application\UI\Form $form): void {
            // ...
        return $form;


Securing presenter action<> (or render<>) methods is not sufficient! All it takes is a one general route in your router, e.g. a very common Route('<presenter>/<action>'), and anyone may successfully submit the form by sending POST request to /secured/foo URL.

You should always check user's permissions when creating the component. To make your life easier there is SecuredComponents trait that calls the standard Nette\Application\UI\Component::checkRequirements() method before calling the component factory. Combining it with SecurityAnnotations it allows you to control access to components via annotations on createComponent<> methods.

Customizing access validators

  • You can disable the default set of validators by enableDefaultValidators: false.
  • You can also define your own validators, i.e. services implementing Nepada\SecurityAnnotations\AccessValidators\AccessValidator interface in validators configuration section.
    enableDefaultValidators: false # disable default set of validators
        - MyRoleAccessValidator # define validator by class name
        - @fooAccessValidator # define validator by service reference
    fooAccessValidator: FooAccessValidator(%fooParameter%)

How do access validators work?

Every access validator implements Nepada\SecurityAnnotations\AccessValidators\AccessValidator interface. The access validator specifies which annotation type it supports via its public API.

When checking the requirements PHP attributes and all annotations parsed using doctrine/annotations are passed one by one to associated access validator for inspection. Based on the annotation value the validator decides either to deny access (throws Nette\Application\BadRequestException), or grant access (no exception is thrown).

PHP attributes support

Security annotations may be defined also via standard PHP attributes (introduced in PHP 8.0), e.g.

use Nepada\SecurityAnnotations\Annotations\LoggedIn;

class SecuredPresenter extends Nette\Application\UI\Presenter
    // ...

PHP attributes are the preferred way of specifying your security metadata. The support for legacy PHP DocBlock annotations will be removed in the future major version.

If you do not use legacy PHP DocBlock annotations, consider completely disabling doctrine annotations reader:

    enableDoctrineAnnotations: false
  • v4.1.0 4.1.0

    • PHP 8.0 compatiblity.
    • PHP attributes support:
      • Security metadata can be now specified via standard PHP attribute syntax (supported on PHP >= 8.0).
      • PHP attributes are preferred over legacy PHP DocBlock annotations. Next major version will support PHP attributes only.
    • Bundled annotations are now explicitly limited to class and method usage.
    • Bundled annotations now define getters for all properties, direct access to public properties is considered deprecated and will be removed in next major version.
    • New configuration option enableDoctrineAnnotations (true by default). Set it to false to disable legacy PHP DocBlock annotations support and test the application with PHP attributes only.
  • v4.0.0 4.0.0

    Backward incompatible changes

    • Annotation parsing rewritten from obsolete nette/reflection to doctrine/annotations. This changes how the security annotations are written, as well as how validators receive the parsed data.
    • Public API changes of AccessValidator: parsed annotation data are received as object, added method that specifies the supported annotation name.
    • Removed interface and trait name prefixes: IAccessValidator -> AccessValidator, TSecuredComponents -> SecuredComponents, TSecurityAnnotations -> SecurityAnnotations.
    • RequirementsChecker must be explicitly injected into presenters and components.
    • Removed SameSiteValidator - signals are protected by default in Nette 3.
    • Removed the possibility to dynamically configure validators used by RequirementsChecker.
    • Dropped support for custom exception messages in default validators.
  • v3.1.0 3.1.0

    • Requires PHP >=7.4.
    • Uses native property typehints.
  • v3.0.1 3.0.1

    • Replaced deprecated DI calls.
    • DI extension uses config schema.
    • PHP 7.4 compatibility.
  • v3.0.0 3.0.0

    • Nette 3 compatibility.
    • CI improvements.
  • v2.2.0 2.2.0

    • New default validator for @sameSite, using sameSite protection from nette/http.
  • v2.1.0 2.1.0

    • Refactored exception hierarchy - unlikely, but possible BC break.
  • v2.0.0 2.0.0

    • Default set of security annotations uses "camelCase" (BC break).
    • Trigger warning on case mismatch in annotation name.
  • v1.0.1 1.0.1

    • PHP 7.2 compatibility.
  • v1.0.0 1.0.0

    • Initial release requires Nette 2.4 and PHP 7.1.
    • Default validators for @LoggedIn, @Role, @Allowed annotations.
    • Trait for securing component factories






php (>=7.2.0)
nette/utils (^3.0@dev)
nette/security (^3.0@dev)
nette/http (^3.0.1@dev)
Componette Componette