Claude Skill

br-jwks-jwt-auth

Configure Better Route 1.1 RS256 or ES256 JWT verification from a local or HTTPS JWKS. Use when integrating OIDC/OAuth bearer tokens, selecting keys by kid, validating issuer/audience/lifetime, or operating JWKS caching and refresh behavior safely.

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-jwks-jwt-auth-52f6020.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-jwks-jwt-auth
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 JWKS JWT authentication

Use Rs256JwksJwtVerifier for asymmetric bearer JWTs and adapt it to the generic bearer middleware.

use BetterRoute\Middleware\Auth\BearerTokenAuthMiddleware;
use BetterRoute\Middleware\Auth\JwtBearerTokenVerifierAdapter;
use BetterRoute\Middleware\Jwt\HttpJwksProvider;
use BetterRoute\Middleware\Jwt\Rs256JwksJwtVerifier;

$jwks = new HttpJwksProvider(
    jwksUri: 'https://issuer.example/.well-known/jwks.json',
    ttlSeconds: 3600,
    issuer: 'https://issuer.example',
    minimumRefreshIntervalSeconds: 30
);

$verifier = new Rs256JwksJwtVerifier(
    jwks: $jwks,
    leewaySeconds: 60,
    expectedIssuer: 'https://issuer.example',
    expectedAudience: 'my-api',
    requireExpiration: true,
    maxLifetimeSeconds: 3600,
    allowedAlgorithms: ['RS256'],
    kidMissRefreshCooldownSeconds: 30
);

$auth = new BearerTokenAuthMiddleware(
    verifier: new JwtBearerTokenVerifierAdapter($verifier),
    requiredScopes: ['orders:read']
);

$router->get('/orders', $handler)
    ->middleware([$auth])
    ->protectedByMiddleware('bearerAuth');

Verification contract

  • Require a non-empty JOSE alg and kid.
  • Allow only explicitly configured RS256 and/or ES256; none, HS*, and other algorithms are rejected.
  • Match kid to exactly one usable signing key. Ambiguous, incompatible, or absent matches fail closed.
  • Require exp by default. Setting maxLifetimeSeconds also requires iat and bounds exp - iat.
  • Pin both expectedIssuer and expectedAudience for production integrations.
  • Keep token size, clock leeway, and key-refresh cooldown bounded.

Remote JWKS behavior

HttpJwksProvider accepts HTTPS URLs only and rejects URL credentials. Its WordPress transport uses wp_safe_remote_get(), TLS verification, a ten-second timeout, at most one redirect, and a 256 KiB response limit.

It caches sanitized public keys in memory and a transient. Refreshes use a persistent cooldown and, when $wpdb is available, a bounded MySQL named lock. A failed refresh preserves the last known-good cached key set. A kid miss can trigger a refresh, but the verifier has its own cooldown to prevent attacker-driven fetch storms.

The better_route/jwks_refresh action clears matching caches. Supply the provider issuer so a targeted action does not flush unrelated providers. StaticJwksProvider is appropriate for pinned or test keys.

Operational checks

  • Confirm WordPress HTTP SSRF protection is not bypassed with a custom httpGet callback.
  • Exercise signing-key rotation: cached old key, new kid, refresh, then successful verification.
  • Exercise refresh failure and verify the last known-good set remains usable.
  • Test duplicate kid, wrong kty/crv, mismatched key alg/use, invalid signature, and stale token.
  • Never fetch a JWKS URL selected by an untrusted request.

Source references: src/Middleware/Jwt/HttpJwksProvider.php, src/Middleware/Jwt/Rs256JwksJwtVerifier.php, src/Middleware/Jwt/JwksKeySanitizer.php, src/Middleware/Auth/JwtBearerTokenVerifierAdapter.php.

References

Files (wp-agent-skills)
  • agents
    • openai.yaml 216 B
      interface:
        display_name: "Better Route JWKS JWT Auth"
        short_description: "Verify RS256/ES256 bearer JWTs from JWKS."
        default_prompt: "Use Better Route 1.1 JWKS JWT verification for an OIDC/OAuth bearer route."
      
  • SKILL.md 3.7 KB
    ---
    name: br-jwks-jwt-auth
    description: Configure Better Route 1.1 RS256 or ES256 JWT verification from a local or HTTPS JWKS. Use when integrating OIDC/OAuth bearer tokens, selecting keys by kid, validating issuer/audience/lifetime, or operating JWKS caching and refresh behavior safely.
    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.0"
      wp-skills-php-min: "8.1"
      wp-skills-last-updated: "2026-07-13"
    ---
    
    # Better Route JWKS JWT authentication
    
    Use `Rs256JwksJwtVerifier` for asymmetric bearer JWTs and adapt it to the generic bearer middleware.
    
    ```php
    use BetterRoute\Middleware\Auth\BearerTokenAuthMiddleware;
    use BetterRoute\Middleware\Auth\JwtBearerTokenVerifierAdapter;
    use BetterRoute\Middleware\Jwt\HttpJwksProvider;
    use BetterRoute\Middleware\Jwt\Rs256JwksJwtVerifier;
    
    $jwks = new HttpJwksProvider(
        jwksUri: 'https://issuer.example/.well-known/jwks.json',
        ttlSeconds: 3600,
        issuer: 'https://issuer.example',
        minimumRefreshIntervalSeconds: 30
    );
    
    $verifier = new Rs256JwksJwtVerifier(
        jwks: $jwks,
        leewaySeconds: 60,
        expectedIssuer: 'https://issuer.example',
        expectedAudience: 'my-api',
        requireExpiration: true,
        maxLifetimeSeconds: 3600,
        allowedAlgorithms: ['RS256'],
        kidMissRefreshCooldownSeconds: 30
    );
    
    $auth = new BearerTokenAuthMiddleware(
        verifier: new JwtBearerTokenVerifierAdapter($verifier),
        requiredScopes: ['orders:read']
    );
    
    $router->get('/orders', $handler)
        ->middleware([$auth])
        ->protectedByMiddleware('bearerAuth');
    ```
    
    ## Verification contract
    
    - Require a non-empty JOSE `alg` and `kid`.
    - Allow only explicitly configured `RS256` and/or `ES256`; `none`, `HS*`, and other algorithms are rejected.
    - Match `kid` to exactly one usable signing key. Ambiguous, incompatible, or absent matches fail closed.
    - Require `exp` by default. Setting `maxLifetimeSeconds` also requires `iat` and bounds `exp - iat`.
    - Pin both `expectedIssuer` and `expectedAudience` for production integrations.
    - Keep token size, clock leeway, and key-refresh cooldown bounded.
    
    ## Remote JWKS behavior
    
    `HttpJwksProvider` accepts HTTPS URLs only and rejects URL credentials. Its WordPress transport uses `wp_safe_remote_get()`, TLS verification, a ten-second timeout, at most one redirect, and a 256 KiB response limit.
    
    It caches sanitized public keys in memory and a transient. Refreshes use a persistent cooldown and, when `$wpdb` is available, a bounded MySQL named lock. A failed refresh preserves the last known-good cached key set. A `kid` miss can trigger a refresh, but the verifier has its own cooldown to prevent attacker-driven fetch storms.
    
    The `better_route/jwks_refresh` action clears matching caches. Supply the provider `issuer` so a targeted action does not flush unrelated providers. `StaticJwksProvider` is appropriate for pinned or test keys.
    
    ## Operational checks
    
    - Confirm WordPress HTTP SSRF protection is not bypassed with a custom `httpGet` callback.
    - Exercise signing-key rotation: cached old key, new `kid`, refresh, then successful verification.
    - Exercise refresh failure and verify the last known-good set remains usable.
    - Test duplicate `kid`, wrong `kty`/`crv`, mismatched key `alg`/`use`, invalid signature, and stale token.
    - Never fetch a JWKS URL selected by an untrusted request.
    
    Source references: `src/Middleware/Jwt/HttpJwksProvider.php`, `src/Middleware/Jwt/Rs256JwksJwtVerifier.php`, `src/Middleware/Jwt/JwksKeySanitizer.php`, `src/Middleware/Auth/JwtBearerTokenVerifierAdapter.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