Search by

kinetis / authorization

aln-1

Ability-based authorization for Kinetis — Gate wraps a callable Policy check, normalizing a bool/AuthorizationResponse result into an allow/deny decision and raising a denial as an exception that declares its own 403.

Package info

github.com/kinetis-dev/authorization

pkg:composer/kinetis/authorization

Statistics

Installs: 6

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.3 2026-09-13 11:01 UTC

This package is auto-updated.

Last update: 2026-09-13 11:15:49 UTC


README

Kinetis

kinetis/authorization
Ability-based authorization for Kinetis

Packagist Version Packagist Downloads PHP Version License CI

Part of Kinetis, a non-blocking PHP framework for API-first applications, developed in the kinetis-dev/kinetis monorepo.

Kinetis is deliberately unopinionated about how your application organizes authorization checks — there's no required Policy convention, no ability-name registry, and nothing here inspects an object's class to decide which code answers a check. Gate is a small, generic wrapper: hand it any callable and it normalizes the result into an allow/deny decision.

use Kinetis\Authorization\Gate;

final readonly class PostController
{
    public function __construct(
        private Gate $gate,
        private PostPolicy $postPolicy,
    ) {}

    public function update(int $id, CurrentUserInterface $user): array
    {
        $post = $this->posts->find($id);

        $this->gate->authorize($user, $this->postPolicy->update(...), $post);

        // ...
    }
}

$this->postPolicy->update(...) is PHP's own first-class callable syntax — PostPolicy is a plain, constructor-injected class with plain methods, resolved and called exactly like any other service. Gate never sees PostPolicy exist as a concept.

Provides

Nothing to register. AuthorizationException declares its own 403 through core's Kinetis\Http\Exception\HttpStatusExceptionInterface, so ExceptionHandlerMiddleware — included unconditionally — returns a denied Gate::authorize() call as that response from any route.

Gate itself needs no explicit binding either: it has no constructor dependencies, so plain autowiring resolves it wherever a controller constructor-injects it.

Nothing else. There's no middleware, no attribute to discover, no registry, and no "Policy" concept this package enforces — PostPolicy above is only a name a developer chose.

The three methods

  • authorize($user, $check, ...$arguments): void — throws AuthorizationException on denial, which core returns as a 403. Use it when a denial should hard-stop the request.
  • allows($user, $check, ...$arguments): bool — reports the decision instead of acting on it: a denial is false, not an exception. Use it to branch, or to shape a response value ('canEdit' => $gate->allows(...)).
  • denies($user, $check, ...$arguments): bool — the exact inverse of allows(), for guard-clause style (if ($gate->denies(...)) { ... }).

Neither allows() nor denies() catches anything the check itself throws — a check that fails outright is a failure, not a denial.

$check is any callable(CurrentUserInterface, mixed...): bool|AuthorizationResponse — a first-class callable reference to a method, a plain closure, or a Gate::allows()-independent function. Returning a plain bool covers the ordinary case; returning AuthorizationResponse::deny('a specific reason') lets a denial carry a message more useful than the generic default.

$check may also be typed against a concrete CurrentUserInterface implementation richer than the interface itself — kinetis/auth-jwt's JwtUser, say, whose claim()/claims() already carry everything the token decoded, with no query needed. Gate's methods are generic over the user type (@template TUser of CurrentUserInterface) precisely so this type-checks correctly. See kinetis.dev/docs/authorization.html.

Installation

composer require kinetis/authorization

Requires PHP 8.4 or later and kinetis/framework. Documentation: kinetis.dev/docs/authorization.html

License

MIT — see LICENSE.