Claude Skill

br-auth-middleware

Configure Better Route 1.1 authentication with JWT, custom bearer tokens, WordPress Application Passwords, or cookie nonces. Use when protecting routes, mapping verified claims to WordPress users, enforcing scopes, or consuming the shared AuthContext identity.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download Lonsdale201-wp-agent-skills-better-route_br-auth-middleware-8820ff3.zip · 2 KB
Part of lonsdale201/wp-agent-skills — 226 skills

Install

skills CLI npx skills add https://github.com/Lonsdale201/wp-agent-skills/tree/main/better-route/br-auth-middleware
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lonsdale201-wp-agent-skills@llmmart
Git git clone https://github.com/Lonsdale201/wp-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lonsdale201/wp-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Better Route authentication middleware

Select authentication by client type, attach it as middleware, and mark every raw route as middleware-protected. Better Route 1.1 denies every raw route by default, including GET and OPTIONS.

use BetterRoute\Middleware\Jwt\Hs256JwtVerifier;
use BetterRoute\Middleware\Jwt\JwtAuthMiddleware;

$auth = new JwtAuthMiddleware(
    verifier: new Hs256JwtVerifier(
        secret: MY_PLUGIN_JWT_SECRET,
        expectedIssuer: 'https://issuer.example',
        expectedAudience: 'my-api',
        maxLifetimeSeconds: 3600
    ),
    requiredScopes: ['orders:read']
);

$router->get('/orders/(?P<id>\d+)', $handler)
    ->middleware([$auth])
    ->protectedByMiddleware('bearerAuth');

Choose the middleware

  • Use JwtAuthMiddleware with Hs256JwtVerifier for first-party HS256 tokens.
  • Use BearerTokenAuthMiddleware with JwtBearerTokenVerifierAdapter and Rs256JwksJwtVerifier for RS256/ES256 JWKS tokens. Follow br-jwks-jwt-auth.
  • Use BearerTokenAuthMiddleware with a custom BearerTokenVerifierInterface for opaque or externally verified bearer tokens.
  • Use ApplicationPasswordAuthMiddleware for server-to-server WordPress Application Password Basic authentication.
  • Use CookieNonceAuthMiddleware for same-site browser requests with a logged-in WordPress cookie and X-WP-Nonce. Keep both requireNonce and requireLoggedIn enabled unless a separately reviewed design requires otherwise.

protectedByMiddleware() tells the WordPress permission callback to let the request reach the middleware pipeline. It does not add authentication by itself: the authentication middleware must also be attached. The optional name describes the OpenAPI security scheme.

JWT verification rules

  • exp is required by default. Do not disable requireExpiration for normal production tokens.
  • When maxLifetimeSeconds is set, both iat and exp are required and exp - iat must not exceed the limit.
  • Set expectedIssuer and expectedAudience in production.
  • Keep maxTokenLength bounded; the default is 8192 bytes.
  • Required-scope wildcards are server-controlled. A token-supplied granted scope ending in * expands authority only when allowGrantedScopeWildcards: true; keep that opt-in off unless the issuer contract requires it.

WordPress user mapping

WpClaimsUserMapper defaults to numeric user_id, uid, and wp_user_id claims. It deliberately does not interpret sub as a WordPress user ID and leaves email/login lookup disabled.

Prefer an issuer-scoped custom sub resolver. If email mapping is unavoidable, explicitly pass emailClaims and retain requireEmailVerified: true. Enable login-name mapping only for a fully controlled issuer. A mapped positive user ID becomes the native WordPress current user only during downstream execution (1.1.1).

Native user scope in 1.1.1

JWT, Bearer and Application Password middleware restore the previous WP user in finally, including exceptions. Nested calls unwind in reverse order. A verified JWT/Bearer identity without a positive WP mapping runs downstream as native user 0, never as an unrelated ambient user.

If you supply setCurrentUser, pair it with the appended optional getCurrentUser callback for the same identity store. The default getter calls get_current_user_id() or returns 0 outside WordPress. Previous constructor positions are unchanged.

WordPress permission callbacks run before middleware. Check middleware-established identity inside the downstream pipeline. Later rest_request_after_callbacks, rest_post_dispatch and _embed see the restored caller; use native WordPress request authentication when those phases need an authenticated user. Do not bypass permission checks or leave a global user set.

Shared identity

Successful built-in authentication writes a normalized identity into RequestContext::$attributes['auth'] with provider, userId, subject, and scopes. JWT/bearer claims and useful user fields are exposed through other context attributes. Ownership guards, rate-limit identity selection, and audit enrichment consume this shared contract; do not invent a parallel identity attribute.

Since 1.1.1, AuthContext::withIdentity() always replaces userId, user, claims and scopes, including null/empty values. Do not treat attribute presence alone as proof of a mapped user.

Checks

  • Verify mapped/unmapped identities, nested success/exception restoration, and the restored caller in response filters and embedding.
  • Test missing, malformed, expired, future, wrong-issuer, wrong-audience, and over-lifetime tokens.
  • Test every missing required scope and ensure a token-provided wildcard cannot widen authority unexpectedly.
  • Test routes without protectedByMiddleware() fail closed.
  • Never log bearer tokens, Basic credentials, cookies, nonces, or complete claims payloads.

Source references: src/Middleware/Jwt/*, src/Middleware/Auth/*, src/Router/RouteBuilder.php.

References

Files (wp-agent-skills)
  • agents
    • openai.yaml 271 B
      interface:
        display_name: "Better Route Auth Middleware"
        short_description: "Configure auth and scoped WordPress user identity."
        default_prompt: "Use $br-auth-middleware to configure authentication and verify native user restoration and response-filter boundaries."
      
  • SKILL.md 5.6 KB
    ---
    name: br-auth-middleware
    description: Configure Better Route 1.1 authentication with JWT, custom bearer tokens, WordPress Application Passwords, or cookie nonces. Use when protecting routes, mapping verified claims to WordPress users, enforcing scopes, consuming the shared AuthContext identity, restoring native users after nested dispatch, or diagnosing response-filter/_embed auth boundaries.
    metadata:
      wp-skills-author: "Soczó Kristóf"
      wp-skills-contact: "mailto:lonsdale201@hotmail.com"
      wp-skills-plugin: "better-route"
      wp-skills-plugin-version-tested: "1.1.1"
      wp-skills-php-min: "8.1"
      wp-skills-last-updated: "2026-09-21"
    ---
    
    # Better Route authentication middleware
    
    Select authentication by client type, attach it as middleware, and mark every raw route as middleware-protected. Better Route 1.1 denies every raw route by default, including `GET` and `OPTIONS`.
    
    ```php
    use BetterRoute\Middleware\Jwt\Hs256JwtVerifier;
    use BetterRoute\Middleware\Jwt\JwtAuthMiddleware;
    
    $auth = new JwtAuthMiddleware(
        verifier: new Hs256JwtVerifier(
            secret: MY_PLUGIN_JWT_SECRET,
            expectedIssuer: 'https://issuer.example',
            expectedAudience: 'my-api',
            maxLifetimeSeconds: 3600
        ),
        requiredScopes: ['orders:read']
    );
    
    $router->get('/orders/(?P<id>\d+)', $handler)
        ->middleware([$auth])
        ->protectedByMiddleware('bearerAuth');
    ```
    
    ## Choose the middleware
    
    - Use `JwtAuthMiddleware` with `Hs256JwtVerifier` for first-party HS256 tokens.
    - Use `BearerTokenAuthMiddleware` with `JwtBearerTokenVerifierAdapter` and `Rs256JwksJwtVerifier` for RS256/ES256 JWKS tokens. Follow `br-jwks-jwt-auth`.
    - Use `BearerTokenAuthMiddleware` with a custom `BearerTokenVerifierInterface` for opaque or externally verified bearer tokens.
    - Use `ApplicationPasswordAuthMiddleware` for server-to-server WordPress Application Password Basic authentication.
    - Use `CookieNonceAuthMiddleware` for same-site browser requests with a logged-in WordPress cookie and `X-WP-Nonce`. Keep both `requireNonce` and `requireLoggedIn` enabled unless a separately reviewed design requires otherwise.
    
    `protectedByMiddleware()` tells the WordPress permission callback to let the request reach the middleware pipeline. It does not add authentication by itself: the authentication middleware must also be attached. The optional name describes the OpenAPI security scheme.
    
    ## JWT verification rules
    
    - `exp` is required by default. Do not disable `requireExpiration` for normal production tokens.
    - When `maxLifetimeSeconds` is set, both `iat` and `exp` are required and `exp - iat` must not exceed the limit.
    - Set `expectedIssuer` and `expectedAudience` in production.
    - Keep `maxTokenLength` bounded; the default is 8192 bytes.
    - Required-scope wildcards are server-controlled. A token-supplied granted scope ending in `*` expands authority only when `allowGrantedScopeWildcards: true`; keep that opt-in off unless the issuer contract requires it.
    
    ## WordPress user mapping
    
    `WpClaimsUserMapper` defaults to numeric `user_id`, `uid`, and `wp_user_id` claims. It deliberately does not interpret `sub` as a WordPress user ID and leaves email/login lookup disabled.
    
    Prefer an issuer-scoped custom `sub` resolver. If email mapping is unavoidable, explicitly pass `emailClaims` and retain `requireEmailVerified: true`. Enable login-name mapping only for a fully controlled issuer. A mapped positive user ID becomes the native WordPress current user only during downstream execution (1.1.1).
    
    ## Native user scope in 1.1.1
    
    JWT, Bearer and Application Password middleware restore the previous WP user in `finally`, including exceptions. Nested calls unwind in reverse order. A verified JWT/Bearer identity without a positive WP mapping runs downstream as native user `0`, never as an unrelated ambient user.
    
    If you supply `setCurrentUser`, pair it with the appended optional `getCurrentUser` callback for the same identity store. The default getter calls `get_current_user_id()` or returns `0` outside WordPress. Previous constructor positions are unchanged.
    
    WordPress permission callbacks run before middleware. Check middleware-established identity inside the downstream pipeline. Later `rest_request_after_callbacks`, `rest_post_dispatch` and `_embed` see the restored caller; use native WordPress request authentication when those phases need an authenticated user. Do not bypass permission checks or leave a global user set.
    
    ## Shared identity
    
    Successful built-in authentication writes a normalized identity into `RequestContext::$attributes['auth']` with `provider`, `userId`, `subject`, and `scopes`. JWT/bearer claims and useful user fields are exposed through other context attributes. Ownership guards, rate-limit identity selection, and audit enrichment consume this shared contract; do not invent a parallel identity attribute.
    
    Since 1.1.1, `AuthContext::withIdentity()` always replaces `userId`, `user`, `claims` and `scopes`, including null/empty values. Do not treat attribute presence alone as proof of a mapped user.
    
    ## Checks
    
    - Verify mapped/unmapped identities, nested success/exception restoration, and the restored caller in response filters and embedding.
    - Test missing, malformed, expired, future, wrong-issuer, wrong-audience, and over-lifetime tokens.
    - Test every missing required scope and ensure a token-provided wildcard cannot widen authority unexpectedly.
    - Test routes without `protectedByMiddleware()` fail closed.
    - Never log bearer tokens, Basic credentials, cookies, nonces, or complete claims payloads.
    
    Source references: `src/Middleware/Jwt/*`, `src/Middleware/Auth/*`, `src/Router/RouteBuilder.php`.
    
    ## References
    
    - Official documentation: <https://lonsdale201.github.io/better-docs/docs/better-route/agents>
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related