Key Management in CI/CD (Azure) (anti-forgery)

January 11, 2018
azure cd/cd

Using keys for anti-forgery in Azure in a CI/CD environment

Recently I started getting the oddest exceptions:

An exception was thrown while deserializing the token.The key {guid} was not found in the key ring.

Hmm.

After looking in the logs and trying to discern where this was populating itself (cause I wouldn't do this) from, I got it down to the anti-forgery token that is automatically added to ASP.NET Core 2 forms. But there's no code for that. It's just there. Always. Like the Force.

I had to put my mad debugging/troubleshotting skillz to bear on this particularly vague issue:

Google with Bing (bing gives me points, I just bought 12 months of XBOX Live for 29K points)

And I found some references to keys and changes and...aha. Some more Bingoogling..and my issue:

CI/CD. Anythign continual is guaranteed to complicate your life. Live with it.

In this case, the slot swapping in Azure when using the CI/CD workflow can (but might not) cause an issue with a mismatch of keys. From I have been able to figure out, if the page was loaded in the browser with slot 1 and then slot 2 becomes slot 1 and the user posts - you're getting the error. And no amount of refreshing is going to clear it. Perhaps cache clearing - didn't try it, too much work for a reg (slang for regular user).

The solutions are easy, pick a place for your key. There are at least 76 locations for the key. I went with Blob storage. There's an error today with using the URI based SAS tokenized version of the PersistKeysToAzureBlobStorage function. So I had to go the long way:

            var storageAccount = CloudStorageAccount.Parse(Configuration.GetValue<string>("AzureStorage"));
            var blobClient = storageAccount.CreateCloudBlobClient();
            var container = blobClient.GetContainerReference("keys");
            services.AddDataProtection().PersistKeysToAzureBlobStorage(container, "keys.xml");

This is the simple, straigh tup version. There are some other options which you should read through for encrypting at rest (which I think is fancy lingo for not storing in plaintext).

And voila, issues fixed. And I haven't had any issued (that's zero (0) exceptions) for about 5 minutes - so it must be working.

 

Reference:

https://www.bing.com

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-management

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers#data-protection-implementation-key-storage-providers

https://github.com/aspnet/DataProtection/blob/rel/1.1.0/src/Microsoft.AspNetCore.DataProtection.AzureStorage/AzureDataProtectionBuilderExtensions.cs

https://github.com/aspnet/Home/issues/2759