IIS ClientAuthIssuer store

Windows has a native cert store named ClientAuthIssuer.

By default IIS will 'trust' CA roots in the Trusted Root Certification Authorities store. This means a client certificate trying to connect to IIS requires the issuing CA be in the Trusted Root store. BY DEFAULT

Sometimes you don't want IIS to 'trust' each/every CA that's in the default store. So Windows provides the ClientAuthIssuer store. By using netsh you can tell the site to use that store (vs the default). To my knowledge this can't be changed in the gui

You can view these values with: netsh http show sslcert

You can update these values with:

netsh http update sslcert hostnameport=blah.site.com:443 certhash=95476810cb8a39933a6d3f7b3db8458656a9488c appid={4dc3e181-e14b-4a21-b022-59fc669b0914} certstorename=My sslctlstorename=ClientAuthIssuer

So my problem - apparently the Let's Encrypt client (I'm using win-acme) doesn't understand this and simply clobbers this particular config, setting it back to the default store during cert renewal.

Is this an issue with the underlying ACME protocol or with the implementation?


The underlying ACME protocol just describes how one gets a certificate over the network. It doesn't have anything to do with how Windows (or any other OS) implements its TLS stack.

I might suggest trying out some of the other Windows clients and see if they integrate with your configuration better.


Just to be clear, you are specifically trying to use a client certificate yes? Not just a standard https certificate for an IIS binding?

This definitely has zero to do with ACME and everything to do with implementation and there are no windows acme clients which support this feature directly (you should log an issue with win-acme if you think this is necessary) - what you're trying to do is non-standard (this is the first I've seen it mentioned in 6 years of developing a windows ACME client) so you need to do more yourself to facilitate that.

Personally if I had trusted roots that I didn't want to be trusted I'd move them to untrusted.

1 Like

I'm sure :slight_smile:
So by default Microsoft trusts Comodo, Entrust, Go Daddy, Verisign, etc, etc. This OS level store is used by both client apps (web browers) but also by IIS.

Suppose I want IIS to ONLY accept client certs issued by XYZ CA (in this case, maybe I only want to allow connections from DOD issued certs). Microsoft allows IIS sites to be configured to use the Client Authentication Issuers store instead of the default Trusted Root Certification Authorities. While this can't be done via the IIS MMC snap-in (to my knowledge anyway) - it CAN be done via the netsh command line. Sometimes I'm asked to do this (devs, etc, etc).

I can setup the site to only accept certs issued by the CAs in the Client Authentication Issuers store - but then the ACME client clobbers that config upon renewal. I agree this is an implementation issue. I'm a bit surprised this has never come up before.

If I start mucking with the OS level store it will impact everything on the OS (so then my browser also won't trust Entrust, Digicert, etc)


1 Like

"from" ???

The problem, as best as I can figure, is created by trying to prevent IIS admins from binding sites to certs that should NOT be allowed.
That sounds more like a "policy issue" [layer 9] than something the O/S should be restricted from doing.
How many people have access to manage IIS (enough to bind certs to sites)?
How many people have enough rights to remove the CA restriction (using netsh, regedit, etc.)?
How many of those people know how to follow policy/procedures?

Me too.
Perhaps another ACME client won't have this "unintended side-effect"...
Have you tested with any other clients?


According to iis-docs/changes-in-security-between-iis-60-and-iis-7-and-above.md at main · MicrosoftDocs/iis-docs · GitHub this setting could previously be managed in the IIS metabase config (years ago) but it now part of http.sys and I don't see a way to set the default. I would go with a post-request script to update the binding or ask win-acme to to add it as a feature (they already have an option to select the certificate store, so you need an option to also specify the corresponding trust store).


Thank you for your feedback. Can you point me to any references on a post-request script?

1 Like

If you can script the changes that you need to happen, you can just have win-acme run that script after each renewal.


Thanks - this link is helpful.

1 Like

As a related aside, in case any Certify The Web users are looking for a solution to the same problem, the equivalent post-request scripting link for https://certifytheweb.com users is Scripting | Certify The Web Docs - You would add a "Run Powershell Script.." or "Run Script.." task under Tasks > Deployment Tasks and those can include user impersonation using stored credentials etc.

So for the equivalent powershell task script would be :


$hostname = $result.ManagedItem.RequestConfig.PrimaryDomain
$certhash = $result.ManagedItem.CertificateThumbprintHash

netsh http update sslcert hostnameport=$hostname:443 certhash=$certhash appid={4dc3e181-e14b-4a21-b022-59fc669b0914} certstorename=My sslctlstorename=ClientAuthIssuer

This assumes you are only updating one hostname (not multiple SAN bindings).


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.