ctors/pledge-symfony-routing
Install the Package
composer require ctors/pledge-symfony-routing
Ensure ext/pledge is installed on OpenBSD (see pecl-pledge).
Enable the Bundle
Add to config/bundles.php:
return [
// ...
ctors\PledgeSymfonyRoutingBundle\PledgeSymfonyRoutingBundle::class => ['all' => true],
];
First Use Case
Apply #[Pledge] and #[Unveil] to a controller method:
use ctors\PledgeSymfonyRoutingBundle\Attribute\Pledge;
use ctors\PledgeSymfonyRoutingBundle\Attribute\Unveil;
class SecureController extends AbstractController {
#[Route('/secure', name: 'secure')]
#[Pledge('stdio rpath')]
#[Unveil('/var/log', 'rw')]
public function secureEndpoint(): Response {
return new Response('Secure!');
}
}
Granular Route Security
Apply #[Pledge]/#[Unveil] per route or controller:
// Controller-level (applies to all routes)
#[Pledge('stdio rpath')]
class SecureController extends AbstractController { ... }
// Method-level (overrides controller-level)
#[Pledge('stdio rpath inet')]
public function dbEndpoint(): Response { ... }
Dynamic Unveil Paths
Use __DIR__ for relative paths:
#[Unveil(__DIR__.'/../storage', 'rwc')]
Fallback Pledges
Define default pledges in config/packages/pledge_symfony_routing.yaml:
pledge_symfony_routing:
default_pledge: 'stdio rpath'
pm.max_requests = 1 in www/conf.php-fpm.conf to avoid process reuse.#[Pledge('inet')]
public function __construct(private EntityManager $em) { ... }
pledge()/unveil() calls in unit tests using PHPUnit extensions.Overly Restrictive Pledges
#[Pledge('stdio')] blocks all file operations. Use rpath/wpath for filesystem access.pledge('stdio rpath', ...) in development.Unveil Order Matters
/ last is common:#[Unveil('/htdocs/storage', 'rwc')]
#[Unveil('/', 'r')] // Allow reading other files
FPM Pool Isolation
pm.max_requests = 1.Missing ext/pledge
Class 'ctors\PledgeSymfonyRoutingBundle\Attribute\Pledge' not found.pecl-pledge and restart PHP-FPM./var/log/system.log. Use:
tail -f /var/log/system.log | grep pledge
#[Pledge('')] // Disables all pledges (dev-only!)
Custom Attributes
Extend the bundle by creating your own attributes (e.g., #[DbPledge]):
#[Attribute]
class DbPledge implements PledgeInterface {
public function getPledge(): string { return 'inet'; }
}
Event Listeners
Listen to kernel.controller to dynamically adjust pledges:
$event->getController()->addAttribute(new Pledge('stdio rpath'));
Global Configuration
Override defaults in config/packages/pledge_symfony_routing.yaml:
pledge_symfony_routing:
default_unveils:
- { path: '/var/log', mode: 'rw' }
How can I help you explore Laravel packages today?