Demystifying AutoSelectCertificateForUrls syntax
When a web server requires mutual TLS authentication, the default behavior of web browsers is to show a dialog that lets us choose which client certificate we’d like to use.
These certificate prompts can become annoying, so browsers provide ways to suppress them:
Internet Explorer and Edge Legacy offered a behavior (Don’t prompt for client certificate selection when only one certificate exists, URLACTION_CLIENT_CERT_PROMPT), on-by-default for the Local Intranet Zone.
This setting can be controlled locally in IE’s Security Settings or via group policy:
If you enable this policy setting, Internet Explorer does not prompt users with a "Client Authentication" message when they connect to a Web site that has no certificate or only one certificate. If you disable this policy setting, Internet Explorer prompts users with a "Client Authentication" message when they connect to a Web site that has no certificate or only one certificate.
Chromium follows a different approach:
Chromium (and thus Chrome, Edge, Brave, Opera, Vivaldi) largely does not use the concept of Zones, so instead the AutoSelectCertificateForUrls policy exists. This policy allows an IT administrator to configure clients to automatically send certificates to specified websites that request them, which can be used to satisfy the need to have, say, the user’s Windows Hello certificate sent to *.login.microsoft.com sites.
There’s no UI for configuring the AutoSelectCertificateForUrls policy, but we can manage the setting by using a group policy and the Chrome administrative templates:
If using a group policy isn’t an option, we can also create the registry entry
Software\Policies\Google\Chrome\AutoSelectCertificateForUrls
manually. In both
cases, the policy is a list of values, which the
Chrome documentation describes as:
[...] an array of stringified JSON dictionaries, each with the form { "pattern": "$URL_PATTERN", "filter" : $FILTER }, where $URL_PATTERN is a content setting pattern.
But what’s the format for the URL content setting pattern? Chrome supports two URL pattern formats:
- Match patterns
(also called extension patterns) look like
https://*.example.com/foo*bar
. - Enterprise policy URL pattern
look like
https://[*.]example.com
.
The main difference between the two pattern formats is how they handle domain wildcards. Match patterns define the *
wildcard as:
If the host is *._hostname_, then it matches the specified host or any of its subdomains
So the match pattern https://*.example.com/
matches https://www.example.com/
and
https://example.com/
, but not https://www.marketing.example.com/
.
Enterprise policy URL patterns define the [*.]
wildcard subtly different:
A domain can be prefixed by a wildcard “[*.]” to match the domain or any of its subdomains. The domain in question can be a subdomain of any level. Note the fact that the wildcard “[*.]” isn’t followed by a dot and should be prefixed directly to the domain/subdomain.
So the enterprise policy URL pattern https://[*.]example.com/
matches https://www.example.com/
,
https://example.com/
, and also https://www.marketing.example.com/
.
As it turns out, enterprise policy URL pattern is another name for content setting pattern, which is the term Chrome uses internally. So you should read the AutoSelectCertificateForUrls documentation as:
[...] an array of stringified JSON dictionaries, each with the form
{ "pattern": "$URL_PATTERN", "filter" : "$FILTER" }
,
where$URL_PATTERN
is an enterprise policy URL pattern such ashttps://[*.]example.com
.
A proper AutoSelectCertificateForUrls
entry should therefore look like this (but without the line breaks):
{
"pattern": "https://[*.]mtls.example.com",
"filter": {"ISSUER":"C=US,S=CA,L=MTV,O=Acme,OU=Sales,CN=Issuer"}
}