domainflow / security
Framework-neutral authentication and authorization contracts with PSR-compatible HTTP adapters for DomainFlow applications.
Requires
- php: ^8.4
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- domainflow/core: ^0.2.0
- domainflow/http: ^0.1.0
- friendsofphp/php-cs-fixer: ^3.95
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^2.2
- phpstan/phpstan-deprecation-rules: ^2.0
- phpunit/phpunit: ^13.0
- symfony/phpunit-bridge: ^8.0
Suggests
- domainflow/core: Registers optional security services during application bootstrap.
- domainflow/http: Provides the DomainFlow PSR-15 HTTP kernel and endpoint dispatch.
- firebase/php-jwt: Can back an application-owned JWT verification adapter.
- league/oauth2-server: Can back an application-owned OAuth2 authorization-server adapter.
- nyholm/psr7: Provides PSR-7 and PSR-17 implementations for applications.
README
Framework-neutral authentication and authorization contracts for DomainFlow applications, with PSR-compatible HTTP adapters.
domainflow/security answers two questions without choosing a framework or
identity provider:
- Who is calling? An
Authenticatorturns a credential into an immutableAuthenticationOutcomeandPrincipal. - May that caller perform an operation? An
AuthorizationPolicyevaluates aSecurityContextand anAuthorizationRequirement.
The package supports application-owned adapters for API keys, OAuth/OIDC, JWT, Keycloak, Symfony Security, Laravel guards, sessions, mTLS, or custom providers. Provider libraries and provider objects stay outside the base package.
Install
composer require domainflow/security
PHP 8.4+ and the PSR HTTP message/server/factory contracts are required. A concrete PSR-7 implementation, such as Nyholm PSR-7, belongs to the application.
Optional integrations:
domainflow/coreregisters configured security services during bootstrap.domainflow/httpprovides the generic endpoint-context seam and HTTP kernel.domainflow/openapican describe operation security requirements.
Authentication and authorization
Implement the stable ports in the application or an adapter package:
use DomainFlow\Security\Authentication\AuthenticationFailure; use DomainFlow\Security\Authentication\AuthenticationOutcome; use DomainFlow\Security\Authentication\Authenticator; use DomainFlow\Security\Authentication\Credential; use DomainFlow\Security\Principal; final readonly class ApiTokenAuthenticator implements Authenticator { public function authenticate(Credential $credential): AuthenticationOutcome { $identifier = $this->lookup($credential->value()); return $identifier === null ? AuthenticationOutcome::failed(new AuthenticationFailure('invalid_credentials')) : AuthenticationOutcome::authenticated(new Principal($identifier)); } private function lookup(string $token): ?string { // Delegate token verification to the application/provider adapter. return $token === 'example-token' ? 'service-1' : null; } }
The raw credential is never placed in the Principal. Authorization remains
an explicit application policy:
use DomainFlow\Security\Authorization\AuthorizationRequirement; $requirement = new AuthorizationRequirement( 'orders.read', ['scheme' => 'oauth2', 'scopes' => ['orders:read']], ); $decision = $policy->decide($context, $requirement);
Provider examples
The examples/ directory contains dependency-free seams for custom token
stores, Keycloak/OIDC claim verification, Symfony Security identity mapping,
and Laravel guard identity mapping. Replace the example verifier/guard ports
with the concrete provider package in your application. The base package does
not install those providers.
Development
composer test-all composer phpstan composer lint composer quality
The package targets PHP 8.4 and 8.5, PHPStan level 10, strict formatting, dependency auditing, and full reachable-source line coverage.
License
MIT license.