I want to restrict access to a private website that needs to be accessible to multiple people.

In the event the website has public and private areas, a login to a user session is the usual solution.

In the event the website must be completely private, I typically use Apache configuration directives like 'Require ip'. The problem with these is that staff and the home office don't have state ip addresses and we spend an inordinate amount of time whitelisting and managing the conf files.

Is there some way to require a local file of some sort, perhaps something similar to a private/public key combination used by SSH? I've never heard of such a thing, and I tried searching without success. It would be very convenient if I could generate "authorization keys" (for lack of knowing the right term) and issue them to authorized staff.

Possession of such a key would permit the website to be accessed. Otherwise, the server would respond with Forbidden and the attempt would be logged.

Ideally the solution will work with Apache on our server and all of the various browsers used by our personnel.

  • Does this post answer your question? webmasters.stackexchange.com/questions/16243/… Sep 13, 2021 at 21:19
  • @MaximillianLaumeister Thank you. That looks very promising. I think "client-side certificate" must be the search term I wanted.
    – Timothy B.
    Sep 13, 2021 at 21:24
  • The answers in that other post look like they cover the basics of client side certs and provide a sample Apache config. Good luck, and feel free to submit another question if you run into any problems! Sep 13, 2021 at 21:30

1 Answer 1


Is there some way to require a local file of some sort, perhaps something similar to a private/public key combination used by SSH?

Yes, that is called an X509 certificate, the thing that everyone wrongly calls an "SSL" certificate. Webservers have them, but clients can have them too. Clients here in the sense of "HTTP browser" but acting on behalf typically of real clients, that are humans.

A typical "client" certificate identifies a specific given human being.

You can configure your webserver to reply only if the client provided a certificate and then you can decide which ones are correct or not (either listing them, or just allowing any of them from a specific CA or with a specific subject).

That is the easy part. See https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslrequire for Apache (but note that this part is deprecated, you should do the same thing with Require but that link gives concrete examples on filtering based on the client certificate).

Now the real difficult part, that will often be overcome, especially at the beginning, but which is crucial is: how are those client certificates generated, by whom, and how are they refreshed.

And related to that how/where they are installed: they need to be put in each browser, so if a client (human) uses multiple browsers from multiple devices, the certificate needs to be installed everywhere. And if some devices are smartphones, it may be very complicated to add customer user certificates there.

This setup typically happens on internal or corporate networks, where the company internally can ha a CA running and hence provide certificates to all its employees that will then use them from their browsers.

If you can do that, this is the highest form of control, but has the huge burden of needing to run your own CA, secure it, make it generate certificates and renew them, and (specially difficult) provide them in a secure fashion to the relevant people.

If you can't do that or do not want to run your own CA, you need to ask people to go "somewhere" to buy their own certificate (note that this can be cumbersome - like having to prove one's identity remotely -, costly, and taking time), and then make sure your system accepts them.

The above is typically suited for a website whose consumers are clients. If on the other end the consumer is an application, the above can work too but for various reasons (related to how client certificates are cumbersome to manage) most cases use instead an "API key" or some sort, which is basically just an opaque blob that is sent (typically as an HTTP header) at each query and the webserver checks that the value is among the list of allowed values. This is "kind of" bad, because it means it is a shared secret. It has to be protected (it is fine during the HTTP exchange itself because it is typically/should be over HTTPS, hence the secret is not exposed), and make sure not to leak it (putting it in git repository for example is a known problem), plus it does not solve the problem of implementing the good idea of rotating things regularly for good security hygiene.

BTW, it is not very clear why you reject that:

In the event the website has public and private areas, a login to a user session is the usual solution.

If you are fine with the idea, note that you can implement that without having to handle credentials yourself, that is you do not necessarily need to create local users and manage their passwords, you can offer to login through external identity providers (Google, Facebook, GitHub, etc.) and people will use their credentials at these providers to log in on your server. Of course it means you fully trust those providers to handle the authentication correctly.

Not the answer you're looking for? Browse other questions tagged or ask your own question.