> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apivalk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Apivalk features a robust, OpenAPI-compliant security and authorization system.

The security system in Apivalk is designed to be extensible, type-safe, and fully compatible with OpenAPI 3.0 standards. It handles everything from identifying the requester to enforcing granular permissions via scopes.

## Core Concepts

The security layer consists of four main pillars:

1. **[Identities](/security/identity)**: Objects representing the current requester (e.g., a logged-in user or a guest).
2. **Scopes and Permissions**: Granular strings that define what an identity is allowed to do.
3. **[Authenticators](/security/authenticator)**: Services that turn credentials (like a JWT) into an Identity.
4. **[Middleware](/middleware/security)**: The glue that executes authentication and enforces authorization on routes.

## The Security Flow

1. **Request Arrival**: An HTTP request enters the application.
2. **Authentication**: An authentication middleware (like `AuthenticationMiddleware`) uses an `Authenticator` to identify the requester and sets an `AuthIdentity` on the request.
3. **Authorization**: The `SecurityMiddleware` compares the `AuthIdentity`'s granted scopes and permissions against the `RouteAuthorization` defined in the `Route`.
4. **Controller**: If authorized, the controller receives the request and can access the identity via `$request->getAuthIdentity()`.

## Route Security Levels

Apivalk supports three levels of route security. The level is determined by whether a `RouteAuthorization` is present and what scopes/permissions it requires.

### 1. Public Route (No Authentication)

A route without a `RouteAuthorization` is fully public. Anyone can access it, including anonymous users. The `SecurityMiddleware` passes the request through without any checks.

```php theme={null}
use apivalk\apivalk\Router\Route\Route;

$route = Route::get('/about')->description('About page');
```

### 2. Authenticated Route (No Specific Scopes)

A route that requires the user to be authenticated but does not require any specific scopes or permissions. This is useful for endpoints like "get my profile" where you just need to know the user is logged in.

Pass a `RouteAuthorization` with only the security scheme name and omit (or pass empty arrays for) scopes and permissions. The `SecurityMiddleware` will still enforce that the user is authenticated (not a `GuestAuthIdentity`), returning a `401 Unauthorized` for anonymous requests.

```php theme={null}
use apivalk\apivalk\Router\Route\Route;
use apivalk\apivalk\Security\RouteAuthorization;

$route = Route::get('/me/profile')
    ->description('Get my profile')
    ->routeAuthorization(new RouteAuthorization('BearerAuth'));
```

### 3. Scoped Route (Specific Scopes and/or Permissions)

A route that requires the user to be authenticated **and** possess specific scopes and/or permissions. The `SecurityMiddleware` checks each required scope and permission against the user's identity:

* Missing scope/permission + authenticated user = `403 Forbidden`
* Missing scope/permission + anonymous user = `401 Unauthorized`

```php theme={null}
use apivalk\apivalk\Router\Route\Route;
use apivalk\apivalk\Security\RouteAuthorization;

$route = Route::get('/admin/settings')
    ->description('Admin Settings')
    ->routeAuthorization(
        new RouteAuthorization('BearerAuth', ['admin:settings'], ['admin:settings:read'])
    );
```

In this example, the route requires a security scheme named `BearerAuth` with the `admin:settings` scope and `admin:settings:read` permission.

### Connection to OpenAPI

The first argument of `RouteAuthorization` is the security scheme name. **This name must match the `name` parameter of a `SecuritySchemeObject` in your `ComponentsObject`.** This is how Apivalk connects a route to its security definition in the generated OpenAPI spec, and how Swagger UI knows to show the "Authorize" button for that endpoint.

```
ComponentsObject → SecuritySchemeObject::http('api', ...)
                                              │
                                              ▼
Route → routeAuthorization(new RouteAuthorization('api', [...], [...]))
```

If the names match, Apivalk uses your full configuration (descriptions, flows, bearer format, etc.) in the generated Swagger file. If they don't match, Apivalk will generate a basic placeholder scheme automatically.

> Keep in mind: Future Auto-Discovery. Apivalk is moving towards full auto-discovery of security schemes. In the future, it will be able to automatically detect and document your security configuration (including names and versions) directly from your middleware and authenticators.

See the [OpenAPI Generator documentation](/documentation/openapi-generator#security-schemes-and-components) for full examples including JWT Bearer, API Key, and OAuth2 setups.

## Examples: Getting Started with Middleware

To use the security system, you typically need to register two middlewares in your `MiddlewareStack`.

### 1. Authentication Middleware

The [Authentication Middleware](/middleware/authentication) identifies the user. It uses an authenticator to turn a token into an identity.

<a id="authentication-middleware" />

```php theme={null}
use apivalk\apivalk\Security\Authenticator\JwtAuthenticator;
use apivalk\apivalk\Middleware\AuthenticationMiddleware;

$authenticator = new JwtAuthenticator(
    'https://example.com/.well-known/jwks.json',
    $cache, // Instance of CacheInterface or null
    'https://example.com/',
    'my-api-audience'
);

$configuration->addMiddleware(new AuthenticationMiddleware($authenticator));
```

### 2. Security Middleware

The [Security Middleware](/middleware/security) enforces the scopes defined on your routes. It MUST run after the authentication middleware.

<a id="security-middleware" />

```php theme={null}
use apivalk\apivalk\Middleware\SecurityMiddleware;

$configuration->addMiddleware(new SecurityMiddleware());
```

### Full Example: All Three Security Levels

Here is how you would define routes with different security requirements:

```php theme={null}
use apivalk\apivalk\Router\Route\Route;
use apivalk\apivalk\Security\RouteAuthorization;

// PUBLIC: No security requirements — anyone can access
$publicRoute = Route::get('/about')->description('About us');

// AUTHENTICATED: Requires any valid token, no specific scopes
$authenticatedRoute = Route::get('/me/profile')
    ->description('Get my profile')
    ->routeAuthorization(new RouteAuthorization('BearerAuth'));

// SCOPED: Requires valid token with specific scopes and permissions
$scopedRoute = Route::post('/orders')
    ->description('Create order')
    ->routeAuthorization(
        new RouteAuthorization('BearerAuth', ['order'], ['order:create'])
    );
```

For more details on custom logic, check the [Custom Authentication](/middleware/authentication#custom-authentication-logic) section.
