Esempio n. 1
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
                }
            }
        }
Esempio n. 6
0
        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);
        }