@capsara/sdk 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# Capsara SDK
|
|
1
|
+
# Capsara SDK - TypeScript
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
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.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **AES-256-GCM** encryption with unique keys per capsa
|
|
8
8
|
- **RSA-4096-OAEP** key encryption for multi-party access
|
|
9
|
-
- **Compression**
|
|
10
|
-
- **Digital signatures**
|
|
9
|
+
- **Compression** with gzip before encryption
|
|
10
|
+
- **Digital signatures** using RSA-SHA256 for sender authenticity
|
|
11
11
|
- **Encrypted subject, body, and structured data**
|
|
12
12
|
- **Batch sending** with automatic chunking
|
|
13
13
|
|
|
@@ -43,7 +43,7 @@ await client.login({
|
|
|
43
43
|
After logging in, set your private key for signing and decryption. Generate and register your keypair using `generateKeyPair()` and `addPublicKey()`, then store the private key securely.
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
//
|
|
46
|
+
// Your code to load the private key from secure storage (key vault, HSM, etc.)
|
|
47
47
|
const privateKey = loadPrivateKeyFromSecureStorage();
|
|
48
48
|
|
|
49
49
|
client.setPrivateKey(privateKey);
|
|
@@ -51,7 +51,7 @@ client.setPrivateKey(privateKey);
|
|
|
51
51
|
|
|
52
52
|
## Sending Capsas
|
|
53
53
|
|
|
54
|
-
Use the `CapsaBuilder` to create capsas with recipients and files. Always use `sendCapsas()` even for a single capsa
|
|
54
|
+
Use the `CapsaBuilder` to create capsas with recipients and files. Always use `sendCapsas()` even for a single capsa since it handles encryption and batching efficiently.
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
57
|
import { CapsaraClient, CapsaraError, FileInput } from '@capsara/sdk';
|
|
@@ -60,7 +60,7 @@ try {
|
|
|
60
60
|
// Create a builder for each capsa you want to send
|
|
61
61
|
const builder = await client.createCapsaBuilder();
|
|
62
62
|
|
|
63
|
-
// Add recipients
|
|
63
|
+
// Add recipients (can add multiple)
|
|
64
64
|
builder.addRecipient('party_recipient1');
|
|
65
65
|
builder.addRecipient('party_recipient2');
|
|
66
66
|
|
|
@@ -72,7 +72,7 @@ try {
|
|
|
72
72
|
));
|
|
73
73
|
|
|
74
74
|
// Add optional metadata
|
|
75
|
-
builder.withSubject('Policy Documents
|
|
75
|
+
builder.withSubject('Policy Documents - Q1 2025');
|
|
76
76
|
builder.withBody('Please review the attached policy documents.');
|
|
77
77
|
builder.withStructured({
|
|
78
78
|
policyNumber: 'POL-12345',
|
|
@@ -96,19 +96,19 @@ try {
|
|
|
96
96
|
}
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
A **capsa** maps one-to-one with a *matter
|
|
99
|
+
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:
|
|
100
100
|
|
|
101
101
|
```typescript
|
|
102
102
|
const matter1 = await client.createCapsaBuilder();
|
|
103
103
|
matter1
|
|
104
104
|
.addRecipient('party_org_b')
|
|
105
|
-
.withSubject('Client 1
|
|
105
|
+
.withSubject('Client 1 - New Home Policy')
|
|
106
106
|
.addFile(FileInput.fromPath('./policy.pdf'));
|
|
107
107
|
|
|
108
108
|
const matter2 = await client.createCapsaBuilder();
|
|
109
109
|
matter2
|
|
110
110
|
.addRecipient('party_org_b')
|
|
111
|
-
.withSubject('Client 1
|
|
111
|
+
.withSubject('Client 1 - Auto Endorsement')
|
|
112
112
|
.withBody('Endorsement effective 3/1. No documents required.');
|
|
113
113
|
|
|
114
114
|
await client.sendCapsas([matter1, matter2]);
|
|
@@ -147,7 +147,7 @@ if (response.pagination.hasMore) {
|
|
|
147
147
|
```typescript
|
|
148
148
|
import fs from 'node:fs';
|
|
149
149
|
|
|
150
|
-
const capsa = await client.getCapsa('
|
|
150
|
+
const capsa = await client.getCapsa('capsa_abc-123');
|
|
151
151
|
|
|
152
152
|
console.log('Subject:', capsa.subject);
|
|
153
153
|
console.log('Body:', capsa.body);
|
|
@@ -162,7 +162,7 @@ for (const file of capsa.files) {
|
|
|
162
162
|
|
|
163
163
|
## Delegation
|
|
164
164
|
|
|
165
|
-
Capsara supports delegation for scenarios where a system acts on behalf of a party
|
|
165
|
+
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.
|
|
166
166
|
|
|
167
167
|
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.
|
|
168
168
|
|
|
@@ -172,7 +172,7 @@ const client = new CapsaraClient('https://api.capsara.com');
|
|
|
172
172
|
await client.login({ email: 'ams@example.com', password: '...' });
|
|
173
173
|
client.setPrivateKey(loadPrivateKeyFromSecureStorage());
|
|
174
174
|
|
|
175
|
-
// List capsas
|
|
175
|
+
// List capsas (includes capsas for all parties you represent)
|
|
176
176
|
const response = await client.listCapsas();
|
|
177
177
|
|
|
178
178
|
for (const summary of response.capsas) {
|
|
@@ -194,15 +194,15 @@ for (const summary of response.capsas) {
|
|
|
194
194
|
|
|
195
195
|
## Encryption
|
|
196
196
|
|
|
197
|
-
Every capsa is protected by a unique AES-256-GCM symmetric key (the "master key") generated at send time. Files and metadata
|
|
197
|
+
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.
|
|
198
198
|
|
|
199
199
|
## Private Key Security
|
|
200
200
|
|
|
201
|
-
Your private key is the sole point of access to every capsa encrypted for you. Capsara uses zero-knowledge encryption
|
|
201
|
+
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.
|
|
202
202
|
|
|
203
|
-
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
|
|
203
|
+
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.
|
|
204
204
|
|
|
205
|
-
The SDK provides a `rotateKey()` 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
|
|
205
|
+
The SDK provides a `rotateKey()` 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.
|
|
206
206
|
|
|
207
207
|
## API Reference
|
|
208
208
|
|
|
@@ -227,4 +227,4 @@ The SDK provides a `rotateKey()` method that generates a new RSA-4096 key pair a
|
|
|
227
227
|
|
|
228
228
|
## License
|
|
229
229
|
|
|
230
|
-
Capsara SDK License
|
|
230
|
+
Capsara SDK License. See [LICENSE](./LICENSE) for details.
|