Currently on macOS, the dotnet dev-certs https command installs the dev cert into the system keychain. The dotnet dev-certs --trust command then trusts the dev cert for all purposes (Always Trust) and does so in the admin store, by passing the -d option to the generated security add-trusted-certificate command. This requires running the generated command with sudo, and forces an extra user prompt to allow the keychain modification to take place. In some configurations (e.g. when using a YubiKey as a smart card for macOS login) the second prompt always fails, resulting in the --trust command failing.
We should narrow the scope of the dev cert to just the logged in user, by just installing the cert in the current user's login keychain. For the trust operation, we should specify that the certificate should only be trusted for SSL and X.509 Basic Policy only, via the -p option, and only for the current user's store, by not passing the -d option.
This more closely matches what we do on Windows where the cert is only installed into the current user's "Personal" certificate store and trusted in the user's "Trusted Root Authorities" certificate store.
Example command to trust a cert for the current user & only the required purposes:
$ security add-trusted-cert -r trustRoot -p basic -p ssl -k /Users/<<username>>/Library/Keychains/login.keychain-db devcert.cer
The user's keychain location can be determined with the following command:
$ security login-keychain
"/Users/myusername/Library/Keychains/login.keychain-db"
$
After trusting the certificate in this way, it should appear like this in the Keychain Access app:

I simulated this manually on my Mac and verified that:
- ASP.NET Core apps can load the dev cert for Kestrel's HTTPS endpoint binding (after approving access by the app to the private key in the keychain)
- Browsers (including Edge, Chrome, and Safari) still see the dev cert as trusted when browsing a local ASP.NET Core site
- Other clients (including a custom .NET console app that uses
HttpClient to call an API in a locally running ASP.NET Core app over HTTPS) successfully establish an HTTPS connection and can send and receive requests (i.e. the cert chain is trusted)
security command docs
Currently on macOS, the
dotnet dev-certs httpscommand installs the dev cert into the system keychain. Thedotnet dev-certs --trustcommand then trusts the dev cert for all purposes (Always Trust) and does so in the admin store, by passing the-doption to the generatedsecurity add-trusted-certificatecommand. This requires running the generated command withsudo, and forces an extra user prompt to allow the keychain modification to take place. In some configurations (e.g. when using a YubiKey as a smart card for macOS login) the second prompt always fails, resulting in the--trustcommand failing.We should narrow the scope of the dev cert to just the logged in user, by just installing the cert in the current user's login keychain. For the trust operation, we should specify that the certificate should only be trusted for SSL and X.509 Basic Policy only, via the
-poption, and only for the current user's store, by not passing the-doption.This more closely matches what we do on Windows where the cert is only installed into the current user's "Personal" certificate store and trusted in the user's "Trusted Root Authorities" certificate store.
Example command to trust a cert for the current user & only the required purposes:
The user's keychain location can be determined with the following command:
After trusting the certificate in this way, it should appear like this in the Keychain Access app:
I simulated this manually on my Mac and verified that:
HttpClientto call an API in a locally running ASP.NET Core app over HTTPS) successfully establish an HTTPS connection and can send and receive requests (i.e. the cert chain is trusted)securitycommand docs