1
votes

I'd like to know if it is possible to get all Azure Key Vault Secrets by a prefix.

Let's say I have 3 secrets.

key: pre-secret1 
value: value1

key: secret2 
value: value2

key: pre-secret3
value: value3

I would like to get all secrets with a prefix pre and serialize them to JSON. In the future, I will have more secrets with a prefix so I don't want to read by secret manually. So when I add a new secret with a prefix, my function will return JSON with a new value as well.

The question is: is it possible to get secrets from Azure Key Vault by prefix and serialize dynamically to JSON?

Update: I would like to use it in ASP.NET Core 3.1 and C#. Update2: I added how I can get one secret.

var client = new SecretClient(vaultUri: new Uri(kvUri), credential: new DefaultAzureCredential(true));
var secret = client.GetSecret("secret-name");
1
I have updated my post. I would like to use it in ASP.NET Core 3.1 and C#.mskuratowski
Can you not just add a wildcard to the name when querying secrets? Please show the code you currently have so we can help.Rufus L
@RufusL I added how I can get one secret. There is no method to get secrets.mskuratowski
You might try something like this: stackoverflow.com/questions/53499397/…Rufus L
You need to get all secrets await client.GetSecretsAsync(VaultUrl), filter it then serialize it. Seems to me you're abusing Key Vault for use cases it has never been designed to accommodate.evilSnobu

1 Answers

4
votes

You can use below code to achieve this. The GetSecretsAsync method gives you a dictionary of all the keys and secrets from the vault.

public async Task<IDictionary<string, string>> GetSecretsAsync(string vaultBaseUrl, string prefix = null, string keyVaultKeyDelimeter = "--", string configurationKeyDelimeter = ":")
            {
                // validation
                BaseUrlValidation(vaultBaseUrl);

            // variable declartion
            IDictionary<string, string> secretCollection = new Dictionary<string, string>();
            var updatedPrefix = string.IsNullOrWhiteSpace(prefix) ? prefix : $"{prefix}{keyVaultKeyDelimeter}";
            List<SecretItem> secretIdentifierCollection = new List<SecretItem>();

            // reading and adding secrets
            var secrets = await this.keyVaultClient.GetSecretsAsync(vaultBaseUrl).ConfigureAwait(false);
            string nextPageLink = secrets.NextPageLink;
            secretIdentifierCollection.AddRange(secrets);

            while (!string.IsNullOrWhiteSpace(nextPageLink))
            {
                // reading and adding secrets
                var nextSecrets = await this.keyVaultClient.GetSecretsNextAsync(nextPageLink).ConfigureAwait(false);
                secretIdentifierCollection.AddRange(nextSecrets);
                nextPageLink = nextSecrets.NextPageLink;
            }

            if (!secretIdentifierCollection.Any())
            {
                return secretCollection;
            }

            // add filtered secrets to dictionary and remove prefix if any
            foreach (var secretId in FilterPrefixMatchingSecrets(updatedPrefix, secretIdentifierCollection))
            {
                await this.FetchSecretDetailsAsync(updatedPrefix, keyVaultKeyDelimeter, configurationKeyDelimeter, secretCollection, secretId);
            }

            return secretCollection;
        }

 private async Task FetchSecretDetailsAsync(string prefix, string keyVaultKeyDelimeter, string configurationKeyDelimeter, IDictionary<string, string> secretCollection, string secretId)
        {
            var secretDetails = await this.keyVaultClient.GetSecretAsync(secretId).ConfigureAwait(false);
            var secretName = secretDetails.SecretIdentifier.Name.Substring(string.IsNullOrWhiteSpace(prefix) ? 0 : prefix.Length).Replace(keyVaultKeyDelimeter, configurationKeyDelimeter);
            if (!secretCollection.ContainsKey(secretName))
            {
                secretCollection.Add(secretName, secretDetails.Value);
            }
        }