public async Task NewSecretVersion_TriggersKeyVaultJob_AutoInvalidatesSecret() { // Arrange var applicationId = _config.GetValue <string>("Arcus:ServicePrincipal:ApplicationId"); var clientKey = _config.GetValue <string>("Arcus:ServicePrincipal:AccessKey"); var keyVaultUri = _config.GetValue <string>("Arcus:KeyVault:Uri"); var authentication = new ServicePrincipalAuthentication(applicationId, clientKey); var cachedSecretProvider = _host.Services.GetService <ICachedSecretProvider>(); var secretValue = Guid.NewGuid().ToString("N"); using (IKeyVaultClient client = await authentication.AuthenticateAsync()) // Act await using (var tempSecret = await TemporaryAzureKeyVaultSecret.CreateNewAsync(client, keyVaultUri)) { await tempSecret.UpdateSecretAsync(secretValue); // Assert RetryAssertion( // ReSharper disable once AccessToDisposedClosure - disposal happens after retry. () => Mock.Get(cachedSecretProvider) .Verify(p => p.InvalidateSecretAsync(It.Is <string>(n => n == tempSecret.Name)), Times.Once), timeout: TimeSpan.FromMinutes(5), interval: TimeSpan.FromMilliseconds(500)); } }
private static async Task <IKeyVaultClient> CreateKeyVaultClientAsync(KeyRotationConfig rotationConfig) { ServicePrincipalAuthentication authentication = rotationConfig.ServicePrincipal.CreateAuthentication(); IKeyVaultClient keyVaultClient = await authentication.AuthenticateAsync(); return(keyVaultClient); }
public void Constructor_ValidArguments_Succeeds() { // Arrange string clientId = Guid.NewGuid().ToString(); string clientKey = Guid.NewGuid().ToString(); // Act var authenticator = new ServicePrincipalAuthentication(clientId: clientId, clientKey: clientKey); // Assert Assert.NotNull(authenticator); }
private ISecretProvider CreateSecretProvider() { var keyVaultEndpoint = Configuration["KeyVaultUri"]; #if RELEASE var vaultAuthentication = new ManagedServiceIdentityAuthentication(); #elif DEBUG var clientId = Configuration["KEYVAULT_AUTH_ID"]; var clientSecret = Configuration["KEYVAULT_AUTH_SECRET"]; var vaultAuthentication = new ServicePrincipalAuthentication(clientId, clientSecret); #endif var vaultConfiguration = new KeyVaultConfiguration(keyVaultEndpoint); var keyVaultSecretProvider = new Arcus.Security.Providers.AzureKeyVault.KeyVaultSecretProvider(vaultAuthentication, vaultConfiguration); return(keyVaultSecretProvider); }
public async Task ServiceBusMessagePump_RotateServiceBusConnectionKeys_MessagePumpRestartsThenMessageSuccessfullyProcessed() { // Arrange var config = TestConfig.Create(); KeyRotationConfig keyRotationConfig = config.GetKeyRotationConfig(); _logger.LogInformation("Using Service Principal [ClientID: '{ClientId}']", keyRotationConfig.ServicePrincipal.ClientId); var client = new ServiceBusConfiguration(keyRotationConfig, _logger); string freshConnectionString = await client.RotateConnectionStringKeysForQueueAsync(KeyType.PrimaryKey); ServicePrincipalAuthentication authentication = keyRotationConfig.ServicePrincipal.CreateAuthentication(); IKeyVaultClient keyVaultClient = await authentication.AuthenticateAsync(); await SetConnectionStringInKeyVaultAsync(keyVaultClient, keyRotationConfig, freshConnectionString); var options = new WorkerOptions(); options.AddEventGridPublisher(config) .AddSingleton <ISecretProvider>(serviceProvider => { return(new KeyVaultSecretProvider( new ServicePrincipalAuthentication(keyRotationConfig.ServicePrincipal.ClientId, keyRotationConfig.ServicePrincipal.ClientSecret), new KeyVaultConfiguration(keyRotationConfig.KeyVault.VaultUri))); }) .AddServiceBusQueueMessagePump(keyRotationConfig.KeyVault.SecretName, opt => opt.AutoComplete = true) .WithServiceBusMessageHandler <OrdersAzureServiceBusMessageHandler, Order>(); await using (var worker = await Worker.StartNewAsync(options)) { string newSecondaryConnectionString = await client.RotateConnectionStringKeysForQueueAsync(KeyType.SecondaryKey); await SetConnectionStringInKeyVaultAsync(keyVaultClient, keyRotationConfig, newSecondaryConnectionString); await using (var service = await TestMessagePumpService.StartNewAsync(config, _logger)) { // Act string newPrimaryConnectionString = await client.RotateConnectionStringKeysForQueueAsync(KeyType.PrimaryKey); // Assert await service.SimulateMessageProcessingAsync(newPrimaryConnectionString); } } }
public async Task RotateServiceBusSecrets_WithValidArguments_RotatesPrimarySecondaryAlternatively() { // Arrange var config = TestConfig.Create(); KeyRotationConfig keyRotationConfig = config.GetKeyRotationConfig(); _logger.LogInformation("Using Service Principal [ClientID: '{ClientId}']", keyRotationConfig.ServicePrincipal.ClientId); const ServiceBusEntityType entity = ServiceBusEntityType.Topic; var keyVaultAuthentication = new ServicePrincipalAuthentication( keyRotationConfig.ServicePrincipal.ClientId, keyRotationConfig.ServicePrincipal.ClientSecret); var keyVaultConfiguration = new KeyVaultConfiguration(keyRotationConfig.KeyVault.VaultUri); var secretProvider = new KeyVaultSecretProvider(keyVaultAuthentication, keyVaultConfiguration); AzureServiceBusClient azureServiceBusClient = CreateAzureServiceBusClient(keyRotationConfig, secretProvider, entity); var rotation = new AzureServiceBusKeyRotation(azureServiceBusClient, keyVaultAuthentication, keyVaultConfiguration, _logger); var client = new ServiceBusConfiguration(keyRotationConfig, _logger); AccessKeys keysBefore1stRotation = await client.GetConnectionStringKeysForTopicAsync(); // Act await rotation.RotateServiceBusSecretAsync(keyRotationConfig.KeyVault.SecretName); // Assert string secondaryConnectionString = await secretProvider.GetRawSecretAsync(keyRotationConfig.KeyVault.SecretName); AccessKeys keysAfter1stRotation = await client.GetConnectionStringKeysForTopicAsync(); Assert.True(secondaryConnectionString == keysAfter1stRotation.SecondaryConnectionString, "Secondary connection string should be set in Azure Key Vault after first rotation"); Assert.NotEqual(keysBefore1stRotation.PrimaryConnectionString, keysAfter1stRotation.PrimaryConnectionString); Assert.NotEqual(keysBefore1stRotation.SecondaryConnectionString, keysAfter1stRotation.SecondaryConnectionString); await rotation.RotateServiceBusSecretAsync(keyRotationConfig.KeyVault.SecretName); string primaryConnectionString = await secretProvider.GetRawSecretAsync(keyRotationConfig.KeyVault.SecretName); AccessKeys keysAfter2ndRotation = await client.GetConnectionStringKeysForTopicAsync(); Assert.True(primaryConnectionString == keysAfter2ndRotation.PrimaryConnectionString, "Primary connection string should be set in Azure Key Vault after second rotation"); Assert.NotEqual(keysAfter1stRotation.PrimaryConnectionString, keysAfter2ndRotation.PrimaryConnectionString); Assert.NotEqual(keysAfter2ndRotation.SecondaryConnectionString, keysAfter1stRotation.SecondaryConnectionString); }