Skip to content

Secure Persistence

Anthony Turner edited this page Apr 27, 2020 · 1 revision

Secure Storage Providers (AuthJanitor.Automation.Shared.SecureStorageProviders)

When persistence of secure data is required, a Secure Storage Provider is used. For example, a Secure Storage Provider is used when caching credentials for future use, because that data is considered high-risk. When using a Secure Storage Provider, you can optionally encrypt data going to the Secure Storage Provider before it is persisted. By default, the AuthJanitor Automation tools use KeyVaultSecureStorageProvider for secure persistence.

Creating a new Secure Storage Provider

Creating a new Secure Storage Provider is accomplished by extending the ISecureStorageProvider interface:

/// <summary>
/// Persist sensitive content to secure storage
/// </summary>
/// <typeparam name="T">Type of object being persisted</typeparam>
/// <param name="expiry">Expiry of data</param>
/// <param name="persistedObject">Object to persist</param>
/// <returns>ID of persisted object</returns>
Task<Guid> Persist<T>(DateTimeOffset expiry, T persistedObject);

/// <summary>
/// Retrieve sensitive content from secure storage by its ID
/// </summary>
/// <typeparam name="T">Type of object being retrieved</typeparam>
/// <param name="persistenceId">ID of persisted object</param>
/// <returns>Persisted object</returns>
Task<T> Retrieve<T>(Guid persistenceId);

/// <summary>
/// Destroy a persisted object by its ID
/// </summary>
/// <param name="persistenceId">ID of persisted object</param>
Task Destroy(Guid persistenceId);

Persistence Encryption (AuthJanitor.Automation.Shared.PersistenceEncryption)

When storing sensitive information, it is advised that it be encrypted prior to storage. By default, NoPersistenceEncryption and Rfc2898AesPersistenceEncryption are provided, and the Rfc2898AesPersistenceEncryption strategy is used by default in the AuthJanitor Automation tools.

One example of this in use is with KeyVaultSecureStorageProvider, whose constructor takes an instance of IPersistenceEncryption. This encryption strategy is applied implicitly on objects being stored as a part of the Persist/Retrieve methods.

Creating a new Persistence Encryption strategy

Creating a new Persistence Encryption strategy is accomplished by extending the IPersistenceEncryption interface:

/// <summary>
/// Encrypt sensitive data
/// </summary>
/// <param name="salt">Encryption salt</param>
/// <param name="plainText">Text to encrypt</param>
/// <returns>Encrypted ciphertext</returns>
Task<string> Encrypt(string salt, string plainText);

/// <summary>
/// Decrypt sensitive data
/// </summary>
/// <param name="salt">Encryption salt</param>
/// <param name="cipherText">Encrypted ciphertext</param>
/// <returns>Decrypted text</returns>
Task<string> Decrypt(string salt, string cipherText);