Capsara.SDK 1.0.4

dotnet add package Capsara.SDK --version 1.0.4
                    
NuGet\Install-Package Capsara.SDK -Version 1.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Capsara.SDK" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Capsara.SDK" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="Capsara.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Capsara.SDK --version 1.0.4
                    
#r "nuget: Capsara.SDK, 1.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Capsara.SDK@1.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Capsara.SDK&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=Capsara.SDK&version=1.0.4
                    
Install as a Cake Tool

Capsara SDK - .NET

A capsa is a zero-knowledge encrypted envelope for securely exchanging files and data between multiple parties. Each capsa is sealed with its own encryption key and can only be opened by the parties explicitly authorized to access it. Capsara never sees your content, your keys, or your metadata.

Features

  • AES-256-GCM encryption with unique keys per capsa
  • RSA-4096-OAEP key encryption for multi-party access
  • Compression with gzip before encryption
  • Digital signatures using RSA-SHA256 for sender authenticity
  • Encrypted subject, body, and structured data
  • Batch sending with automatic chunking

Installation

dotnet add package Capsara.SDK

Or via the Package Manager Console:

Install-Package Capsara.SDK

Initialize the Client

using Capsara.SDK;

var client = new CapsaraClient("https://capsara-env-api-url.com");

Authentication

Authentication requires two steps: login with your credentials, then set your private key for cryptographic operations.

Login

using Capsara.SDK.Models;

await client.LoginAsync(new AuthCredentials("you@example.com", "..."));

Set Private Key

After logging in, set your private key for signing and decryption. Generate and register your keypair using GenerateKeyPair() and AddPublicKeyAsync(), then store the private key securely.

// Your code to load the private key from secure storage (key vault, HSM, etc.)
var privateKey = LoadPrivateKeyFromSecureStorage();

client.SetPrivateKey(privateKey);

Sending Capsas

Use the CapsaBuilder to create capsas with recipients and files. Always use SendCapsasAsync() even for a single capsa since it handles encryption and batching efficiently.

using Capsara.SDK.Exceptions;
using Capsara.SDK.Models;

try
{
    // Create a builder for each capsa you want to send
    var builder = await client.CreateCapsaBuilderAsync();

    // Add recipients (can add multiple)
    builder.AddRecipient("party_recipient1");
    builder.AddRecipient("party_recipient2");

    // Add files from path or buffer
    builder.AddFile(FileInput.FromPath("./documents/policy.pdf"));
    builder.AddFile(FileInput.FromBuffer(
        Encoding.UTF8.GetBytes("Policy data here"),
        "policy-data.txt"
    ));

    // Add optional metadata
    builder.Subject = "Policy Documents - Q1 2025";
    builder.Body = "Please review the attached policy documents.";
    builder.Structured = new { PolicyNumber = "POL-12345", EffectiveDate = "2025-01-01" };

    // Set expiration
    builder.Expiration = DateTimeOffset.UtcNow.AddDays(90);

    // Send
    var result = await client.SendCapsasAsync(new[] { builder });
    Console.WriteLine($"Sent {result.Successful} capsa(s)");

    if (result.Failed > 0)
    {
        Console.Error.WriteLine($"{result.Failed} capsas failed to send");
    }
}
catch (CapsaraException ex)
{
    Console.Error.WriteLine($"Failed to send: {ex.Message}");
}

A capsa maps one-to-one with a matter, which is a unique combination of sender, recipient, client, and action. You can send multiple capsas in one call:

var matter1 = await client.CreateCapsaBuilderAsync();
matter1.Subject = "Client 1 - New Home Policy";
matter1
    .AddRecipient("party_org_b")
    .AddFile(FileInput.FromPath("./policy.pdf"));

var matter2 = await client.CreateCapsaBuilderAsync();
matter2.Subject = "Client 1 - Auto Endorsement";
matter2.Body = "Endorsement effective 3/1. No documents required.";
matter2.AddRecipient("party_org_b");

await client.SendCapsasAsync(new[] { matter1, matter2 });

The SDK automatically splits large batches to stay within server limits.

Receiving Capsas

List Capsas

var response = await client.ListCapsasAsync(new CapsaListFilters
{
    Status = "active",
    Limit = 50
});

Console.WriteLine($"Found {response.Capsas.Count} capsas");

foreach (var capsa in response.Capsas)
{
    Console.WriteLine($"- {capsa.Id}: {capsa.FileCount} files");
    Console.WriteLine($"  Created: {capsa.CreatedAt}");
    Console.WriteLine($"  From: {capsa.CreatorId}");
}

// Pagination
if (response.Pagination.HasMore)
{
    var nextPage = await client.ListCapsasAsync(new CapsaListFilters
    {
        After = response.Pagination.NextCursor
    });
}

Get Capsa and Download Files

var capsa = await client.GetDecryptedCapsaAsync("capsa_abc-123");

Console.WriteLine($"Subject: {capsa.Subject}");
Console.WriteLine($"Body: {capsa.Body}");
Console.WriteLine($"Structured data: {capsa.Structured}");

// Download each file
foreach (var file in capsa.Files)
{
    var result = await client.DownloadFileAsync(capsa.PackageId, file.Id);
    await File.WriteAllBytesAsync($"./downloads/{result.Filename}", result.Data);
}

Delegation

Capsara supports delegation for scenarios where a system acts on behalf of a party. For example, an agency management system (AMS) might process capsas on behalf of the agencies it serves. When a capsa is sent to a delegated recipient, the delegate receives its own RSA-encrypted copy of the master key. If the recipient also has a public key registered in the system, they receive their own encrypted copy as well. Otherwise, only the delegate can decrypt on their behalf.

If you're a delegate, the flow is identical to receiving. List your capsas and check the ActingFor field on each one to see which party it belongs to. This lets you route the data to the correct recipient in your system.

// Authenticate as the delegate (e.g., an AMS)
var client = new CapsaraClient("https://capsara-env-api-url.com");
await client.LoginAsync(new AuthCredentials("ams@example.com", "..."));
client.SetPrivateKey(LoadPrivateKeyFromSecureStorage());

// List capsas (includes capsas for all parties you represent)
var response = await client.ListCapsasAsync();

foreach (var summary in response.Capsas)
{
    var capsa = await client.GetDecryptedCapsaAsync(summary.Id);

    // Check who this capsa is for
    if (capsa.ActingFor != null)
    {
        Console.WriteLine($"Capsa {summary.Id} is for agency {capsa.ActingFor}");
        RouteToAgency(capsa.ActingFor, capsa);
    }

    // Download and process files
    foreach (var file in capsa.Files)
    {
        var result = await client.DownloadFileAsync(summary.Id, file.Id);
        ProcessFile(capsa.ActingFor, result.Filename, result.Data);
    }
}

Encryption

Every capsa is protected by a unique AES-256-GCM symmetric key (the "master key") generated at send time. Files and metadata (subject, body, and structured data) are each encrypted with this master key using a fresh random IV, producing authenticated ciphertext that guarantees both confidentiality and tamper detection. The master key itself is then encrypted once per authorized party and any authorized delegates using their RSA-4096 public key with OAEP-SHA256 padding, so only the holder of the corresponding private key can recover it. Each file is independently hashed with SHA-256 before encryption, and these hashes along with all IVs are bound into a canonical string that the sender signs using RS256 (RSA-SHA256 in JWS format). Recipients and the server validate this signature against the sender's public key before trusting any content, ensuring both authenticity and integrity of the entire capsa. Key fingerprints are SHA-256 hashes of the public key PEM, providing a compact identifier for key verification. Files are gzip-compressed before encryption by default to reduce storage and transfer costs. All encryption, decryption, signing, and verification happen locally in the SDK. Capsara's servers only ever store ciphertext and cannot read your files, your metadata, or your keys.

Private Key Security

Your private key is the sole point of access to every capsa encrypted for you. Capsara uses zero-knowledge encryption: your private key never leaves your environment, is never transmitted to Capsara's servers, and is never stored by Capsara. There is no recovery mechanism, no master backdoor, and no support override. If your private key is lost, every capsa encrypted for your party becomes permanently inaccessible. No one (not Capsara, not the sender, not an administrator) can recover your data without your private key.

You are fully responsible for your private key's lifecycle: generation, secure storage, and backup. Store it in a cloud key vault (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault), a hardware security module, or at minimum an encrypted secrets manager. Never store it in source code, configuration files, or logs. Back it up to a secondary secure location so that a single infrastructure failure does not result in permanent data loss.

The SDK provides a RotateKeyAsync() method that generates a new RSA-4096 key pair and registers the new public key with Capsara. New capsas sent to you will be encrypted with your new key. However, capsas are immutable once created and their keychain and encrypted contents never change. Existing capsas remain accessible only with the private key that was active when they were created. Keep prior private keys available for as long as you need access to capsas encrypted under them.

API Reference

Method Description
CapsaraClient.GenerateKeyPair() Generate an RSA-4096 key pair (static)
LoginAsync(credentials) Authenticate with email and password
LogoutAsync() Log out and clear cached data
SetPrivateKey(privateKey) Set the private key for signing and decryption
CreateCapsaBuilderAsync() Create a CapsaBuilder pre-loaded with server limits
SendCapsasAsync(builders) Encrypt and send one or more capsas
GetDecryptedCapsaAsync(capsaId) Fetch and decrypt a capsa
GetCapsaAsync(capsaId) Fetch a capsa without decryption
ListCapsasAsync(filters?) List capsas with optional filters
DeleteCapsaAsync(capsaId) Soft-delete a capsa
DownloadFileAsync(capsaId, fileId) Download and decrypt a file
GetAuditEntriesAsync(capsaId) Get audit trail entries
AddPublicKeyAsync(key, fp, reason?) Register a new public key
RotateKeyAsync() Generate and register a new key pair
GetKeyHistoryAsync() Get previous public keys
GetLimitsAsync() Get server-enforced limits
Dispose() Release resources (IDisposable)

License

Capsara SDK License. See LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.4 128 3/16/2026
1.0.3 112 2/27/2026
1.0.0 124 2/26/2026 1.0.0 is deprecated because it is no longer maintained.