Skip to main content
The SecurityMiddleware is the core authorization engine of Apivalk. It ensures that the current requester has the necessary scopes and permissions to access a specific route. For a deep dive into the underlying architecture, check the Security Overview.
Coming from 3.1? Three things moved:
  • Security schemes are registered with ApivalkConfiguration::addSecurityScheme() instead of ComponentsObject::setSecuritySchemes(), and the generator reads them from there.
  • new SecurityMiddleware() now takes the scheme collection: new SecurityMiddleware($configuration->getSecuritySchemes()).
  • The fourth RouteAuthorization argument (the route audience) is gone. Put the audiences on the security scheme and point the route at that scheme.

How it Works

The middleware retrieves the Route object from the controller being called and examines its RouteAuthorization. The security schemes it resolves against are the ones registered on the ApivalkConfiguration, so it is constructed with that collection:

Authorization Logic

A route can have a RouteAuthorization object that defines:
  1. Security Scheme: The name of the security scheme required (e.g., BearerAuth). The name must match a scheme registered with ApivalkConfiguration::addSecurityScheme(): the middleware resolves it on every request and throws a LogicException when it is unknown. See Security Schemes and Components for full setup examples.
  2. Scopes: A list of required scopes.
  3. Permissions: A list of required permissions.
The current Identity must possess all the required scopes and permissions to be granted access. The audience is not part of the route: it belongs to the security scheme, because a token is issued for an API, not for a single endpoint. When the scheme lists audiences, the identity has to carry at least one of them.

Route Examples

Public Route (No Authorization)

A route that is accessible by anyone. When no RouteAuthorization is defined, the middleware passes the request through without any checks.

Authenticated Route (Any Valid Token)

A route that requires the user to be authenticated but does not enforce any specific scopes or permissions. Pass only the security scheme name to RouteAuthorization. The middleware will return 401 Unauthorized for anonymous users but allow any authenticated identity through.

Scoped Route (Specific Scopes and Permissions)

A route that requires a logged-in user with specific scopes and permissions.

Audience-Restricted Scheme

Routes that only accept tokens of a certain audience use their own scheme. The audiences are matched against AbstractAuthIdentity::getAud(), which for a JWT holds the aud claim; a token issued for several audiences passes as soon as one of them matches.

Optional Security (Public with Identity)

If you want a route to be public but also optionally use identity information when a token is provided, leave RouteAuthorization as null. The AuthenticationMiddleware will still populate the identity if a valid token is present — you can check $request->getAuthIdentity()->isAuthenticated() in your controller to adapt behavior.

Status Codes

When authorization fails, the middleware returns an error response directly — it does not throw. The checks run in this order:
  1. 401 Unauthorized (audience mismatch): Returned when the scheme lists audiences and the identity carries none of them, even when it is authenticated. A token issued for a different audience is not a missing privilege, it was never meant for this API, so the request is treated as unauthenticated rather than forbidden. Because this check runs first, such a token never learns which scope it lacks.
  2. 403 Forbidden, or 401 Unauthorized for a guest: Every required scope and then every required permission is checked in turn. An authenticated identity (e.g. JwtAuthIdentity) missing one gets a 403 Forbidden, a GuestAuthIdentity missing one gets a 401 Unauthorized.
  3. 401 Unauthorized: The final check. A GuestAuthIdentity (anonymous user) that got this far is rejected here, which is what makes a RouteAuthorization carrying only a scheme name mean “any authenticated user”.

Scopes and Permissions

While many frameworks use roles (e.g., ROLE_ADMIN), Apivalk follows the OpenAPI standard of using Scopes and Permissions. Scopes and permissions are more granular and describe what an identity is allowed to do (e.g., read:users) rather than who they are.

Integration

The SecurityMiddleware should always be placed after your authentication middleware in the stack.