In my situation we already have our hosting set up with a 3rd party
hosting company, so I'm wondering if it's possible to somehow still
use Azure's Key Vault when not hosting on Azure. Failing that, what
are the alternatives?
You can still use fully On Premise alternative to securely host your secrets without putting them into the settings file.
What you need to know first is how settings are loading into ASP.Net Core applications. At the time of writing this answer this is the order that is used to load the configurations when you call CreateDefaultBuilder on the Program.cs file:
CreateDefaultBuilder provides default configuration for the app in the
following order:
ChainedConfigurationProvider : Adds an existing IConfiguration as a source. In the default configuration case, adds the host configuration
and setting it as the first source for the app configuration.
appsettings.json using the JSON configuration provider.
appsettings.Environment.json using the JSON configuration provider. For example, appsettings.Production.json and
appsettings.Development.json.
App secrets when the app runs in the Development environment.
Environment variables using the Environment Variables configuration provider.
Command-line arguments using the Command-line configuration provider.
In your case, the step you need to look at is the step n°5. In Windows, environment variables are configured in two ways:
- globally: machines environment variables. So it means all users can see environment variables
- per user: users only see environment variables belong to them. A user can't see other environment variables until he/she connected as that user using her/his login and password.
So in your case you need to follow these steps:
1. Create a specific user account
You'll need to create a specific user account for running your application.
It can be only a local user account.
2. Create environment variables for that user account
Connect to the server with that newly created user account, set the environment variables and make sure it will remain in the scope of that user (it is the purpose of the thrid parameter in the PowerShell Command below). For example to set the connection string you'll run something like below:
[Environment]::SetEnvironmentVariable("ConnectionStrings:MySuperDatabse", "my super database connection string", "User")
3. Configure the process that run your ASP.Net Core application
You need to configure the IIS Application Pool to use that new account to run the application. So you need to go to the Advanced Settings of the application pool dedicated to your application and set the new account like below:

4. Configure the process to load the user profile
One last thinks is to configure again the IIS Application Pool to load the User Profile. In some IIS configuration it is set to false by default. You need to set it to true so when loading the user profiles, the environment variables for that specific user will also be loaded. That can be configured in Advanced Settings of the application pool dedicated to your ASP.Net Core application like below:

And it is done! You'll be able to access to the secrets for the user account running your ASP.Net Core Application without modifying anything into your code base but only configurations on environment varaibles scoped to that user and configurations done on IIS. Beside the user account creation, all the remaining steps can be automated into your CD Pipelines without any difficulties.
Because the secrets are set to the environment variables of the created account, make sure that not many people are aware about its password (threat that account as an admin account).