A plain PHP application demonstrating API authorization using AuthAction with JWKS-based JWT validation. No framework required — runs with the PHP built-in server.
This application shows how to configure and handle authorization using AuthAction's access tokens in a plain PHP API. It validates JSON Web Tokens (JWT) signed with RS256 by fetching public keys dynamically from AuthAction's JWKS endpoint.
- PHP 8.2+ and Composer
- AuthAction credentials:
tenantDomainandapiIdentifierfrom your AuthAction account.
-
Clone the repository:
git clone git@github.com:authaction/authaction-php-example.git cd authaction-php-example -
Install dependencies:
composer install
-
Configure your AuthAction credentials:
cp .env.example .env
Edit
.envand replace the placeholders:AUTHACTION_DOMAIN=your-authaction-tenant-domain AUTHACTION_AUDIENCE=your-authaction-api-identifier
-
Start the development server:
php -S localhost:8000 -t public
The API will be available at
http://localhost:8000. -
Obtain an access token via client credentials:
curl --request POST \ --url https://your-authaction-tenant-domain/oauth2/m2m/token \ --header 'content-type: application/json' \ --data '{ "client_id": "your-authaction-app-clientid", "client_secret": "your-authaction-app-client-secret", "audience": "your-authaction-api-identifier", "grant_type": "client_credentials" }'
-
Call the public endpoint (no token required):
curl http://localhost:8000/public
{ "message": "This is a public message!" } -
Call the protected endpoint with the access token:
curl --request GET \ --url http://localhost:8000/protected \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'{ "message": "This is a protected message!", "sub": "client-id@clients" }
authaction-php-example/
├── public/
│ └── index.php # Entry point: simple router + route handlers
├── src/
│ └── JwtValidator.php # JWKS fetching, in-memory caching, JWT validation
├── .env.example
├── composer.json
└── README.md
-
getJwks()— Fetches public keys fromhttps://{AUTHACTION_DOMAIN}/.well-known/jwks.jsonand stores them in a static property for the lifetime of the request. On key rotation (kid not found), the cache is busted and the JWKS is re-fetched once. -
verify()— Decodes and validates the JWT usingfirebase/php-jwtwith:- Algorithm:
RS256 - Issuer:
https://{AUTHACTION_DOMAIN}(validated manually) - Audience:
{AUTHACTION_AUDIENCE}(validated manually)
- Algorithm:
GET /public— Accessible without authentication.GET /protected— Extracts theBearertoken from theAuthorizationheader, callsJwtValidator::verify(), and returns the decodedsub. Returns 401 on any validation failure.
Invalid token errors — Verify that AUTHACTION_DOMAIN and
AUTHACTION_AUDIENCE match the values in your AuthAction dashboard exactly.
Public key fetching errors — Check that your application can reach
https://{AUTHACTION_DOMAIN}/.well-known/jwks.json. You may need to enable
allow_url_fopen in php.ini.
Unauthorized access — Ensure the Authorization: Bearer <token> header is
present and the token was issued for the correct audience.
Feel free to submit issues or pull requests if you encounter bugs or have suggestions for improvement!