Beispiel #1
0
        public async Task UpdateSecret()
        {
            string secretName = Recording.GenerateId();

            KeyVaultSecret secret = await Client.SetSecretAsync(secretName, "CrudBasicValue1");

            RegisterForCleanup(secret.Name);

            secret.Properties.ExpiresOn = secret.Properties.CreatedOn;

            SecretProperties updateResult = await Client.UpdateSecretPropertiesAsync(secret.Properties);

            AssertSecretPropertiesEqual(secret.Properties, updateResult);
        }
        protected void AssertSecretPropertiesEqual(SecretProperties exp, SecretProperties act, bool compareId = true)
        {
            if (compareId)
            {
                Assert.AreEqual(exp.Id, act.Id);
            }

            Assert.AreEqual(exp.ContentType, act.ContentType);
            Assert.AreEqual(exp.KeyId, act.KeyId);
            Assert.AreEqual(exp.Managed, act.Managed);

            Assert.AreEqual(exp.Enabled, act.Enabled);
            Assert.AreEqual(exp.ExpiresOn, act.ExpiresOn);
            Assert.AreEqual(exp.NotBefore, act.NotBefore);
        }
        public void BackupAndRestoreSync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");
            string backupPath  = Path.GetTempFileName();

            // Instantiate a secret client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create a secret holding bank account credentials valid for 1 year. if the secret
            // already exists in the key vault, then a new version of the secret is created.
            string secretName = $"StorageAccountPasswor{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v")
            {
                Properties =
                {
                    ExpiresOn = DateTimeOffset.Now.AddYears(1)
                }
            };

            KeyVaultSecret storedSecret = client.SetSecret(secret);

            // Backups are good to have if in case secrets get accidentally deleted by you.
            // For long term storage, it is ideal to write the backup to a file.
            File.WriteAllBytes(backupPath, client.BackupSecret(secretName));

            // The storage account secret is no longer in use, so you delete it.
            DeleteSecretOperation operation = client.StartDeleteSecret(secretName);

            // To ensure the secret is deleted on server before we try to purge it.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted secret needs to be purged.
            client.PurgeDeletedSecret(secretName);

            // After sometime, the secret is required again. We can use the backup value to restore it in the key vault.
            SecretProperties restoreSecret = client.RestoreSecretBackup(File.ReadAllBytes(backupPath));

            AssertSecretsEqual(storedSecret.Properties, restoreSecret);
        }
Beispiel #4
0
        private void HelloWorldSync(string keyVaultUrl)
        {
            #region Snippet:SecretsSample1SecretClient
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
            #endregion

            #region Snippet:SecretsSample1CreateSecret
            string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");
            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            client.SetSecret(secret);
            #endregion

            #region Snippet:SecretsSample1GetSecret
            KeyVaultSecret bankSecret = client.GetSecret(secretName);
            Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");
            #endregion

            #region Snippet:SecretsSample1UpdateSecretProperties
            bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
            SecretProperties updatedSecret = client.UpdateSecretProperties(bankSecret.Properties);
            Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");
            #endregion

            #region Snippet:SecretsSample1UpdateSecret
            var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa");
            secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            client.SetSecret(secretNewValue);
            #endregion

            #region Snippet:SecretsSample1DeleteSecret
            DeleteSecretOperation operation = client.StartDeleteSecret(secretName);
            #endregion

            #region Snippet:SecretsSample1PurgeSecret
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }

            client.PurgeDeletedSecret(secretName);
            #endregion
        }
        public async Task AsyncPageableLoop()
        {
            // create a client
            var client = new SecretClient(new Uri("http://example.com"), new DefaultAzureCredential());

            #region Snippet:AsyncPageableLoop
            // call a service method, which returns AsyncPageable<T>
            AsyncPageable <SecretProperties> response = client.GetPropertiesOfSecretsAsync();

            IAsyncEnumerator <SecretProperties> enumerator = response.GetAsyncEnumerator();
            while (await enumerator.MoveNextAsync())
            {
                SecretProperties secretProperties = enumerator.Current;
                Console.WriteLine(secretProperties.Name);
            }
            #endregion
        }
        private void BackupAndRestoreSync(string keyVaultUrl)
        {
            #region Snippet:SecretsSample2SecretClient
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
            #endregion

            #region Snippet:SecretsSample2CreateSecret
            string secretName = $"StorageAccountPassword{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");
            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            KeyVaultSecret storedSecret = client.SetSecret(secret);
            #endregion

            #region Snippet:SecretsSample2BackupSecret
            string backupPath   = Path.GetTempFileName();
            byte[] secretBackup = client.BackupSecret(secretName);

            File.WriteAllBytes(backupPath, secretBackup);
            #endregion

            // The storage account secret is no longer in use so you delete it.
            DeleteSecretOperation operation = client.StartDeleteSecret(secretName);

            // Before it can be purged, you need to wait until the secret is fully deleted.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }

            // If the Key Vault is soft delete-enabled and you want to permanently delete the secret before its `ScheduledPurgeDate`,
            // the deleted secret needs to be purged.
            client.PurgeDeletedSecret(secretName);

            #region Snippet:SecretsSample2RestoreSecret
            byte[] secretBackupToRestore = File.ReadAllBytes(backupPath);

            SecretProperties restoreSecret = client.RestoreSecretBackup(secretBackupToRestore);
            #endregion

            AssertSecretsEqual(storedSecret.Properties, restoreSecret);
        }
Beispiel #7
0
        private async Task BackupAndRestoreAsync(string keyVaultUrl)
        {
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string secretName = $"StorageAccountPassword{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");

            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            KeyVaultSecret storedSecret = await client.SetSecretAsync(secret);

            string backupPath = Path.GetTempFileName();

            using (FileStream sourceStream = File.Open(backupPath, FileMode.OpenOrCreate))
            {
                byte[] byteSecret = await client.BackupSecretAsync(secretName);

                sourceStream.Seek(0, SeekOrigin.End);
                await sourceStream.WriteAsync(byteSecret, 0, byteSecret.Length);
            }

            // The storage account secret is no longer in use so you delete it.
            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            // Before it can be purged, you need to wait until the secret is fully deleted.
            await operation.WaitForCompletionAsync();

            // If the Key Vault is soft delete-enabled and you want to permanently delete the secret before its `ScheduledPurgeDate`,
            // the deleted secret needs to be purged.
            await client.PurgeDeletedSecretAsync(secretName);

            SecretProperties restoreSecret = null;

            using (FileStream sourceStream = File.Open(backupPath, FileMode.Open))
            {
                byte[] result = new byte[sourceStream.Length];
                await sourceStream.ReadAsync(result, 0, (int)sourceStream.Length);

                restoreSecret = await client.RestoreSecretBackupAsync(result);
            }

            AssertSecretsEqual(storedSecret.Properties, restoreSecret);
        }
Beispiel #8
0
        public async Task UpdateEnabled()
        {
            string secretName = Recording.GenerateId();

            KeyVaultSecret secret = await Client.SetSecretAsync(secretName, "CrudBasicValue1");

            RegisterForCleanup(secret.Name);

            secret.Properties.Enabled = false;

            SecretProperties updateResult = await Client.UpdateSecretPropertiesAsync(secret.Properties);

            AssertSecretPropertiesEqual(secret.Properties, updateResult);

            Assert.ThrowsAsync <RequestFailedException>(() => Client.GetSecretAsync(secretName));

            secret.Properties.Enabled = true;

            await Client.UpdateSecretPropertiesAsync(secret.Properties);
        }
        public void UpdateSecret()
        {
            // Make sure a secret exists.
            client.SetSecret("secret-name", "secret-value");

            #region UpdateSecret
            Secret secret = client.GetSecret("secret-name");

            // Clients may specify the content type of a secret to assist in interpreting the secret data when it's retrieved.
            secret.Properties.ContentType = "text/plain";

            // You can specify additional application-specific metadata in the form of tags.
            secret.Properties.Tags["foo"] = "updated tag";

            SecretProperties updatedSecretProperties = client.UpdateSecretProperties(secret.Properties);

            Console.WriteLine(updatedSecretProperties.Name);
            Console.WriteLine(updatedSecretProperties.Version);
            Console.WriteLine(updatedSecretProperties.ContentType);
            #endregion
        }
Beispiel #10
0
        public async Task UpdateSecret()
        {
            // Make sure a secret exists. This will create a new version if "secret-name" already exists.
            await client.SetSecretAsync("secret-name", "secret-value");

            #region UpdateSecret
            KeyVaultSecret secret = await client.GetSecretAsync("secret-name");

            // Clients may specify the content type of a secret to assist in interpreting the secret data when it's retrieved.
            secret.Properties.ContentType = "text/plain";

            // You can specify additional application-specific metadata in the form of tags.
            secret.Properties.Tags["foo"] = "updated tag";

            SecretProperties updatedSecretProperties = await client.UpdateSecretPropertiesAsync(secret.Properties);

            Console.WriteLine(updatedSecretProperties.Name);
            Console.WriteLine(updatedSecretProperties.Version);
            Console.WriteLine(updatedSecretProperties.ContentType);
            #endregion
        }
        public async Task HelloWorldAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");

            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secret);

            KeyVaultSecret bankSecret = await client.GetSecretAsync(secretName);

            Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");

            bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
            SecretProperties updatedSecret = await client.UpdateSecretPropertiesAsync(bankSecret.Properties);

            Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");

            var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa");

            secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secretNewValue);

            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            #region Snippet:SecretsSample1PurgeSecretAsync
            // You only need to wait for completion if you want to purge or recover the secret.
            await operation.WaitForCompletionAsync();

            await client.PurgeDeletedSecretAsync(secretName);

            #endregion
        }
        public async Task RecoverSecret()
        {
            string secretName = Recording.GenerateId();

            Secret secret = await Client.SetAsync(secretName, "value");

            RegisterForCleanup(secret.Name);

            DeletedSecret deletedSecret = await Client.DeleteAsync(secretName);

            await WaitForDeletedSecret(secretName);

            SecretProperties recoverSecretResult = await Client.RecoverDeletedAsync(secretName);

            await PollForSecret(secretName);

            Secret recoveredSecret = await Client.GetAsync(secretName);

            AssertSecretPropertiesEqual(secret.Properties, deletedSecret.Properties);
            AssertSecretPropertiesEqual(secret.Properties, recoverSecretResult);
            AssertSecretsEqual(secret, recoveredSecret);
        }
Beispiel #13
0
        public async Task GetPropertiesOfSecrets()
        {
            string secretName = Recording.GenerateId();

            List <KeyVaultSecret> createdSecrets = new List <KeyVaultSecret>();

            for (int i = 0; i < PagedSecretCount; i++)
            {
                KeyVaultSecret secret = await Client.SetSecretAsync(secretName + i, i.ToString());

                createdSecrets.Add(secret);
                RegisterForCleanup(secret.Name);
            }

            List <SecretProperties> allSecrets = await Client.GetPropertiesOfSecretsAsync().ToEnumerableAsync();

            foreach (KeyVaultSecret createdSecret in createdSecrets)
            {
                SecretProperties returnedSecret = allSecrets.Single(s => s.Name == createdSecret.Name);
                AssertSecretPropertiesEqual(createdSecret.Properties, returnedSecret, compareId: false);
            }
        }
        public async Task GetSecretsVersions()
        {
            string secretName = Recording.GenerateId();

            List <Secret> createdSecrets = new List <Secret>();

            for (int i = 0; i < PagedSecretCount; i++)
            {
                Secret secret = await Client.SetAsync(secretName, i.ToString());

                createdSecrets.Add(secret);
            }

            RegisterForCleanup(createdSecrets.First().Name);

            List <Response <SecretProperties> > allSecrets = await Client.GetSecretVersionsAsync(secretName).ToEnumerableAsync();

            foreach (Secret createdSecret in createdSecrets)
            {
                SecretProperties returnedSecret = allSecrets.Single(s => s.Value.Id == createdSecret.Id);
                AssertSecretPropertiesEqual(createdSecret.Properties, returnedSecret);
            }
        }
        private async Task HelloWorldAsync(string keyVaultUrl)
        {
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");

            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secret);

            KeyVaultSecret bankSecret = await client.GetSecretAsync(secretName);

            Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");

            bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
            SecretProperties updatedSecret = await client.UpdateSecretPropertiesAsync(bankSecret.Properties);

            Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");

            var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa");

            secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secretNewValue);

            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            #region Snippet:SecretsSample1PurgeSecretAsync
            await operation.WaitForCompletionAsync();

            await client.PurgeDeletedSecretAsync(secretName);

            #endregion
        }
        private static Blob ToBlob(SecretProperties secretProperties)
        {
            var blob = new Blob(secretProperties.Name, BlobItemKind.File);

            blob.LastModificationTime = secretProperties.UpdatedOn;

            blob.TryAddProperties(
                "ContentType", secretProperties.ContentType,
                "CreatedOn", secretProperties.CreatedOn,
                "IsEnabled", secretProperties.Enabled,
                "ExpiresOn", secretProperties.ExpiresOn,
                "Id", secretProperties.Id,
                "KeyId", secretProperties.KeyId,
                "IsManaged", secretProperties.Managed,
                "NotBefore", secretProperties.NotBefore,
                "RecoveryLevel", secretProperties.RecoveryLevel,
                "Tags", secretProperties.Tags,
                "UpdatedOn", secretProperties.UpdatedOn,
                "VaultUri", secretProperties.VaultUri,
                "Version", secretProperties.Version,
                "IsSecret", true);

            return(blob);
        }
Beispiel #17
0
 internal FrontDoorSecretData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData, FrontDoorProvisioningState?provisioningState, FrontDoorDeploymentStatus?deploymentStatus, string profileName, SecretProperties properties) : base(id, name, resourceType, systemData)
 {
     ProvisioningState = provisioningState;
     DeploymentStatus  = deploymentStatus;
     ProfileName       = profileName;
     Properties        = properties;
 }
        public void HelloWorldSync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            // Instantiate a secret client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create a secret holding bank account credentials valid for 1 year. if the secret
            // already exists in the key vault, then a new version of the secret is created.
            string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v")
            {
                Properties =
                {
                    ExpiresOn = DateTimeOffset.Now.AddYears(1)
                }
            };

            client.SetSecret(secret);

            // Let's Get the bank secret from the key vault.
            KeyVaultSecret bankSecret = client.GetSecret(secretName);

            Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");

            // After one year, the bank account is still active, we need to update the expiry time of the secret.
            // The update method can be used to update the expiry attribute of the secret. It cannot be used to update
            // the value of the secret.
            bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
            SecretProperties updatedSecret = client.UpdateSecretProperties(bankSecret.Properties);

            Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");

            // Bank forced a password update for security purposes. Let's change the value of the secret in the key vault.
            // To achieve this, we need to create a new version of the secret in the key vault. The update operation cannot
            // change the value of the secret.
            var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa")
            {
                Properties =
                {
                    ExpiresOn = DateTimeOffset.Now.AddYears(1)
                }
            };

            client.SetSecret(secretNewValue);

            // The bank account was closed. You need to delete its credentials from the key vault.
            DeleteSecretOperation operation = client.StartDeleteSecret(secretName);

            // To ensure the secret is deleted on server before we try to purge it.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted secret needs to be purged.
            client.PurgeDeletedSecret(secretName);
        }
Beispiel #19
0
 /// <inheritdoc />
 public override bool Load(SecretProperties secret)
 {
     return(secret.Name.StartsWith(_prefix, StringComparison.Ordinal));
 }
 internal SecretData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData, string location, IReadOnlyDictionary <string, string> tags, SecretProperties properties) : base(id, name, resourceType, systemData, location, tags)
 {
     Properties = properties;
 }
Beispiel #21
0
 public override bool Load(SecretProperties secret)
 {
     return(secret.Name.StartsWith(_prefix));
 }
Beispiel #22
0
        private static void VerifySecretToload(ParallelSecretLoader secretLoader, Dictionary <string, LoadedSecret> newLoadedSecrets, Dictionary <string, LoadedSecret> oldLoadedSecrets, SecretProperties secret)
        {
            var secretId = secret.Name;

            if (oldLoadedSecrets != null &&
                oldLoadedSecrets.TryGetValue(secretId, out var existingSecret) &&
                existingSecret.IsUpToDate(secret.UpdatedOn))
            {
                oldLoadedSecrets.Remove(secretId);
                newLoadedSecrets.Add(secretId, existingSecret);
            }
            else
            {
                secretLoader.AddSecretToLoad(secret.Name);
            }
        }
        public override async Task RunAsync(CancellationToken cancellationToken)
        {
            try
            {
                _console.WriteLine($"Synchronizing secrets contained in {_manifestFile}");
                if (_force || _forcedSecrets.Any())
                {
                    bool confirmed = await _console.ConfirmAsync(
                        "--force or --force-secret is set, this will rotate one or more secrets ahead of schedule, possibly causing service disruption. Continue? ");

                    if (!confirmed)
                    {
                        return;
                    }
                }

                DateTimeOffset now      = _clock.UtcNow;
                SecretManifest manifest = SecretManifest.Read(_manifestFile);
                using StorageLocationType.Bound storage = _storageLocationTypeRegistry
                                                          .Get(manifest.StorageLocation.Type).BindParameters(manifest.StorageLocation.Parameters);
                using var disposables = new DisposableList();
                var references = new Dictionary <string, StorageLocationType.Bound>();
                foreach (var(name, storageReference) in manifest.References)
                {
                    var bound = _storageLocationTypeRegistry.Get(storageReference.Type)
                                .BindParameters(storageReference.Parameters);
                    disposables.Add(bound);
                    references.Add(name, bound);
                }

                Dictionary <string, SecretProperties> existingSecrets = (await storage.ListSecretsAsync()).ToDictionary(p => p.Name);

                List <(string name, SecretManifest.Secret secret, SecretType.Bound bound, HashSet <string> references)> orderedSecretTypes = GetTopologicallyOrderedSecrets(manifest.Secrets);
                var regeneratedSecrets = new HashSet <string>();

                foreach (var(name, secret, secretType, secretReferences) in orderedSecretTypes)
                {
                    _console.WriteLine($"Synchronizing secret {name}, type {secret.Type}");
                    List <string> names    = secretType.GetCompositeSecretSuffixes().Select(suffix => name + suffix).ToList();
                    var           existing = new List <SecretProperties>();
                    foreach (string n in names)
                    {
                        existingSecrets.Remove(n, out SecretProperties e);
                        existing.Add(e); // here we intentionally ignore the result of Remove because we want to add null to the list to represent "this isn't in the store"
                    }

                    bool regenerate = false;

                    if (_force)
                    {
                        _console.WriteLine("--force is set, will rotate.");
                        regenerate = true;
                    }
                    else if (_forcedSecrets.Contains(name))
                    {
                        _console.WriteLine($"--force-secret={name} is set, will rotate.");
                        regenerate = true;
                    }
                    else if (existing.Any(e => e == null))
                    {
                        _console.WriteLine("Secret not found in storage, will create.");
                        // secret is missing from storage (either completely missing or partially missing)
                        regenerate = true;
                    }
                    else if (regeneratedSecrets.Overlaps(secretReferences))
                    {
                        _console.WriteLine("Referenced secret was rotated, will rotate.");
                        regenerate = true;
                    }
                    else
                    {
                        // If these fields aren't the same for every part of a composite secrets, assume the soonest value is right
                        DateTimeOffset nextRotation = existing.Select(e => e.NextRotationOn).Min();
                        DateTimeOffset expires      = existing.Select(e => e.ExpiresOn).Min();
                        if (nextRotation <= now)
                        {
                            _console.WriteLine($"Secret scheduled for rotation on {nextRotation}, will rotate.");
                            // we have hit the rotation time, rotate
                            regenerate = true;

                            // since the rotation runs weekly, we need a 1 week grace period
                            // where verification runs will not fail, but rotation will happen.
                            // otherwise a secret scheduled for rotation on tuesday, will cause
                            // a build failure on wednesday, before it gets rotated normally on the following monday
                            // the verification mode is to catch the "the rotation hasn't happened in months" case
                            if (_verifyOnly && nextRotation > now.AddDays(-7))
                            {
                                _console.WriteLine("Secret is within verification grace period.");
                                regenerate = false;
                            }
                        }
                        if (expires <= now)
                        {
                            _console.WriteLine($"Secret expired on {expires}, will rotate.");
                            // the secret has expired, this shouldn't happen in normal operation but we should rotate
                            regenerate = true;
                        }
                    }

                    if (!regenerate)
                    {
                        _console.WriteLine("Secret is fine.");
                    }


                    if (regenerate && _verifyOnly)
                    {
                        _console.LogError($"Secret {name} requires rotation.");
                    }
                    else if (regenerate)
                    {
                        _console.WriteLine($"Generating new value(s) for secret {name}...");
                        SecretProperties primary = existing.FirstOrDefault(p => p != null);
                        IImmutableDictionary <string, string> currentTags = primary?.Tags ?? ImmutableDictionary.Create <string, string>();
                        var context = new RotationContext(name, currentTags, storage, references);
                        List <SecretData> newValues = await secretType.RotateValues(context, cancellationToken);

                        IImmutableDictionary <string, string> newTags = context.GetValues();
                        regeneratedSecrets.Add(name);
                        _console.WriteLine("Done.");
                        _console.WriteLine($"Storing new value(s) in storage for secret {name}...");
                        foreach (var(n, value) in names.Zip(newValues))
                        {
                            await storage.SetSecretValueAsync(n, new SecretValue(value.Value, newTags, value.NextRotationOn, value.ExpiresOn));
                        }

                        _console.WriteLine("Done.");
                    }
                }

                if (!_verifyOnly)
                {
                    foreach (var(name, key) in manifest.Keys)
                    {
                        await storage.EnsureKeyAsync(name, key);
                    }

                    foreach (var(name, value) in existingSecrets)
                    {
                        _console.LogWarning($"Extra secret '{name}' consider deleting it.");
                    }
                }
            }
            catch (FailWithExitCodeException)
            {
                throw;
            }
            catch (HumanInterventionRequiredException hire)
            {
                _console.LogError(hire.Message);
                throw new FailWithExitCodeException(42);
            }
            catch (Exception ex)
            {
                _console.LogError($"Unhandled Exception: {ex.Message}");
                throw new FailWithExitCodeException(-1);
            }
        }
 /// <summary>
 /// Maps secret to a configuration key.
 /// </summary>
 /// <param name="secret">The <see cref="KeyVaultSecret"/> instance.</param>
 /// <returns>Configuration key name to store secret value.</returns>
 public virtual bool Load(SecretProperties secret)
 {
     return(true);
 }
 public override bool Load(SecretProperties properties)
 {
     return(properties.Name.StartsWith(_prefix));
 }
Beispiel #26
0
        internal static FrontDoorSecretData DeserializeFrontDoorSecretData(JsonElement element)
        {
            ResourceIdentifier id         = default;
            string             name       = default;
            ResourceType       type       = default;
            SystemData         systemData = default;
            Optional <FrontDoorProvisioningState> provisioningState = default;
            Optional <FrontDoorDeploymentStatus>  deploymentStatus  = default;
            Optional <string>           profileName = default;
            Optional <SecretProperties> parameters  = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = new ResourceType(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("systemData"))
                {
                    systemData = JsonSerializer.Deserialize <SystemData>(property.Value.ToString());
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("provisioningState"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            provisioningState = new FrontDoorProvisioningState(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("deploymentStatus"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            deploymentStatus = new FrontDoorDeploymentStatus(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("profileName"))
                        {
                            profileName = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("parameters"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            parameters = SecretProperties.DeserializeSecretProperties(property0.Value);
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new FrontDoorSecretData(id, name, type, systemData, Optional.ToNullable(provisioningState), Optional.ToNullable(deploymentStatus), profileName.Value, parameters.Value));
        }