コード例 #1
0
        public async Task KeyVaultSecretProvider_StoreSecret_Succeeds()
        {
            // Arrange
            var keyVaultUri            = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var connectionString       = Configuration.GetValue <string>("Arcus:MSI:AzureServicesAuth:ConnectionString");
            var secretName             = $"Test-Secret-{Guid.NewGuid()}";
            var secretValue            = Guid.NewGuid().ToString();
            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ManagedServiceIdentityAuthentication(),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            using (TemporaryEnvironmentVariable.Create(KeyVaultConnectionStringEnvironmentVariable, connectionString))
            {
                // Act
                Secret secret = await keyVaultSecretProvider.StoreSecretAsync(secretName, secretValue);

                // Assert
                Assert.NotNull(secret);
                Assert.NotNull(secret.Value);
                Assert.NotNull(secret.Version);
                Secret fetchedSecret = await keyVaultSecretProvider.GetSecretAsync(secretName);

                Assert.Equal(secretValue, fetchedSecret.Value);
                Assert.Equal(secret.Version, fetchedSecret.Version);
                Assert.Equal(secret.Expires, fetchedSecret.Expires);
            }
        }
コード例 #2
0
        public async Task KeyVaultSecretProvider_StoreSecret_Succeeds()
        {
            // Arrange
            var    keyVaultUri = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            string tenantId    = Configuration.GetTenantId();
            string clientId    = Configuration.GetServicePrincipalClientId();
            string clientKey   = Configuration.GetServicePrincipalClientSecret();

            var secretName  = $"Test-Secret-{Guid.NewGuid()}";
            var secretValue = Guid.NewGuid().ToString();

            using (TemporaryEnvironmentVariable.Create(Constants.AzureTenantIdEnvironmentVariable, tenantId))
                using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientIdVariable, clientId))
                    using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientSecretVariable, clientKey))
                    {
                        var keyVaultSecretProvider = new KeyVaultSecretProvider(
                            tokenCredential: new ChainedTokenCredential(new ManagedIdentityCredential(clientId), new EnvironmentCredential()),
                            vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));
                        var cachedSecretProvider = new KeyVaultCachedSecretProvider(keyVaultSecretProvider);

                        // Act
                        Secret secret = await cachedSecretProvider.StoreSecretAsync(secretName, secretValue);

                        // Assert
                        Assert.NotNull(secret);
                        Assert.NotNull(secret.Value);
                        Assert.NotNull(secret.Version);
                        Secret fetchedSecret = await cachedSecretProvider.GetSecretAsync(secretName);

                        Assert.Equal(secretValue, fetchedSecret.Value);
                        Assert.Equal(secret.Version, fetchedSecret.Version);
                        Assert.Equal(secret.Expires, fetchedSecret.Expires);
                    }
        }
コード例 #3
0
        public async Task KeyVaultSecretProvider_WithUserAssignedManagedIdentity_GetSecret_Succeeds()
        {
            // Arrange
            var    keyVaultUri = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            string tenantId    = Configuration.GetTenantId();
            string clientId    = Configuration.GetServicePrincipalClientId();
            string clientKey   = Configuration.GetServicePrincipalClientSecret();
            var    secretName  = Configuration.GetValue <string>("Arcus:KeyVault:TestKeyName");

            using (TemporaryEnvironmentVariable.Create(Constants.AzureTenantIdEnvironmentVariable, tenantId))
                using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientIdVariable, clientId))
                    using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientSecretVariable, clientKey))
                    {
                        var keyVaultSecretProvider = new KeyVaultSecretProvider(
                            tokenCredential: new ChainedTokenCredential(new ManagedIdentityCredential(clientId), new EnvironmentCredential()),
                            vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

                        // Act
                        Secret secret = await keyVaultSecretProvider.GetSecretAsync(secretName);

                        // Assert
                        Assert.NotNull(secret);
                        Assert.NotNull(secret.Value);
                        Assert.NotNull(secret.Version);
                    }
        }
コード例 #4
0
        public async Task KeyVaultSecretProvider_WithUserAssignedManagedIdentity_GetSecret_NonExistingSecret_ThrowsSecretNotFoundException()
        {
            // Arrange
            var    keyVaultUri = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            string tenantId    = Configuration.GetTenantId();
            string clientId    = Configuration.GetServicePrincipalClientId();
            string clientKey   = Configuration.GetServicePrincipalClientSecret();

            using (TemporaryEnvironmentVariable.Create(Constants.AzureTenantIdEnvironmentVariable, tenantId))
                using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientIdVariable, clientId))
                    using (TemporaryEnvironmentVariable.Create(Constants.AzureServicePrincipalClientSecretVariable, clientKey))
                    {
                        var notExistingSecretName  = $"secret-{Guid.NewGuid():N}";
                        var keyVaultSecretProvider = new KeyVaultSecretProvider(
                            tokenCredential: new ChainedTokenCredential(new ManagedIdentityCredential(clientId), new EnvironmentCredential()),
                            vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

                        // Assert
                        await Assert.ThrowsAsync <SecretNotFoundException>(async() =>
                        {
                            // Act
                            await keyVaultSecretProvider.GetSecretAsync(notExistingSecretName);
                        });
                    }
        }
コード例 #5
0
        public async Task KeyVaultSecretProvider_GetsRawSecretWithIncorrectSecretNameFormat_Throws(string secretName)
        {
            // Arrange
            KeyVaultSecretProvider provider = CreateSecretProviderWithTooManyRequestSimulation("some ignored secret value");

            // Act / Assert
            await Assert.ThrowsAnyAsync <FormatException>(() => provider.GetRawSecretAsync(secretName));
        }
コード例 #6
0
        public async Task KeyVaultSecretProvider_StoreSecretWithIncorrectSecretNameFormat_Throws(string secretName)
        {
            // Arrange
            var secretValue = Guid.NewGuid().ToString();
            KeyVaultSecretProvider provider = CreateSecretProviderWithTooManyRequestSimulation("some ignored secret value");

            // Act / Assert
            await Assert.ThrowsAnyAsync <FormatException>(() => provider.StoreSecretAsync(secretName, secretValue));
        }
コード例 #7
0
        public void KeyVaultSecretProvider_CreateWithValidArguments_ShouldSucceed()
        {
            // Arrange
            string uri = GenerateVaultUri();

            // Act & Assert
            var secretProvider = new KeyVaultSecretProvider(new AzureKeyVaultAuthenticatorDummy(), new KeyVaultConfiguration(uri));

            Assert.NotNull(secretProvider);
        }
コード例 #8
0
        public async Task KeyVaultSecretProvider_GetsRawSecretWithCorrectFormat(string secretName)
        {
            // Arrange
            string expected = $"secret-{Guid.NewGuid()}";
            KeyVaultSecretProvider provider = CreateSecretProviderWithTooManyRequestSimulation(expected);

            // Act
            string actual = await provider.GetRawSecretAsync(secretName);

            // Assert
            Assert.Equal(actual, expected);
        }
コード例 #9
0
        public async Task KeyVaultSecretProvider_GetsRawSecretValue_AfterRetriedTooManyRequestException()
        {
            // Arrange
            string expected   = $"secret-value-{Guid.NewGuid()}";
            string secretName = $"secret-name-{Guid.NewGuid()}";
            KeyVaultSecretProvider provider = CreateSecretProviderWithTooManyRequestSimulation(expected);

            // Act
            string actual = await provider.GetRawSecret(secretName);

            // Assert
            Assert.Equal(expected, actual);
        }
コード例 #10
0
        private ISecretProvider CreateSecretProvider()
        {
            var keyVaultEndpoint = Configuration["KEYVAULT_ENDPOINT"];

#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 KeyVaultSecretProvider(vaultAuthentication, vaultConfiguration);
            return(keyVaultSecretProvider);
        }
コード例 #11
0
        public async Task KeyVaultSecretProvider_WithManagedIdentity_GetSecret_NonExistingSecret_ThrowsSecretNotFoundException()
        {
            // Arrange
            var keyVaultUri            = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var connectionString       = Configuration.GetValue <string>("Arcus:MSI:AzureServicesAuth:ConnectionString");
            var notExistingSecretName  = $"secret-{Guid.NewGuid():N}";
            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ManagedServiceIdentityAuthentication(connectionString: connectionString),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            // Assert
            await Assert.ThrowsAsync <SecretNotFoundException>(async() =>
            {
                // Act
                await keyVaultSecretProvider.GetSecretAsync(notExistingSecretName);
            });
        }
コード例 #12
0
        public async Task KeyVaultSecretProvider_GetsSecretAsync_AfterRetriedTooManyRequestException()
        {
            // Arrange
            string   expected               = $"secret-value-{Guid.NewGuid()}";
            string   secretName             = $"secret-name-{Guid.NewGuid()}";
            DateTime expirationDate         = DateTime.UtcNow;
            KeyVaultSecretProvider provider = CreateSecretProviderWithTooManyRequestSimulation(expected, expirationDate);

            // Act
            Secret actual = await provider.GetSecretAsync(secretName);

            // Assert
            Assert.NotNull(actual);
            Assert.Equal(expected, actual.Value);
            Assert.NotNull(actual.Version);
            Assert.Equal(expirationDate, actual.Expires);
        }
コード例 #13
0
        public async Task KeyVaultSecretProvider_WithManagedIdentity_GetSecret_Succeeds()
        {
            // Arrange
            var keyVaultUri            = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var connectionString       = Configuration.GetValue <string>("Arcus:MSI:AzureServicesAuth:ConnectionString");
            var secretName             = Configuration.GetValue <string>("Arcus:KeyVault:TestKeyName");
            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ManagedServiceIdentityAuthentication(connectionString: connectionString),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            // Act
            Secret secret = await keyVaultSecretProvider.GetSecretAsync(secretName);

            // Assert
            Assert.NotNull(secret);
            Assert.NotNull(secret.Value);
            Assert.NotNull(secret.Version);
        }
コード例 #14
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);
        }
コード例 #15
0
        public async Task KeyVaultSecretProvider_GetSecret_NonExistingSecret_ThrowsSecretNotFoundException()
        {
            // Arrange
            string applicationId = Configuration.GetValue <string>("Arcus:ServicePrincipal:ApplicationId");
            var    clientKey     = Configuration.GetValue <string>("Arcus:ServicePrincipal:AccessKey");
            var    keyVaultUri   = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var    keyName       = Guid.NewGuid().ToString("N");

            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ServicePrincipalAuthenticator(applicationId, clientKey),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            // Assert
            await Assert.ThrowsAnyAsync <SecretNotFoundException>(async() =>
            {
                // Act
                await keyVaultSecretProvider.GetSecretAsync(keyName);
            });
        }
コード例 #16
0
        private static KeyVaultSecretProvider CreateSecretProviderWithTooManyRequestSimulation(string expected)
        {
            // Arrange
            var keyVaultClient = new SimulatedKeyVaultClient(
                () => throw new KeyVaultErrorException("Sabotage secret retrieval with TooManyRequests")
            {
                Response = new HttpResponseMessageWrapper(
                    new HttpResponseMessage(HttpStatusCode.TooManyRequests),
                    "some HTTP response content to ignore")
            },
                () => new SecretBundle(value: expected, id: $"http://requires-3-or-4-segments/secrets/with-the-second-named-secrets-{Guid.NewGuid()}"));


            var provider = new KeyVaultSecretProvider(
                new StubKeyVaultAuthenticator(keyVaultClient),
                new KeyVaultConfiguration(GenerateVaultUri()));

            return(provider);
        }
コード例 #17
0
        public async Task KeyVaultSecretProvider_WithServicePrincipalWithTenant_GetSecret_NonExistingSecret_ThrowsSecretNotFoundException()
        {
            // Arrange
            string tenantId              = Configuration.GetTenantId();
            string applicationId         = Configuration.GetValue <string>("Arcus:ServicePrincipal:ApplicationId");
            var    clientKey             = Configuration.GetValue <string>("Arcus:ServicePrincipal:AccessKey");
            var    keyVaultUri           = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var    notExistingSecretName = $"secret-{Guid.NewGuid():N}";

            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                tokenCredential: new ClientSecretCredential(tenantId, applicationId, clientKey),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            // Assert
            await Assert.ThrowsAnyAsync <SecretNotFoundException>(async() =>
            {
                // Act
                await keyVaultSecretProvider.GetSecretAsync(notExistingSecretName);
            });
        }
コード例 #18
0
        /// <summary>
        /// Adds Azure Key Vault as a secret source.
        /// </summary>
        /// <param name="builder">The builder to create the secret store.</param>
        /// <param name="authentication">The requested authentication type for connecting to the Azure Key Vault instance.</param>
        /// <param name="configuration">The configuration related to the Azure Key Vault instance to use.</param>
        /// <param name="cacheConfiguration">The configuration to control how the caching will be done.</param>
        public static SecretStoreBuilder AddAzureKeyVault(
            this SecretStoreBuilder builder,
            IKeyVaultAuthentication authentication,
            IKeyVaultConfiguration configuration,
            ICacheConfiguration cacheConfiguration)
        {
            Guard.NotNull(builder, nameof(builder));
            Guard.NotNull(authentication, nameof(authentication));
            Guard.NotNull(configuration, nameof(configuration));

            var keyVaultSecretProvider = new KeyVaultSecretProvider(authentication, configuration);

            if (cacheConfiguration != null)
            {
                var cachedSecretProvider = new CachedSecretProvider(keyVaultSecretProvider, cacheConfiguration);
                return(builder.AddProvider(cachedSecretProvider));
            }

            return(builder.AddProvider(keyVaultSecretProvider));
        }
コード例 #19
0
        public async Task KeyVaultSecretProvider_GetSecret_Succeeds()
        {
            // Arrange
            string applicationId = Configuration.GetValue <string>("Arcus:ServicePrincipal:ApplicationId");
            var    clientKey     = Configuration.GetValue <string>("Arcus:ServicePrincipal:AccessKey");
            var    keyVaultUri   = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var    keyName       = Configuration.GetValue <string>("Arcus:KeyVault:TestKeyName");

            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ServicePrincipalAuthenticator(applicationId, clientKey),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            // Act
            Secret secret = await keyVaultSecretProvider.GetSecretAsync(keyName);

            // Assert
            Assert.NotNull(secret);
            Assert.NotNull(secret.Value);
            Assert.NotNull(secret.Version);
        }
コード例 #20
0
        public async Task KeyVaultSecretProvider_WithDefaultManagedServiceIdentity_GetSecret_NonExistingSecret_ThrowsSecretNotFoundException()
        {
            // Arrange
            var keyVaultUri            = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var connectionString       = Configuration.GetValue <string>("Arcus:MSI:AzureServicesAuth:ConnectionString");
            var notExistingKeyName     = Guid.NewGuid().ToString("N");
            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ManagedServiceIdentityAuthentication(),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            using (TemporaryEnvironmentVariable.Create(KeyVaultConnectionStringEnvironmentVariable, connectionString))
            {
                // Assert
                await Assert.ThrowsAsync <SecretNotFoundException>(async() =>
                {
                    // Act
                    await keyVaultSecretProvider.GetSecretAsync(notExistingKeyName);
                });
            }
        }
コード例 #21
0
        public async Task KeyVaultSecretProvider_WithDefaultManagedServiceIdentity_GetSecret_Succeeds()
        {
            // Arrange
            var keyVaultUri            = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var connectionString       = Configuration.GetValue <string>("Arcus:MSI:AzureServicesAuth:ConnectionString");
            var keyName                = Configuration.GetValue <string>("Arcus:KeyVault:TestKeyName");
            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                authentication: new ManagedServiceIdentityAuthentication(),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            using (TemporaryEnvironmentVariable.Create(KeyVaultConnectionStringEnvironmentVariable, connectionString))
            {
                // Act
                Secret secret = await keyVaultSecretProvider.GetSecretAsync(keyName);

                // Assert
                Assert.NotNull(secret);
                Assert.NotNull(secret.Value);
                Assert.NotNull(secret.Version);
            }
        }
コード例 #22
0
        public async Task KeyVaultSecretProvider_WithServicePrincipalWithTenant_GetSecret_Succeeds()
        {
            // Arrange
            string tenantId      = Configuration.GetTenantId();
            string applicationId = Configuration.GetValue <string>("Arcus:ServicePrincipal:ApplicationId");
            var    clientKey     = Configuration.GetValue <string>("Arcus:ServicePrincipal:AccessKey");
            var    keyVaultUri   = Configuration.GetValue <string>("Arcus:KeyVault:Uri");
            var    secretName    = Configuration.GetValue <string>("Arcus:KeyVault:TestKeyName");

            var keyVaultSecretProvider = new KeyVaultSecretProvider(
                tokenCredential: new ClientSecretCredential(tenantId, applicationId, clientKey),
                vaultConfiguration: new KeyVaultConfiguration(keyVaultUri));

            // Act
            Secret secret = await keyVaultSecretProvider.GetSecretAsync(secretName);

            // Assert
            Assert.NotNull(secret);
            Assert.NotNull(secret.Value);
            Assert.NotNull(secret.Version);
        }
コード例 #23
0
 private void Init(string vaultName)
 {
     _vaultAuthenticator     = new ManagedServiceIdentityAuthenticator();
     _vaultConfiguration     = new KeyVaultConfiguration($"https://{vaultName}.vault.azure.net/");
     _keyVaultSecretProvider = new KeyVaultSecretProvider(_vaultAuthenticator, _vaultConfiguration);
 }