Enterprise Middleware

OAuth2 JWT Middleware

Add OAuth 2 Authentication with JWT validation to your Kipchak API.

Introduction

Note: This middleware is only available with Kipchak Enterprise.

The Auth JWT middleware provides a secure, automated way to verify JSON Web Tokens (JWTs) against a a public key. It is designed to integrate seamlessly with OpenID Connect (OIDC) providers such as Keycloak, Auth0, or Okta.

Key features include:

  • Scope Validation: Enforces access control by checking for required scopes (e.g., email, profile) within the token.
  • CORS Support: Built-in handling for OPTIONS preflight requests.
  • Path Whitelisting: Easily exclude specific routes (like health checks) from authentication requirements.

Installation

To install this middleware, you need to access the Enterprise Composer repository at https://php.pkgs.1x.ax.

If you have an enterprise licence, please contact your account representative for access.

Once you have access (see https://getcomposer.org/doc/articles/authentication-for-private-packages.md on how to configure access once you have credentials), install the middleware via composer by running:

composer require kipchak/middleware-auth-jwt

Configuration

The configuration in kipchak.auth.jwt.php can be used to configure this middleware. This file defines the identity provider connection and validation rules.

Global Settings

  • enabled (bool): Master switch. Set to true to enforce authentication globally.
  • publicKey (string): Required. Base 64 encoded public key from the identity provider.
  • algorithm (string): The signing algorithm, such as RS256 (default) or ES256.

Request Handling

  • ignore_options (bool): If true, OPTIONS requests (used for CORS preflight checks) are allowed through without a token.
  • ignore_paths (array): A list of URI paths that should be publicly accessible.
    • Default: ['/status']

Scope Validation

  • validate_scopes (bool): If true, the middleware will verify that the token contains the specific scopes listed in the scopes array.
  • scopes (array): The list of required scopes that must be present in the JWT for the request to be authorized.
    • Default: ['email', 'profile']

Usage

Once enabled, the middleware inspects the Authorization header of incoming requests. It expects a Bearer Token format:

Authorization: Bearer <token>

Basic Workflow

  1. Header Check: The middleware looks for the Authorization header. If missing, the request is denied (unless the path is in ignore_paths).
  2. Signature Verification: The token's signature is validated against the base64-encoded publicKey, with algorithm (default RS256).
  3. Expiration Check: The middleware ensures the token is not expired (exp claim).
  4. Scope Check: If validate_scopes is enabled, it ensures the token claims include the required permissions.

Using the verified token

Once a token is verified, its claims are on the request as the kipchak.auth.token attribute, a stdClass:

use Kipchak\Middleware\Auth\JWT\Handlers\AuthJWT;

$token = $request->getAttribute(AuthJWT::ATTRIBUTE_TOKEN);   // 'kipchak.auth.token'
$userId = $token->sub;
$clientId = $token->client_id ?? $token->azp ?? null;

Requests on ignore_paths, and preflight requests when ignore_options is on, do not carry it.

The middleware also still stores the token in the container under token, for compatibility. Prefer the attribute: in FrankenPHP worker mode the container lives for the whole worker, so that entry still holds the previous caller's token on later requests that carry none.

Usage Metering and Quotas read the verified claims through Consumer Identity, for example to bill each client_id or to take the plan from a plan claim. Run this middleware globally for that, so that it runs before them.

Customizing Validation per Route

While the config file sets global defaults, you can pass custom scopes when assigning the middleware to specific routes. See the implementation in the starter project, for example.

Upgrading

Earlier releases read each setting as if it were a config file of its own, so none of kipchak.auth.jwt was applied: 'enabled' => true did not enable the middleware globally, ignore_paths and ignore_options were not honoured, and a middleware attached to a route failed every request that carried a token. All settings are now read from kipchak.auth.jwt.

Check enabled before upgrading. If it is true, the middleware will now authenticate every request that is not in ignore_paths, which it did not do before. Set it to false if you attach the middleware to routes yourself.

Git Repository

The source code for this middleware is hosted internally.

Previous
Subashi WAF