# HashiCorp Vault

Optional Socigy.OpenSource.DB.HashiCorp package — field encryption keyed from Vault and rotating PostgreSQL credentials from Vault's Database secrets engine, wired with one DI call each.

The optional **`Socigy.OpenSource.DB.HashiCorp`** package integrates Socigy with [HashiCorp Vault](https://www.vaultproject.io/) for two things:

1. **Field encryption** — supplies the `IFieldEncryptor` for [`[Encrypted]` columns](/database/0.3.1/defining-models/encrypted-columns), keyed from Vault.
2. **Rotating DB credentials** — supplies an `IDbCredentialsProvider` that leases short-lived PostgreSQL credentials from Vault's Database secrets engine, which the generated connection factory consumes automatically.

```bash
dotnet add package Socigy.OpenSource.DB.HashiCorp
```

> **NOTE** This package depends on the main `Socigy.OpenSource.DB` package and `VaultSharp`. Both Vault features are independent — register either or both.

## Field encryption

The data-encryption key is read from a **Vault KV-v2 secret at startup** and used for fast, local AES-256-CBC + HMAC encryption — so per-field crypto stays synchronous with no Vault round-trip per row. Store a Base64-encoded 32-byte key in Vault:

```bash
vault kv put secret/socigy/db-encryption-key key="$(openssl rand -base64 32)"
```

Then register it:

```csharp
builder.Services.AddSocigyVaultEncryption(o =>
{
    o.Address = "https://vault.example.com:8200";
    o.Token = builder.Configuration["Vault:Token"];     // or AppRoleId + AppRoleSecretId
    o.KvMountPoint = "secret";
    o.KeySecretPath = "socigy/db-encryption-key";
    o.KeyField = "key";
});
```

At host start the package reads the key and installs the ambient `SocigyFieldEncryption` encryptor, so every `[Encrypted]` column just works.

> **NOTE** Key material is fetched into process memory for local crypto. Rotating the key means updating the KV secret and re-encrypting existing rows. (A Transit data-key envelope mode that keeps old rows readable across rotations is a planned enhancement.)

## Rotating database credentials

Configure Vault's Database secrets engine with a role per database, then map each Socigy database name to its Vault role:

```csharp
builder.Services.AddSocigyVaultCredentials(o =>
{
    o.Address = "https://vault.example.com:8200";
    o.AppRoleId = builder.Configuration["Vault:RoleId"];
    o.AppRoleSecretId = builder.Configuration["Vault:SecretId"];
    o.DatabaseMountPoint = "database";
    o.BaseConnectionString = "Host=db.internal;Port=5432;Pooling=true";   // no user/pass
    o.DatabaseRoles["AuthDb"] = "auth-db-role";
    o.DatabaseRoles["UserDb"] = "user-db-role";
    o.RefreshInterval = TimeSpan.FromMinutes(30);
});

builder.AddAuthDb();   // the generated factory picks up IDbCredentialsProvider automatically
builder.AddUserDb();
```

How it fits together:

- At startup the package leases credentials for each configured database and composes a connection string (`BaseConnectionString` + the leased `Username`/`Password`), cached in memory.
- The generated connection factory calls the provider **synchronously** for the current connection string each time it opens a connection — see [Connections & DI](/database/0.3.1/core-concepts/connections-and-di).
- A background timer renews the lease every `RefreshInterval`. When credentials rotate, new connections use the new string and Npgsql's old pool drains naturally.

## Authentication

Both `Add…` calls accept either a **token** (`Token`) or **AppRole** (`AppRoleId` + `AppRoleSecretId`). AppRole is recommended for production workloads.

## Diagnostics

All background actions are observable so admins can track what the library does:

- **OpenTelemetry spans** under the existing `Socigy.OpenSource.DB` ActivitySource — `vault.encryption.key.fetch` and `vault.credentials.lease` (with `db.name`, `vault.database.role`, and lease-duration tags). Subscribe with `AddSource("Socigy.OpenSource.DB")` (see [Diagnostics & OpenTelemetry](/database/0.3.1/observability/diagnostics)).
- **`ILogger` messages** under categories `Socigy.OpenSource.DB.Vault.Encryption` and `Socigy.OpenSource.DB.Vault.Credentials`: key load, each credential lease (database, role, user, lease seconds), renewal ticks, and failures. The connection factory also logs when it refreshes rotating credentials, and `SocigyFieldEncryption.Configure` logs when an encryptor is installed.
