ServiceStack allows you to configure 'global filters', which can intercept all requests.
I solved my problem using a global filter:
public static void Validate(IRequest request, IResponse response, object message)
{
var httpRequest = ((ListenerRequest)request).HttpRequest;
var consoleCert = httpRequest.GetClientCertificate();
...
I can then send 403 if the client certificate is not present or is invalid:
response.StatusCode = 403;
response.EndRequest();
return;
Not sure if this is the recommended approach (or indeed if there is a recommended approach, but it works for me.