I decided to go with silex's middleware function 'before'. I'm sure this probably isn't the best way to go about this, but my app doesn't have users or authentication so I just need to check the key is correct and return the response. If anyone has any comments on improving this I'd love to hear them.
When an external system is generating a url they must use the shared secret key defined in my config file, and accessible through $app['config']['hmac_key']. the hmac is generated on everything after the hmac in the path. so if ive got sub folders domain.com/folder/hmac/arg1/arg2/arg3. The before filter splits the route at the hmac and builds the path after that.
// Before firing the controller check the hmac matches, otherwise return 403.
$app->before(function (Request $request) use ($app) {
// 40 chars in a sha1 hmac hash
if(!preg_match('/^[0-9a-f]{40}$/i', $request->get('hmac')))
$app->abort(403, "Invalid key.");
// break the route down to the arguments used in hmac
$route = explode('hmac_', $request->get('_route'));
$route = explode('_',$route[1]);
// build the path used to generate hmac
$path = array();
foreach($route as $r)
if($v = $request->get($r))
$path[] = $v;
$path = implode('/', $path);
// Generate hmac hash from path and key
$hmac = hash_hmac("sha1", $path, $app['config']['hmac_key']);
// If the hmac's don't match return 403
if($hmac !== $request->get('hmac'))
$app->abort(403, "Invalid key.");
});