.NET Encryption
The E4A.PostGuard SDK provides sending-side encryption for .NET applications. It handles file encryption, signing via API key, and upload to Cryptify. Decryption is not supported; the receiving side uses the PostGuard website or email plugins.
Constructor
using E4A.PostGuard;
using E4A.PostGuard.Models;
var pg = new PostGuard(new PostGuardConfig
{
PkgUrl = "https://pkg.staging.postguard.eu",
CryptifyUrl = "https://storage.staging.postguard.eu",
Headers = new Dictionary<string, string> // optional
{
["X-My-Client"] = "v1.0"
}
});PkgUrl and CryptifyUrl must be absolute https:// URLs. The constructor throws ArgumentException for any other scheme (including http://, ftp://, ws://), as well as for relative or empty values. Set AllowInsecureUrls = true to permit http://localhost during local development.
| Option | Type | Required | Description |
|---|---|---|---|
PkgUrl | string | Yes | URL of the PKG server. Must be an absolute https:// URL. |
CryptifyUrl | string | No | URL of the Cryptify file storage service. Required for UploadAsync(). Must be an absolute https:// URL. |
AllowInsecureUrls | bool | No | Allow http://localhost URLs for local dev. Default false. Any non-https:// value still throws ArgumentException. |
Headers | Dictionary<string, string> | No | Custom HTTP headers included in all requests |
HttpClient | HttpClient? | No | Caller-supplied HttpClient. The SDK reuses it for all PKG and Cryptify calls and does not dispose it. When unset, PostGuard creates and owns its own long-lived client. |
Timeout | TimeSpan? | No | Request timeout for the SDK-owned HttpClient. Ignored when HttpClient is supplied (the caller owns that client's timeout). Defaults to HttpClient's built-in 100 second default when unset. |
Lifetime
PostGuard implements IDisposable. The SDK keeps a single long-lived HttpClient (backed by a SocketsHttpHandler with a 2 minute PooledConnectionLifetime) and reuses it across calls, so reuse one PostGuard instance per process for sustained workloads rather than constructing a new one per request.
using var pg = new PostGuard(config);When PostGuardConfig.HttpClient is unset (the default), pg.Dispose() disposes the SDK-owned client. When you inject your own HttpClient, the SDK leaves it alone; ownership stays with the caller, which fits DI scenarios where the container manages the client's lifetime.
Encrypt
pg.Encrypt() returns a Sealed builder. Nothing happens until you call a terminal method.
var sealed = pg.Encrypt(new EncryptInput
{
Files = [new PgFile("report.txt", fileStream)],
Recipients = [
pg.Recipient.Email("citizen@example.com"),
pg.Recipient.EmailDomain("info@org.nl")
],
Sign = pg.Sign.ApiKey("PG-your-key")
});Input Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Files | PgFile[] | Yes | Files to encrypt. Each PgFile has a Name (string) and Stream (Stream). |
Recipients | RecipientBuilder[] | Yes | One or more recipients |
Sign | ISign | Yes | Signing method (currently only pg.Sign.ApiKey()) |
Terminal Methods
| Method | Returns | Description |
|---|---|---|
UploadAsync(ct?) | UploadResult | Encrypt and upload to Cryptify silently, no Cryptify-sent emails. Returns UUID. |
UploadAsync(options, ct?) | UploadResult | Same, plus opt-in Cryptify-sent emails (see below). |
ToBytesAsync(ct?) | byte[] | Encrypt and return the raw sealed bytes. |
All methods accept an optional CancellationToken.
Upload with Notification
The upload is silent by default. Both recipient and sender mails are opt-in. Set Recipients = true to email each recipient with a download link, and/or Sender = true for a confirmation back to the sender.
var result = await sealed.UploadAsync(new UploadOptions
{
Notify = new NotifyOptions
{
Recipients = true, // email each recipient (default false)
Sender = false, // confirmation to sender (default false)
Message = "Your documents are ready.",
Language = "EN" // "EN" (default) or "NL"
}
});
Console.WriteLine(result.Uuid);Notify options
| Property | Type | Default | Description |
|---|---|---|---|
Recipients | bool | false | Send a download-link email to each recipient |
Sender | bool | false | Send a delivery confirmation to the sender |
Message | string? | null | Optional unencrypted text included in any mail sent |
Language | string | "EN" | Notification email template language ("EN" or "NL") |
Recipients
// Encrypt for an exact email address
pg.Recipient.Email("alice@example.com")
// Encrypt for anyone with an email at a domain
pg.Recipient.EmailDomain("alice@example-org.com")
// Require extra attributes (fluent chaining)
pg.Recipient.Email("alice@example.com")
.ExtraAttribute("pbdf.gemeente.personalData.surname", "Smith")
.ExtraAttribute("pbdf.sidn-pbdf.mobilenumber.mobilenumber", "0612345678")Signing
The .NET SDK supports API key signing only. API keys bypass interactive Yivi sessions and are intended for server-to-server use.
pg.Sign.ApiKey("PG-your-key")Raw Bytes (No Upload)
To get the encrypted bytes without uploading to Cryptify:
byte[] encrypted = await sealed.ToBytesAsync();
// Deliver the bytes however you want