Skip to content

Granit.Vault & Encryption

Granit.Encryption provides a pluggable string encryption service with AES-256-CBC as the default provider. Granit.Vault is the abstraction layer defining ITransitEncryptionService and IDatabaseCredentialProvider. Provider packages implement those interfaces: Granit.Vault.HashiCorp wraps VaultSharp for HashiCorp Vault Transit encryption and dynamic database credentials, Granit.Vault.Azure uses Azure Key Vault for RSA-OAEP-256 encryption and dynamic credentials via Key Vault Secrets, Granit.Vault.Aws targets AWS KMS and Secrets Manager, and Granit.Vault.GoogleCloud uses Google Cloud KMS for symmetric encryption and Secret Manager for dynamic database credentials. All provider modules are automatically disabled in Development environments so no external vault server is required locally.

  • DirectoryGranit.Encryption/ AES-256-CBC default, IStringEncryptionService
    • DirectoryGranit.Vault/ Abstraction layer — ITransitEncryptionService, IDatabaseCredentialProvider, localization
      • Granit.Vault.HashiCorp HashiCorp Vault provider — VaultSharp client, Transit encryption, dynamic database credentials
      • Granit.Vault.Azure Azure Key Vault provider (RSA-OAEP-256), dynamic credentials
      • Granit.Vault.Aws AWS KMS + Secrets Manager provider
      • Granit.Vault.GoogleCloud Google Cloud KMS encryption, Secret Manager credentials
PackageRoleDepends on
Granit.EncryptionIStringEncryptionService, AES-256-CBC providerGranit.Core
Granit.VaultAbstraction layer — ITransitEncryptionService, IDatabaseCredentialProvider, localizationGranit.Encryption
Granit.Vault.HashiCorpHashiCorp Vault provider — VaultSharp client, Transit encryption, dynamic database credentialsGranit.Vault
Granit.Vault.AzureAzure Key Vault encryption (RSA-OAEP-256), dynamic credentials from Key Vault SecretsGranit.Vault
Granit.Vault.AwsAWS KMS encryption, dynamic credentials from Secrets ManagerGranit.Vault
Granit.Vault.GoogleCloudGoogle Cloud KMS symmetric encryption, dynamic credentials from Secret ManagerGranit.Vault
graph TD
    VH[Granit.Vault.HashiCorp] --> V[Granit.Vault]
    VA[Granit.Vault.Azure] --> V
    VAW[Granit.Vault.Aws] --> V
    VGC[Granit.Vault.GoogleCloud] --> V
    V --> E[Granit.Encryption]
    E --> C[Granit.Core]
[DependsOn(typeof(GranitEncryptionModule))]
public class AppModule : GranitModule { }

Registers IStringEncryptionService with the AES provider by default. No external dependencies required.

The main abstraction for encrypting and decrypting strings:

public interface IStringEncryptionService
{
string Encrypt(string plainText);
string? Decrypt(string cipherText);
}

Encrypt returns a Base64-encoded ciphertext. Decrypt returns the original string, or null if decryption fails (wrong key, corrupted data).

public class PatientNoteService(IStringEncryptionService encryption)
{
public string ProtectNote(string note) =>
encryption.Encrypt(note);
public string? RevealNote(string encryptedNote) =>
encryption.Decrypt(encryptedNote);
}

The default provider derives the encryption key from a passphrase using PBKDF2 and encrypts with AES-256-CBC. Each encryption operation generates a random 16-byte IV.

{
"Encryption": {
"PassPhrase": "<from-vault-config-provider>",
"KeySize": 256,
"ProviderName": "Aes"
}
}

The ProviderName option selects the active encryption provider at runtime:

ProviderValueBackend
AES (default)"Aes"Local AES-256-CBC with PBKDF2 key derivation
Vault Transit"Vault"HashiCorp Vault Transit engine (requires Granit.Vault.HashiCorp)
Azure Key Vault"AzureKeyVault"Azure Key Vault RSA-OAEP-256 (requires Granit.Vault.Azure)

When ProviderName is "Vault", IStringEncryptionService delegates to VaultStringEncryptionProvider, which calls Vault Transit under the hood.


Granit.Vault is the abstraction package. It defines ITransitEncryptionService and IDatabaseCredentialProvider — provider packages (Granit.Vault.HashiCorp, Granit.Vault.Azure, Granit.Vault.Aws) supply the implementations.

The transit encryption abstraction for encrypt/decrypt operations:

public interface ITransitEncryptionService
{
Task<string> EncryptAsync(
string keyName, string plaintext,
CancellationToken cancellationToken = default);
Task<string> DecryptAsync(
string keyName, string ciphertext,
CancellationToken cancellationToken = default);
}

Ciphertext follows the Vault format: vault:v1:base64encodeddata...

public class SensitiveDataService(ITransitEncryptionService transit)
{
public async Task<string> ProtectSsnAsync(
string ssn, CancellationToken cancellationToken)
{
return await transit.EncryptAsync(
"pii-data", ssn, cancellationToken).ConfigureAwait(false);
// Returns: "vault:v1:AbCdEf..."
}
public async Task<string> RevealSsnAsync(
string encryptedSsn, CancellationToken cancellationToken)
{
return await transit.DecryptAsync(
"pii-data", encryptedSsn, cancellationToken).ConfigureAwait(false);
}
}

[DependsOn(typeof(GranitVaultHashiCorpModule))]
public class AppModule : GranitModule { }

VaultCredentialLeaseManager obtains short-lived database credentials from the Vault Database engine and handles automatic lease renewal at a configurable threshold (default: 75% of TTL). The connection string is updated transparently — no application restart required.

{
"Vault": {
"Address": "https://vault.example.com",
"AuthMethod": "Kubernetes",
"KubernetesRole": "my-backend"
}
}

Uses the Kubernetes service account token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.

{
"Vault": {
"Address": "https://vault.example.com",
"AuthMethod": "Kubernetes",
"KubernetesRole": "my-backend",
"KubernetesTokenPath": "/var/run/secrets/kubernetes.io/serviceaccount/token",
"DatabaseMountPoint": "database",
"DatabaseRoleName": "readwrite",
"TransitMountPoint": "transit",
"LeaseRenewalThreshold": 0.75
},
"Encryption": {
"PassPhrase": "<from-vault>",
"KeySize": 256,
"ProviderName": "Aes",
"VaultKeyName": "string-encryption"
}
}
PropertyDefaultDescription
Vault.AddressVault server URL
Vault.AuthMethod"Kubernetes""Kubernetes" or "Token"
Vault.KubernetesRole"my-backend"Vault Kubernetes auth role
Vault.DatabaseMountPoint"database"Database secrets engine mount point
Vault.DatabaseRoleName"readwrite"Database role for dynamic credentials
Vault.TransitMountPoint"transit"Transit secrets engine mount point
Vault.LeaseRenewalThreshold0.75Renew lease at this fraction of TTL
Encryption.PassPhraseAES passphrase (via secrets manager)
Encryption.KeySize256AES key size in bits
Encryption.ProviderName"Aes"Active provider: "Aes" or "Vault"
Encryption.VaultKeyName"string-encryption"Transit key name for IStringEncryptionService

AddGranitVaultHashiCorpHealthCheck registers a Vault health check that verifies connectivity and authentication status, tagged ["readiness"] for Kubernetes probe integration.


[DependsOn(typeof(GranitVaultAzureModule))]
public class AppModule : GranitModule { }

Uses Azure Key Vault’s CryptographyClient for RSA-OAEP-256 encrypt/decrypt operations. Registered as an IStringEncryptionProvider with key "AzureKeyVault".

AzureSecretsCredentialProvider reads database credentials from a Key Vault secret (JSON: {"username": "...", "password": "..."}) and polls for version changes at a configurable interval. Credential rotation is detected automatically.

{
"Vault": {
"Azure": {
"VaultUri": "https://my-vault.vault.azure.net/"
}
}
}

Uses DefaultAzureCredential — Managed Identity in Kubernetes, az login locally.

PropertyDefaultDescription
Vault:Azure:VaultUriAzure Key Vault URI
Vault:Azure:EncryptionKeyName"string-encryption"Key name for encrypt/decrypt
Vault:Azure:EncryptionAlgorithm"RSA-OAEP-256"Algorithm (RSA-OAEP-256, RSA-OAEP, RSA1_5)
Vault:Azure:DatabaseSecretNamenullSecret name for DB credentials (omit to disable)
Vault:Azure:RotationCheckIntervalMinutes5Secret rotation polling interval
Vault:Azure:TimeoutSeconds30Azure SDK operation timeout

Granit.Vault.Azure registers a health check that retrieves the configured key to verify connectivity and key availability, tagged ["readiness"].


[DependsOn(typeof(GranitVaultGoogleCloudModule))]
public class AppModule : GranitModule { }

Uses Cloud KMS CryptoKeyVersion for symmetric AES-256-GCM encrypt/decrypt operations. Registered as an IStringEncryptionProvider with key "CloudKms".

SecretManagerCredentialProvider reads database credentials from a Secret Manager secret (JSON: {"username": "...", "password": "..."}) and polls for version changes at a configurable interval. Credential rotation is detected automatically.

{
"Vault": {
"GoogleCloud": {
"ProjectId": "my-project",
"Location": "europe-west1",
"KeyRing": "my-keyring",
"CryptoKey": "string-encryption"
}
}
}

Uses Application Default Credentials — Workload Identity in GKE, gcloud auth locally.

PropertyDefaultDescription
Vault:GoogleCloud:ProjectIdGCP project ID (required)
Vault:GoogleCloud:LocationCloud KMS location, e.g. "europe-west1" (required)
Vault:GoogleCloud:KeyRingCloud KMS key ring name (required)
Vault:GoogleCloud:CryptoKeyCloud KMS crypto key for transit encryption (required)
Vault:GoogleCloud:DatabaseSecretNamenullSecret Manager secret name for DB credentials (omit to disable)
Vault:GoogleCloud:RotationCheckIntervalMinutes5Secret rotation polling interval
Vault:GoogleCloud:CredentialFilePathnullService account key JSON; ADC when null
Vault:GoogleCloud:TimeoutSeconds30API call timeout

AddGranitCloudKmsHealthCheck registers a health check that verifies KMS key accessibility, tagged ["readiness"].

CategoryKey typesPackage
ModulesGranitEncryptionModule, GranitVaultHashiCorpModule, GranitVaultAzureModule, GranitVaultAwsModule, GranitVaultGoogleCloudModule
EncryptionIStringEncryptionService (Encrypt / Decrypt)Granit.Encryption
ProviderIStringEncryptionProvider, AesStringEncryptionProviderGranit.Encryption
TransitITransitEncryptionService (EncryptAsync / DecryptAsync)Granit.Vault
CredentialsIDatabaseCredentialProviderGranit.Vault
HashiCorp ProviderVaultStringEncryptionProvider, VaultCredentialLeaseManagerGranit.Vault.HashiCorp
HashiCorp OptionsHashiCorpVaultOptionsGranit.Vault.HashiCorp
OptionsStringEncryptionOptionsGranit.Encryption
Azure ProviderAzureKeyVaultStringEncryptionProvider, IAzureKeyVaultTransitEncryptionService, IAzureDatabaseCredentialProviderGranit.Vault.Azure
Azure OptionsAzureKeyVaultOptionsGranit.Vault.Azure
Google Cloud ProviderCloudKmsTransitEncryptionService, CloudKmsStringEncryptionProvider, SecretManagerCredentialProviderGranit.Vault.GoogleCloud
Google Cloud OptionsGoogleCloudVaultOptionsGranit.Vault.GoogleCloud
ExtensionsAddGranitEncryption(), AddGranitVaultHashiCorp(), AddGranitVaultAzure(), AddGranitVaultAws(), AddGranitVaultGoogleCloud()