Repository navigation
v9.3.0
defaults.authorization lets an integration YAML declare one shared authorization config that every action inherits instead of repeating the full dynamic-auth block on each one — with per-action override and an explicit false opt-out.
What's new
Most integrations protect many endpoints behind one token action. Before this release, every single action had to repeat the full type: dynamic block (action, token_field, ttl, ...) even when it was identical everywhere. Now declare it once:
defaults:
authorization:
type: dynamic
action: FetchToken
token_field: access_token
ttl: 3600
GetOrders:
action: App\...\GetOrdersAction
method: GET
path: /orders
# inherits the default dynamic authorization as-is
FetchToken:
action: App\...\FetchTokenAction
method: POST
path: /oauth/token
authorization: false # opts out of the default: this action itself is unauthenticatedResolution rules: no authorization: key inherits the default unchanged; authorization: false (or ~) opts out entirely; fields with no type or the same type as the default merge on top of it (action wins on conflict); a different type replaces the default wholesale. See ADR 0020 and the authorization docs.
Also hardened: an action's authorization: value that's none of a map, false, or ~/null (e.g. true) is now rejected eagerly when the YAML loads, instead of crashing later at dispatch time with an unrelated low-level error.
Documentation
docs/webhook.md now opens with an explicit three-layer request-flow diagram (bundle → Symfony Webhook/Messenger → your consumer), a "What happens if the event fails" section covering both rejection-before-acceptance and consumer failure under sync vs. async Messenger transports, and a concrete idempotent-receipt code example.
Validation
make qa: code style, static analysis and 904 tests (2,581 assertions) passed.