acrnogor/symfony-opa-form
Symfony middleware for authorization via build.security PDP/Open Policy Agent. Configure PDP host/port/policy path and timeouts in services.yaml, then use the OpenPolicyAgent service to send authz checks. Requires PHP 8+ and Symfony 4.4+.
Installation
composer require buildsecurity/symfony-opa
Verify PHP 8.0+ and Symfony 4.22+ compatibility.
Configure PDP Connection
Add to config/packages/security.yaml (or services.yaml):
parameters:
pdp:
hostname: "http://localhost" # or your PDP endpoint
port: 8181
policy_path: "/authz/allow"
read_timeout_ms: 5000
connection_timeout_ms: 3000
First Use Case: Basic Middleware Integration
Add to config/packages/security.yaml under firewalls:
firewalls:
main:
middleware: [buildsecurity_opa]
# ... other middleware
Define Input/Output Format
Create a opa_input.yaml in config/packages/ to define request/response mappings:
opa:
input:
path: "request.attributes" # Symfony request attributes
fields:
- "user.id"
- "resource.id"
output:
path: "result.allow"
Test Locally Use the standalone Docker PDP for development.
Request Attributes Injection
Populate request.attributes in controllers or event listeners:
$request->attributes->set('user.id', $user->id);
$request->attributes->set('resource.id', $resource->id);
Policy Evaluation The middleware automatically:
request.attributes → OPA input.pdp.policy.path.result.allow (boolean).Decision Handling Use Symfony voters or access control:
# security.yaml
access_control:
- { path: ^/admin, roles: ROLE_ADMIN, opa: { allow: true } }
opa_input.yaml to adapt to new resource types.StashBundle).access_control for hybrid auth:
access_control:
- { path: ^/profile, roles: ROLE_USER, opa: { allow: true, fallback: true } }
$this->getContainer()->get('buildsecurity_opa.client')->setMockResponse(true);
Extend the default format via a service:
# config/services.yaml
services:
App\Opa\CustomInputMapper:
tags: [buildsecurity_opa.input_mapper]
arguments:
$inputPath: "request.attributes.custom"
Timeouts
read_timeout_ms (5s) may be too short for slow PDPs.services.yaml or handle timeouts gracefully:
// In a subscriber
if ($event->isGranted() === false && $event->getThrowable() instanceof \RuntimeException) {
$event->allowIf($event->getThrowable()->getMessage() === 'PDP timeout');
}
Input Mismatch
opa_input.yaml cause silent failures.# config/packages/monolog.yaml
handlers:
opa:
type: stream
path: "%kernel.logs_dir%/opa.log"
level: debug
CORS/Network Issues
curl to verify PDP accessibility:
curl -X POST http://localhost:8181/authz/allow -d '{"input": {"user.id": 123}}'
Policy Versioning
/authz/allow) breaks if policies change.parameters:
pdp.policy.path: "%env(OPA_POLICY_PATH)%"
Policy Development Use build.security’s playground to test policies before integrating.
Performance Batch requests for multiple resources:
// In a controller
$request->attributes->set('resources', [$id1, $id2]);
// Update opa_input.yaml to handle arrays
Error Handling Customize error responses via a subscriber:
$event->setResponse(new JsonResponse(['error' => 'Policy denied'], 403));
Extension Points
buildsecurity_opa.pre_process event to modify input.buildsecurity_opa.post_process to transform output.Docker Tips
For local development, mount opa_input.yaml into the PDP container for hot-reloading:
# docker-compose.yml
volumes:
- ./config/packages/opa_input.yaml:/etc/opa/opa_input.yaml
How can I help you explore Laravel packages today?