typesecure 0.1.0 → 0.2.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 CHANGED
@@ -1,21 +1,34 @@
1
1
  # typesecure
2
2
 
3
- A focused TypeScript cryptography package that provides secure encryption and hashing utilities with strong typing and runtime validation using Zod.
3
+ `typesecure` is a **classification-first security core** for TypeScript projects.
4
+
5
+ Instead of starting with crypto primitives, it starts with what actually causes most security incidents in web apps: **data leaving the boundary it should never cross** (logs, analytics, error trackers, headers, client bundles, etc).
6
+
7
+ You “type” your data as `public | pii | secret | token | credential`, and `typesecure` helps you **enforce** safe handling using TypeScript + runtime checks.
4
8
 
5
9
  ## Features
6
10
 
7
- - 🔐 **Strong Typing**: Built with TypeScript for complete type safety.
8
- - **Runtime Validation**: Uses Zod to validate inputs and ensure security.
9
- - 🔍 **Advanced Encryption**: AES encryption with multiple modes (CBC, CTR, GCM, ECB).
10
- - 🛡️ **Authenticated Encryption**: GCM mode for authenticated encryption with additional data (AAD).
11
- - 🔏 **Cryptographic Hashing**: SHA-256, SHA-512, SHA-3, and more.
12
- - 📝 **HMAC Signatures**: Create and verify message authentication codes.
13
- - ⏱️ **Timing-Safe Comparison**: Prevent timing attacks with constant-time string comparison.
14
- - 🚦 **Security Level Assessment**: Analyze and report the security level of encryption configurations.
15
- - 🔑 **Password Hashing**: PBKDF2 for secure password hashing with salt and configurable iterations.
11
+ - **Classification types**: `PublicString`, `PIIString`, `SecretString`, `TokenString`, `CredentialString`.
12
+ - **Runtime validation**: Zod-backed constructors (`secretText()`, `piiText()`, ...).
13
+ - **Redaction**: `redact()` and `safeJsonStringify()` prevent secret/PII leakage.
14
+ - **Policy enforcement**: `defaultPolicy()`, `assertAllowed()`, `audit()` help block unsafe crossings.
15
+
16
+ ## Good for / Use when
17
+
18
+ - **You need to stop leaks early**: preventing secrets/PII from ending up in logs, analytics, error trackers, or client bundles.
19
+ - **You want safe defaults**: making insecure behavior harder than secure behavior.
20
+ - **You want guardrails at the boundary**: before logging, emitting telemetry, making network calls, or writing to storage.
21
+
22
+ ## Not a fit / Don’t use when
23
+
24
+ - **You need a full security platform** (hosted policy registry, enterprise controls). `typesecure` is a library.
25
+ - **You need production-grade crypto primitives**. Use well-reviewed, purpose-built libraries and treat crypto carefully.
26
+ - **You only want compile-time types with zero runtime behavior**. `typesecure` deliberately includes runtime checks/redaction.
16
27
 
17
28
  ## Installation
18
29
 
30
+ Requires Node.js `>=18.18.0`.
31
+
19
32
  ```bash
20
33
  # Using npm
21
34
  npm install typesecure
@@ -29,113 +42,125 @@ pnpm add typesecure
29
42
 
30
43
  ## Usage
31
44
 
32
- ### Encryption with Security Assessment
45
+ ### Classification-first data handling
33
46
 
34
47
  ```typescript
35
- import { encrypt, decrypt, generateKey, getSecurityLevel, SecurityLevel } from 'typesecure';
36
-
37
- // Generate a secure key
38
- const key = generateKey();
39
-
40
- // Encrypt data with GCM (authenticated encryption)
41
- const encrypted = encrypt('Sensitive information', key, {
42
- mode: 'aes-gcm',
43
- aad: 'Additional authenticated data' // Optional
44
- });
45
-
46
- // Decrypt data
47
- const decrypted = decrypt(encrypted, key, {
48
- mode: 'aes-gcm',
49
- aad: 'Additional authenticated data' // Must match encryption
50
- });
51
-
52
- // Assess security level of encryption options
53
- const securityLevel = getSecurityLevel({ mode: 'aes-cbc', padding: 'Pkcs7' });
54
- if (securityLevel === SecurityLevel.HIGH) {
55
- console.log('Using high security encryption configuration');
56
- }
48
+ import {
49
+ piiText,
50
+ secretText,
51
+ token,
52
+ publicText,
53
+ redact,
54
+ safeJsonStringify,
55
+ defaultPolicy,
56
+ assertAllowed,
57
+ policyLog,
58
+ } from "typesecure";
59
+
60
+ const userEmail = piiText("user@example.com");
61
+ const sessionToken = token("abc.def.ghi");
62
+ const dbPassword = secretText(process.env.DB_PASSWORD ?? "");
63
+
64
+ // Redact before logging / serialization
65
+ console.log(redact({ userEmail, sessionToken, dbPassword }));
66
+ console.log(
67
+ safeJsonStringify({ userEmail, sessionToken, dbPassword }, undefined, 2),
68
+ );
69
+
70
+ // Enforce policy before a boundary crossing
71
+ const policy = defaultPolicy();
72
+ assertAllowed(policy, "network", { sessionToken }); // allowed
73
+ // assertAllowed(policy, 'log', { dbPassword }); // throws
74
+
75
+ // Safe logging helper with enforcement
76
+ policyLog(policy, console, "info", publicText("login_ok"), { userEmail });
57
77
  ```
58
78
 
59
- ### Secure Password Storage
79
+ ### Express / Next.js examples
60
80
 
61
81
  ```typescript
62
- import { hashPassword, verifyPassword } from 'typesecure';
63
-
64
- // Hash a password with PBKDF2
65
- const { hash, salt, params } = hashPassword('userPassword123', {
66
- algorithm: 'pbkdf2',
67
- iterations: 10000,
68
- saltLength: 32,
69
- keyLength: 64
82
+ // Express middleware example
83
+ import {
84
+ safeLoggerAdapter,
85
+ defaultPolicy,
86
+ assertAllowed,
87
+ token,
88
+ } from "typesecure";
89
+
90
+ const log = safeLoggerAdapter(console);
91
+ const policy = defaultPolicy();
92
+
93
+ app.use((req, _res, next) => {
94
+ const auth = req.headers.authorization?.replace(/^Bearer\s+/i, "");
95
+ if (auth) {
96
+ const t = token(auth);
97
+ assertAllowed(policy, "network", { t });
98
+ log.info({ route: req.path, auth: t }); // will be redacted
99
+ }
100
+ next();
70
101
  });
71
-
72
- // Store hash, salt, and params in your database
73
-
74
- // Later, verify the password
75
- const isValid = verifyPassword('userPassword123', hash, salt, params);
76
102
  ```
77
103
 
78
- ### Timing-Safe Comparison and Random Bytes Generation
79
-
80
- ```typescript
81
- import { timingSafeEqual, generateRandomBytes } from 'typesecure';
82
-
83
- // Compare strings in constant time to prevent timing attacks
84
- const isEqual = timingSafeEqual(userProvidedToken, storedToken);
85
-
86
- // Generate cryptographically secure random bytes
87
- const randomBytes = generateRandomBytes(32, 'hex');
88
- ```
104
+ ## API Reference
89
105
 
90
- ### Hashing and HMAC
106
+ ### Classification
107
+
108
+ - `publicText(value: string): PublicString`
109
+ - `piiText(value: string): PIIString`
110
+ - `secretText(value: string): SecretString`
111
+ - `token(value: string): TokenString`
112
+ - `credential(value: string): CredentialString`
113
+ - `reveal(value): string` (intentionally explicit)
114
+
115
+ ### Redaction
116
+
117
+ - `redact(value): value` (deep traversal)
118
+ - `redactText(value): string` (mask sensitive fragments in plain text)
119
+ - `detectText(value): StringDetection[]` (return ranges/kinds for audit workflows)
120
+ - `safeJsonStringify(value): string`
121
+ - `safeLoggerAdapter(consoleLike)`
122
+ - Redaction options:
123
+ - `guessByKey` (default `true`): redact suspicious keys like `password`, `token`, `apiKey`.
124
+ - `guessByValue` (default `true`): auto-detect and redact sensitive-looking values.
125
+ - `useDefaultValueDetector` (default `true`): keep built-in rule-based detectors on/off.
126
+ - `stringDetectors`: add custom detectors (for NER/ML or domain-specific logic).
127
+ - `minDetectionConfidence` (default `0`): ignore low-confidence custom detections.
128
+ - Value detection masks only the sensitive fragments inside a larger string (instead of replacing the whole text), including:
129
+ - PII: email, phone, SSN, date of birth (`YYYY-MM-DD`), IPv4 address, payment card numbers (Luhn-validated).
130
+ - Secrets/tokens: JWTs, private key PEM blocks, GitHub tokens, AWS access keys, Stripe secret keys, OpenAI-style `sk-...` keys, credential pairs (`user:pass`), high-entropy token-like strings.
131
+
132
+ Example custom detector (NER/ML-style integration):
91
133
 
92
134
  ```typescript
93
- import { hash, verifyHash, hmac } from 'typesecure';
94
-
95
- // Create a hash
96
- const hashedValue = hash('data to hash', {
97
- algorithm: 'sha256',
98
- encoding: 'hex'
99
- });
100
-
101
- // Verify a hash
102
- const isMatch = verifyHash('data to hash', hashedValue, {
103
- algorithm: 'sha256',
104
- encoding: 'hex'
105
- });
106
-
107
- // Create an HMAC
108
- const signature = hmac('message', 'secret key', {
109
- algorithm: 'sha256',
110
- encoding: 'base64'
111
- });
135
+ const out = redact(
136
+ { text: "Customer Jane Doe uses jane@example.com" },
137
+ {
138
+ stringDetectors: [
139
+ (value) => {
140
+ const name = "Jane Doe";
141
+ const idx = value.indexOf(name);
142
+ return idx >= 0
143
+ ? [{ start: idx, end: idx + name.length, kind: "pii", confidence: 0.92, source: "ml.ner" }]
144
+ : [];
145
+ },
146
+ ],
147
+ minDetectionConfidence: 0.8,
148
+ },
149
+ );
112
150
  ```
113
151
 
114
- ## API Reference
115
-
116
- ### Encryption
117
-
118
- - `encrypt(text: string, key: string, options?: Partial<EncryptionOptions>): string`
119
- - `decrypt(encryptedText: string, key: string, options?: Partial<EncryptionOptions>): string`
120
- - `generateKey(length?: number): string`
121
- - `getSecurityLevel(options: EncryptionOptions): SecurityLevel`
122
-
123
- ### Secure Password Storage
152
+ ### Policy
124
153
 
125
- - `hashPassword(password: string, options?: Partial<PasswordHashOptions>): { hash: string; salt: string; params: PasswordHashOptions }`
126
- - `verifyPassword(password: string, hash: string, salt: string, options?: Partial<PasswordHashOptions>): boolean`
127
- - `timingSafeEqual(a: string, b: string, options?: Partial<TimingSafeOptions>): boolean`
128
- - `generateRandomBytes(length?: number, encoding?: 'hex' | 'base64'): string`
129
-
130
- ### Hashing
131
-
132
- - `hash(input: string, options?: Partial<HashOptions>): string`
133
- - `verifyHash(input: string, hashedValue: string, options?: Partial<HashOptions>): boolean`
134
- - `hmac(input: string, key: string, options?: Partial<HashOptions>): string`
154
+ - `defaultPolicy(): Policy`
155
+ - `assertAllowed(policy, action, data): void`
156
+ - `audit(policy, action, data): AuditEvent`
157
+ - `policyLog(policy, logger, level, ...args): void`
135
158
 
136
159
  ## Security Considerations
137
160
 
138
- This package implements best practices for cryptographic operations, but remember that cryptography is complex. For production applications with high security requirements, consider:
161
+ Security is as much about **preventing leaks** as it is about cryptographic correctness. `typesecure` focuses on preventing accidental secret/PII exposure across common boundaries.
162
+
163
+ If you need cryptography for production-grade requirements, prefer well-reviewed primitives and consult a security professional. For production applications with high security requirements, consider:
139
164
 
140
165
  1. Consulting a security professional
141
166
  2. Using specialized security libraries
@@ -153,13 +178,51 @@ To contribute to this project:
153
178
  2. Install dependencies with `pnpm install`
154
179
  3. Run tests with `pnpm test`
155
180
  4. Build the package with `pnpm build`
181
+ 5. Run Enron dataset integration tests with `pnpm test:data`
182
+
183
+ ### Optional: external dataset setup
184
+
185
+ For larger redaction/policy experiments (Enron + Synthea FHIR), fetch datasets locally:
186
+
187
+ ```bash
188
+ pnpm data:setup
189
+ ```
190
+
191
+ This command downloads and extracts to:
192
+
193
+ - `data/enron-maildir`
194
+ - `data/synthea_sample_data_fhir_latest`
195
+
196
+ Notes:
197
+
198
+ - `data/` is gitignored and not published to npm.
199
+ - `pnpm test` excludes dataset suites by default.
200
+ - `pnpm test:data` runs Enron dataset tests with verbose output.
201
+ - `pnpm test:data:synthea` runs Synthea-specific dataset tests.
202
+ - `pnpm test:data:all` runs all dataset suites.
203
+ - You can override source URLs with `ENRON_URL=...` and/or `SYNTHEA_FHIR_URL=...`.
204
+ - You can change destination with `DATA_DIR=/path/to/data`.
205
+
206
+ Dataset sources:
207
+
208
+ - Enron: [https://www.cs.cmu.edu/~enron/](https://www.cs.cmu.edu/~enron/)
209
+ - Synthea: [https://github.com/synthetichealth/synthea-sample-data/](https://github.com/synthetichealth/synthea-sample-data/)
156
210
 
157
211
  This project uses TypeScript for type safety, Jest for testing, and ESLint for code quality.
158
212
 
213
+ ## Dataset Acknowledgements
214
+
215
+ We use these public datasets for redaction and policy testing:
216
+
217
+ - [CMU Enron Email Dataset](https://www.cs.cmu.edu/~enron/)
218
+ - [Synthea Sample Data](https://github.com/synthetichealth/synthea-sample-data/)
219
+
220
+ Personal note: I am especially interested in the historical context around Enron, including how it was able to happen and the improvements in governance and controls that followed.
221
+
159
222
  ## License
160
223
 
161
224
  MIT © [Arvid Berndtsson](https://github.com/arvid-berndtsson)
162
225
 
163
226
  ## Contributing
164
227
 
165
- Contributions are welcome! Please feel free to submit a Pull Request.
228
+ Contributions are welcome! Please feel free to submit a Pull Request.