The problem with asynchronous-only secret retrieval
The Arcus secret store is a very reliable and well-used functionality. It provides an alternative to storing sensitive secrets alongside public application configuration values (learn more about why this is important). In the following releases, the secret store has grown in functionality and usability. It supports caching, and secret versions, lets you retrieve a single secret provider by name and is fully extensible. However, there was a piece missing in this structure — synchronous secret retrieval.
You can easily use secret providers in asynchronous contexts like an API controller, or upon each service method call. The issue occurs, however, when you want to register a service in the dependency container. If that service is to be initialized upon creation, you need the secret at creation time. Dependency containers don’t usually work with asynchronous registration (the one from Microsoft does not).
The following workaround usually happens when the Arcus secret store is used in such scenarios:
The solution of sync-support secret providers
What we did in Arcus Security v1.9 is something that is both simple and very powerful, without any breaking changes. We introduced a new ISyncSecretProvider
interface that defines the contract to retrieve secrets in a synchronous fashion. The ISyncSecretProvider
inherits from our main ISecretProvider
interface, which means that every synchronous secret provider is also an asynchronous secret provider. The transition from sync to async is a lot more straightforward than the other way around. After that, we checked our available built-in secret providers and used the synchronous version on each one that could support synchronous secret retrieval. This includes Azure Key Vault, environment variables, configuration, User Secrets, Docker Secrets and others.
The second thing we did was to provide an extension on the ISecretProvider
that lets you access synchronous secret retrieval variants without the need to inject the ISyncSecretProvider
. This removes the need to know about the synchronous interface in the first place and contact the secret store like before.
Our sample now looks like this:
Note that we still use the ISecretProvider
and do not need to add any other type of method.
✨ Like magic, all your code now supports synchronous secret retrieval.
Implementing your own synchronous secret provider
The Arcus secret store was very flexible and extensible from its inception. That is also why we made a new interface in the same style as ICachedSecretProvider
and IVersionedSecretProvider
. This allows consumers to choose if they want their secret provider to support synchronous secret retrieval or not. If not, then the secret store will either check for a different registration that does support it, or throw a NotSupportedException
.
Implementing a secret provider that checks the Windows Registry for secrets could look like this:
For more information about creating your custom secret provider, see our official documentation.
Conclusion
Adding synchronous secret retrieval to the Arcus secret store was much-needed. It was also the one true missing link for people still storing secrets in the application configuration. The IConfiguration only has synchronous operations, which made the transition toward the Arcus secret store a little bit cumbersome. Now that this feature is available, we can say that Arcus supports a fully working alternative that provides security and flexibility to your application.
For more information about the secret store, see our official documentation. If you have any questions, remarks, or comments, or just want to discuss something with us, feel free to contact the Arcus team at Codit.
Thank you for reading!
The Arcus team
Subscribe to our RSS feed