Shared access key authentication with Azure Key Vault integration
The Arcus shared access key authentication is an API security filter to easily and safely share the same access key across a set of API endpoints. This kind of authentication is very common and therefore a popular feature in the Arcus WebApi library.
The API security filter makes use of the Arcus secret store to retrieve the access keys.
This user guide will walk through the process of adding shared access key authentication to an existing Web API application, using Azure Key Vault to store the access keys.
Terminology
To fully understand this user guide, some terminology is required:
- Shared access key: a single secret that's being used as the authentication mechanism of many API endpoints. Using a single secret means that there is also a single authorization level.
- Arcus secret store: central place where the application retrieve its secrets (more info).
Sample application
In this user guide, we will use a fictive API application to which we'll add shared access key authentication. We will be working with two major parts.
The initial place where the application will be started:
public class Program
{
public static void Main(string[] args)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRouting();
builder.Services.AddControllers();
WebApplication app = builder.Build();
app.UseRouting();
app.Run();
}
}
And the API controller that should be secured:
[ApiController]
[Route("api/v1/order")]
public class OrderController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromBody] Order order)
{
// Process order...
return Accepted();
}
}
1. Installation
To make use of the shared access key authentication, storing its secrets in Azure Key Vault, the following Arcus packages have to be installed.
PM > Install-Package -Name Arcus.WebApi.Security
PM > Install-Package -Name Arcus.Security.Providers.AzureKeyVault
2. Use Arcus secret store with Azure Key Vault integration
Once the packages are installed, add the secret store via extensions to the API application:
- 2.1 Use the
.ConfigureSecretStore
to setup the secret store with necessary secret providers - 2.2 Use the
.AddAzureKeyVaultWithManagedIdentity
to add the Azure Key Vault secret provider that will access the secret store
using Arcus.Security.Core.Caching.Configuration;
public class Program
{
public static void Main(string[] args)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.AddRouting();
builder.AddControllers();
builder.Host.ConfigureSecretStore((config, stores) =>
{
stores.AddAzureKeyVaultWithManagedIdentity("https://your-key.vault.azure.net", CacheConfiguration.Default);
});
WebApplication app = builder.Build();
app.UseRouting();
app.Run();
}
}
3. Use Arcus shared access key authentication API filter
This user guide will make use of the recommended way of securing API endpoints. This is done by registering the authentication mechanism in the startup code and on the API endpoint itself. That being said, we do support finer-grained authentication. See our dedicated feature documentation for more information.
The Arcus.WebApi.Security
package provides all the available authentication and authorization security mechanisms. For shared access key authentication, we will be using the AddSharedAccessKeyAuthenticationFilterOnHeader
extension which will register a global API authentication security filter that applies on all available API endpoints:
using Arcus.Security.Core.Caching.Configuration;
public class Program
{
public static void Main(string[] args)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.AddRouting();
builder.AddControllers(options =>
{
options.AddSharedAccessKeyAuthenticationFilterOnHeader(
"X-API-Key",
"MyAccessKey_SecretName_AvailableInSecretStore");
});
builder.Host.ConfigureSecretStore((config, stores) =>
{
stores.AddAzureKeyVaultWithManagedIdentity("https://your-key.vault.azure.net", CacheConfiguration.Default);
});
WebApplication app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.Run();
}
}
- The
X-API-Key
is the HTTP request header name where the shared access key should be located. Missing or invalid header values will result in401 Unauthorized
HTTP responses. - The
MyAccessKey_SecretName_AvailableInSecretStore
is the name of the secret that holds the shared access key in the Arcus secret store. The secret store will try to find the secret by this name in one of its secret providers, in this case Azure Key Vault.
The shared access key API authentication filter will then try to match the found access key secret with the incoming access key secret, located in the HTTP request header. Successful matches will delegate the request further up the application, unsuccessful matches will result in unauthorized results:
$headers = @{
'Content-Type'='application/json'
'X-API-Key'='invalid-key'
}
curl -Method POST `
-Headers $headers `
'http://localhost:787/api/v1/order' `
-Body '{ "OrderId": "3", "ProductName": "Fancy desk" }'
# Content: Shared access key in request doesn't match expected access key
# StatusCode : 401
$headers = @{
'Content-Type'='application/json'
'X-API-Key'='valid-key'
}
curl -Method POST `
-Headers $headers `
'http://localhost:787/api/v1/order' `
-Body '{ "OrderId": "3", "ProductName": "Fancy desk" }'
# StatusCode : 202
Conclusion
In this user guide, you've seen how the Arcus shared access key API authentication filter can be added to an existing application, using the Arcus secret store that places the access key in Azure Key Vault.
Besides shared access key authentication, we support several other mechanisms and useful API functionality. See our feature documentation for more information.