@fulmenhq/tsfulmen 0.1.9 → 0.1.11

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/CHANGELOG.md CHANGED
@@ -9,6 +9,96 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Added
11
11
 
12
+ - **HTTP Server Metrics** (`@fulmenhq/tsfulmen/telemetry/http`) - Type-safe HTTP instrumentation with Crucible v0.2.18 taxonomy
13
+ - **Core Helpers**:
14
+ - `recordHttpRequest()` - Records all 5 HTTP metrics with automatic unit conversion (ms → seconds)
15
+ - `trackActiveRequest()` - Active requests gauge management with cleanup
16
+ - AppIdentity integration for automatic service label defaults
17
+ - **Framework Middleware**:
18
+ - `createHttpMetricsMiddleware()` - Express/Connect-compatible middleware
19
+ - `createFastifyMetricsPlugin()` - Fastify plugin with hooks
20
+ - `createBunMetricsHandler()` - Bun.serve fetch handler wrapper
21
+ - **Metrics Emitted** (Crucible v0.2.18):
22
+ - `http_requests_total` - Counter with method/route/status/service labels
23
+ - `http_request_duration_seconds` - Histogram with automatic ms → seconds conversion
24
+ - `http_request_size_bytes` - Optional request size histogram
25
+ - `http_response_size_bytes` - Optional response size histogram
26
+ - `http_active_requests` - Active requests gauge
27
+ - **Features**:
28
+ - Configurable route normalizers (prevents cardinality explosion)
29
+ - Optional body size tracking (performance-conscious, disabled by default)
30
+ - Custom method/status extractors for framework flexibility
31
+ - No unsafe TypeScript casts, full type safety
32
+ - **Documentation**:
33
+ - Comprehensive HTTP metrics guide with framework examples
34
+ - Troubleshooting section (6+ common issues with solutions)
35
+ - Production recommendations and best practices
36
+ - Framework integration notes (Express, Fastify, Bun, Node.js HTTP)
37
+ - **Test Coverage**: 40+ tests (100% coverage of helpers module)
38
+ - **Quality**: All tests passing, typecheck clean, lint clean
39
+
40
+ - **Logging Middleware & Secure Redaction** (`@fulmenhq/tsfulmen/logging`) - STRUCTURED profile middleware pipeline with secure-by-default redaction
41
+ - **Middleware Pipeline Support**:
42
+ - Middleware execution for STRUCTURED and ENTERPRISE profiles
43
+ - Child loggers inherit parent middleware chain and bindings
44
+ - Severity adjustment support (middleware can modify event severity)
45
+ - Middleware chain execution before Pino emission
46
+ - **Built-in Middleware**:
47
+ - `RedactSecretsMiddleware` - Enhanced with gofulmen-aligned patterns and field names
48
+ - `AddFieldsMiddleware` - Inject context fields into log events
49
+ - `TransformMiddleware` - Custom event transformations
50
+ - **Helper Function**:
51
+ - `createStructuredLoggerWithRedaction()` - Secure-by-default structured logger
52
+ - Default redaction patterns: SECRET\_*, *TOKEN*, *KEY\*, Base64 blobs, emails, credit cards
53
+ - Default field names (case-insensitive): password, token, apiKey, authorization, secret, cardNumber, cvv, ssn
54
+ - Customization options: customPatterns, customFields, useDefaultPatterns (opt-out)
55
+ - File output support with redaction enabled
56
+ - **Security Model**:
57
+ - Redaction enabled by default when using helper function
58
+ - Gofulmen-aligned patterns for cross-language consistency
59
+ - Case-insensitive field matching (O(1) lookup)
60
+ - Pattern scanning with 10KB threshold optimization
61
+ - **Performance**:
62
+ - Pattern scanning skips strings >10KB to avoid performance degradation
63
+ - Field-based redaction (O(1)) always applies
64
+ - Minimal middleware overhead (<5% for typical events)
65
+ - Pre-compiled regex patterns and lowercase field maps
66
+ - **Documentation**:
67
+ - Comprehensive logging README (789 lines) with 35+ code examples
68
+ - Main README Progressive Logging section with before/after examples
69
+ - API reference for all middleware types and helper functions
70
+ - Troubleshooting guide with 4 common scenarios
71
+ - Migration guide from simple to structured to secure logging
72
+ - **Test Coverage**: 12 new integration tests (121 total logging tests)
73
+ - **Quality**: All tests passing (1749 tests), typecheck clean, fully documented
74
+
75
+ ---
76
+
77
+ ## [0.1.10] - 2025-11-17
78
+
79
+ ### Fixed
80
+
81
+ - **Critical: Signal catalog loading in installed packages** - Fixed path resolution bug that prevented signals catalog from loading when package was installed via npm. The bundled code in `dist/foundry/index.js` was using incorrect relative paths (`../../../config` instead of `../../config`) due to tsup bundling behavior. Added runtime path detection to handle both development (source files) and production (bundled files) contexts.
82
+ - **Pre-publish verification** - Added `scripts/verify-local-install.ts` and `make verify-local-install` target to catch path resolution bugs before publishing. This script packs the package locally, installs it to a temp directory, and tests catalog loading in the installed context.
83
+
84
+ ### Added
85
+
86
+ - Runtime path detection in signals catalog loader (src/foundry/signals/catalog.ts:23-30)
87
+ - Pre-publish integration test (scripts/verify-local-install.ts)
88
+ - Makefile target `verify-local-install` for pre-publish verification
89
+
90
+ ### Changed
91
+
92
+ - Signals catalog path resolution now detects whether running from source (`src/`) or dist (`dist/`) and adjusts paths accordingly
93
+
94
+ ---
95
+
96
+ ## [0.1.9] - 2025-11-16 [DEPRECATED - Non-functional]
97
+
98
+ **⚠️ DO NOT USE**: This version has a critical bug where catalog loading fails in installed packages. Use v0.1.10 or later.
99
+
100
+ ### Added
101
+
12
102
  - **Fulpack Module** (`@fulmenhq/tsfulmen/fulpack`) - Security-first archive operations for TAR, TAR.GZ, ZIP, and GZIP formats
13
103
  - **Five Canonical Operations**:
14
104
  - `create()` - Create archives from files/directories with configurable compression
package/README.md CHANGED
@@ -9,19 +9,20 @@ TypeScript Fulmen helper library for enterprise-scale development.
9
9
  ## Status
10
10
 
11
11
  **Lifecycle Phase:** `alpha` (see [`LIFECYCLE_PHASE`](LIFECYCLE_PHASE))
12
- **Development Status:** v0.1.9 - Fulpack archives, pathfinder repository root discovery
13
- **Test Coverage:** 1638 tests passing (100% pass rate)
12
+ **Development Status:** 🚧 v0.1.11 - HTTP server metrics, logging middleware with secure redaction
13
+ **Test Coverage:** 1749 tests passing (100% pass rate)
14
14
 
15
- TSFulmen v0.1.9 adds security-first archive operations (fulpack) for TAR/TAR.GZ/ZIP/GZIP formats and repository root discovery (pathfinder) with boundary enforcement. See [TSFulmen Overview](docs/tsfulmen_overview.md) for roadmap.
15
+ TSFulmen v0.1.11 adds HTTP server metrics with Crucible v0.2.18 taxonomy (Express/Fastify/Bun middleware) and logging middleware pipeline with secure-by-default redaction (gofulmen-aligned patterns). See [TSFulmen Overview](docs/tsfulmen_overview.md) for roadmap.
16
16
 
17
17
  ## Features
18
18
 
19
19
  - ✅ **Error Handling** - Schema-backed FulmenError with severity levels (43 tests)
20
20
  - ✅ **Telemetry & Metrics** - Counter/gauge/histogram with OTLP export (85 tests)
21
21
  - ✅ **Telemetry Instrumentation** - Metrics in config, schema, crucible modules (24 tests)
22
+ - ✅ **HTTP Server Metrics** - Type-safe HTTP instrumentation with Express/Fastify/Bun middleware (40+ tests)
22
23
  - ✅ **FulHash** - Fast hashing with XXH3-128 and SHA-256, 22x faster small inputs (157 tests)
23
24
  - ✅ **Fulpack** - Archive operations (TAR, TAR.GZ, ZIP, GZIP) with security-first design (20 tests)
24
- - ✅ **Progressive Logging** - Policy enforcement with Pino profiles (83 tests)
25
+ - ✅ **Progressive Logging** - Policy enforcement with Pino profiles, middleware pipeline, secure redaction (121 tests)
25
26
  - ✅ **Crucible Shim** - Typed access to synced schemas, docs, and config defaults (96 tests)
26
27
  - ✅ **DocScribe** - Document processing with frontmatter parsing (50+ tests)
27
28
  - ✅ **Config Path API** - XDG-compliant configuration directory resolution (26 tests)
@@ -237,6 +238,131 @@ await metrics.flush({
237
238
  });
238
239
  ```
239
240
 
241
+ ### HTTP Server Metrics
242
+
243
+ Type-safe HTTP instrumentation with automatic route normalization and cardinality protection:
244
+
245
+ ```typescript
246
+ import {
247
+ recordHttpRequest,
248
+ trackActiveRequest,
249
+ createHttpMetricsMiddleware,
250
+ } from "@fulmenhq/tsfulmen/telemetry/http";
251
+
252
+ // Express middleware (automatic instrumentation)
253
+ app.use(
254
+ createHttpMetricsMiddleware({
255
+ serviceName: "api-server",
256
+ routeNormalizer: (req) => req.route?.path || normalizeRoute(req.path),
257
+ trackBodySizes: true, // Optional: track request/response sizes
258
+ }),
259
+ );
260
+
261
+ // Manual instrumentation
262
+ const start = performance.now();
263
+ const release = trackActiveRequest("api-server");
264
+ try {
265
+ await handleRequest();
266
+ recordHttpRequest({
267
+ method: "GET",
268
+ route: "/users/:id", // Pre-normalized route
269
+ status: 200,
270
+ durationMs: performance.now() - start,
271
+ requestBytes: 512,
272
+ responseBytes: 2048,
273
+ });
274
+ } finally {
275
+ release();
276
+ }
277
+ ```
278
+
279
+ **Metrics emitted** (Crucible v0.2.18 taxonomy):
280
+
281
+ - `http_requests_total` - Request counter with method/route/status/service labels
282
+ - `http_request_duration_seconds` - Duration histogram (auto-converts ms → seconds)
283
+ - `http_request_size_bytes` - Request size histogram (optional)
284
+ - `http_response_size_bytes` - Response size histogram (optional)
285
+ - `http_active_requests` - Active requests gauge
286
+
287
+ **⚠️ Critical**: Routes must be normalized to prevent cardinality explosion. Use `normalizeRoute()` or framework route templates. See [HTTP Metrics Guide](src/telemetry/http/README.md).
288
+
289
+ **Framework support**: Express, Fastify, Bun.serve, Node.js HTTP
290
+
291
+ ### Progressive Logging
292
+
293
+ TSFulmen provides profile-based logging from simple CLI tools to enterprise observability with secure redaction middleware.
294
+
295
+ ```typescript
296
+ import {
297
+ createSimpleLogger,
298
+ createStructuredLogger,
299
+ createStructuredLoggerWithRedaction,
300
+ } from "@fulmenhq/tsfulmen/logging";
301
+
302
+ // Simple: Human-readable for CLI tools
303
+ const cli = createSimpleLogger("mycli");
304
+ cli.info("Processing file", { path: "/data/input.csv" });
305
+
306
+ // Structured: JSON output for APIs
307
+ const api = createStructuredLogger("api-server");
308
+ api.info("Request processed", { requestId: "req-456", duration: 42 });
309
+
310
+ // Structured + Redaction: Secure by default
311
+ const secure = createStructuredLoggerWithRedaction("auth-service");
312
+ secure.info("User login", {
313
+ userId: "user-123",
314
+ email: "user@example.com", // ← Automatically redacted
315
+ password: "secret123", // ← Automatically redacted
316
+ apiKey: "sk_live_1234567890", // ← Automatically redacted
317
+ });
318
+ ```
319
+
320
+ **Output** (with redaction):
321
+
322
+ ```json
323
+ {
324
+ "severity": "INFO",
325
+ "timestamp": "2025-11-18T12:00:00.000Z",
326
+ "service": "auth-service",
327
+ "message": "User login",
328
+ "userId": "user-123",
329
+ "email": "[REDACTED]",
330
+ "password": "[REDACTED]",
331
+ "apiKey": "[REDACTED]"
332
+ }
333
+ ```
334
+
335
+ **Security Model**: `createStructuredLoggerWithRedaction()` enables redaction by default with gofulmen-aligned patterns for common secrets (passwords, tokens, API keys, emails, credit cards).
336
+
337
+ **Performance**: Pattern scanning automatically skips strings larger than 10KB to avoid performance impact on large payloads. Field-based redaction (O(1) lookup) always applies.
338
+
339
+ **Customization**:
340
+
341
+ ```typescript
342
+ // Add organization-specific patterns
343
+ const logger = createStructuredLoggerWithRedaction("api-server", {
344
+ customPatterns: [/INTERNAL_ID_\d+/g, /CUST_[A-Z0-9]{10}/g],
345
+ customFields: ["internalKey", "customerSecret"],
346
+ });
347
+
348
+ // Opt-out of defaults for full control
349
+ const customLogger = createStructuredLoggerWithRedaction("api-server", {
350
+ useDefaultPatterns: false,
351
+ customPatterns: [/MY_SECRET/g],
352
+ });
353
+ ```
354
+
355
+ **Child Loggers**: Child loggers inherit middleware and bindings from parent.
356
+
357
+ ```typescript
358
+ const parent = createStructuredLoggerWithRedaction("api-server");
359
+ const child = parent.child({ requestId: "req-789" });
360
+
361
+ child.info("Processing", { password: "secret" }); // ← Still redacted!
362
+ ```
363
+
364
+ See [Logging README](src/logging/README.md) for complete documentation including middleware, profiles, and policy enforcement.
365
+
240
366
  ### Config Path API
241
367
 
242
368
  ```typescript
@@ -8,63 +8,148 @@
8
8
  # WARNING: This is a SAMPLE file with anonymized/fake secrets for demonstration.
9
9
  # DO NOT commit real secrets to version control in plaintext.
10
10
  # Use encryption (fulsecrets encrypt) before committing production secrets.
11
- schema_version: v1.0.0
12
- # Example 1: Development Environment (Plaintext)
11
+ # Example 1: Minimal Development Environment (Plaintext)
13
12
  # Use case: Local development with non-sensitive test credentials
14
13
  # Policy: allow_plain_secrets = true (default)
15
-
14
+ schema_version: v1.0.0
15
+ env_prefix: APP_
16
16
  projects:
17
17
  - project_slug: myapp-dev
18
- env_prefix: APP_
19
- secrets:
20
- DATABASE_URL: postgres://localhost:5432/myapp_dev
21
- REDIS_URL: redis://localhost:6379/0
22
- API_KEY: dev_key_12345_not_real
23
- SECRET_TOKEN: dev_secret_abc_not_real
24
- LOG_LEVEL: debug
25
- - project_slug: myapp-test
26
- env_prefix: APP_
27
- secrets:
28
- DATABASE_URL: postgres://localhost:5432/myapp_test
29
- REDIS_URL: redis://localhost:6379/1
30
- API_KEY: test_key_67890_not_real
31
- SECRET_TOKEN: test_secret_xyz_not_real
32
- LOG_LEVEL: info
18
+ credentials:
19
+ DATABASE_URL:
20
+ type: password
21
+ value: postgres://localhost:5432/myapp_dev
22
+ REDIS_URL:
23
+ type: password
24
+ value: redis://localhost:6379/0
25
+ API_KEY:
26
+ type: api_key
27
+ value: dev_key_12345_not_real
28
+ SECRET_TOKEN:
29
+ type: token
30
+ value: dev_secret_abc_not_real
31
+ LOG_LEVEL:
32
+ type: password
33
+ value: debug
33
34
  policies:
34
35
  allow_plain_secrets: true # OK for development
35
36
 
36
- # Example 2: Multi-Project Configuration (Plaintext)
37
- # Use case: Monorepo with multiple services sharing some secrets
38
- # Pattern: Project slugs identify service + environment
37
+ # Example 2: Full-Featured Credentials with Metadata & Rotation
38
+ # Use case: Production secrets with lifecycle tracking and rotation policies
39
+ # Pattern: Rich credential objects with type, metadata, rotation
40
+ ---
41
+ schema_version: v1.0.0
42
+ description: |
43
+ Production secrets for MyApp platform
44
+ Contact: platform-team@example.com
45
+ Last updated: 2025-11-17
46
+ env_prefix: PROD_
47
+ projects:
48
+ - project_slug: backend_api
49
+ description: Backend API services
50
+ credentials:
51
+ STRIPE_API_KEY:
52
+ type: api_key
53
+ value: sk_live_abc123def456_not_real
54
+ description: Live Stripe API key for payment processing
55
+ metadata:
56
+ created: "2025-01-15T10:00:00Z"
57
+ expires: "2026-01-15T10:00:00Z"
58
+ purpose: payment-processing
59
+ tags:
60
+ - payment
61
+ - critical
62
+ - pci-scope
63
+ owner: payments-team
64
+ rotation:
65
+ interval: 90d
66
+ method: auto
67
+ DATABASE_PASSWORD:
68
+ type: password
69
+ value: super_secure_password_not_real
70
+ description: Primary PostgreSQL database password
71
+ metadata:
72
+ created: "2025-01-01T00:00:00Z"
73
+ expires: "2025-12-31T23:59:59Z"
74
+ purpose: primary-database
75
+ tags:
76
+ - database
77
+ - critical
78
+ owner: platform-team
79
+ rotation:
80
+ interval: 30d
81
+ method: manual
82
+ JWT_SECRET:
83
+ type: token
84
+ value: bearer_token_abc123_not_real
85
+ description: JWT signing secret for authentication
86
+ metadata:
87
+ purpose: authentication
88
+ tags:
89
+ - auth
90
+ - critical
91
+ REDIS_PASSWORD:
92
+ type: password
93
+ value: redis_password_xyz789_not_real
94
+ description: Redis cache password
95
+
96
+ # Example 3: Multi-Project with External References
97
+ # Use case: Monorepo with multiple services, some credentials from Vault
98
+ # Pattern: Mix of inline values and external references (vault://, aws-secrets://)
39
99
  ---
40
100
  schema_version: v1.0.0
41
101
  projects:
42
102
  - project_slug: api-staging
43
- secrets:
44
- DATABASE_URL: postgres://staging-db.internal:5432/api
45
- REDIS_URL: redis://staging-cache.internal:6379
46
- JWT_SECRET: staging_jwt_secret_abc123_not_real
47
- API_KEY: sk_staging_api_key_not_real
48
- SENTRY_DSN: https://fake@sentry.io/staging
103
+ credentials:
104
+ DATABASE_URL:
105
+ type: password
106
+ ref: vault://secrets/staging/db-url
107
+ description: Database URL from HashiCorp Vault
108
+ REDIS_URL:
109
+ type: password
110
+ value: redis://staging-cache.internal:6379
111
+ JWT_SECRET:
112
+ type: token
113
+ value: staging_jwt_secret_abc123_not_real
114
+ API_KEY:
115
+ type: api_key
116
+ value: sk_staging_api_key_not_real
117
+ SENTRY_DSN:
118
+ type: password
119
+ value: https://fake@sentry.io/staging
49
120
  - project_slug: worker-staging
50
- secrets:
51
- DATABASE_URL: postgres://staging-db.internal:5432/api # Shared DB
52
- QUEUE_URL: amqp://staging-queue.internal:5672
53
- WORKER_TOKEN: staging_worker_token_xyz789_not_real
54
- SENTRY_DSN: https://fake@sentry.io/staging
55
- - project_slug: frontend-staging
56
- env_prefix: VITE_ # Frontend framework convention
57
- secrets:
58
- API_URL: https://api-staging.example.com
59
- ANALYTICS_KEY: staging_analytics_key_not_real
60
- SENTRY_DSN: https://fake@sentry.io/staging
121
+ credentials:
122
+ DATABASE_URL:
123
+ type: password
124
+ ref: vault://secrets/staging/db-url # Shared reference
125
+ QUEUE_URL:
126
+ type: password
127
+ value: amqp://staging-queue.internal:5672
128
+ WORKER_TOKEN:
129
+ type: token
130
+ value: staging_worker_token_xyz789_not_real
131
+ SENTRY_DSN:
132
+ type: password
133
+ value: https://fake@sentry.io/staging
134
+ - project_slug: frontend_staging
135
+ env_prefix: VITE_ # Override global prefix for frontend
136
+ credentials:
137
+ API_URL:
138
+ type: password
139
+ value: https://api-staging.example.com
140
+ ANALYTICS_KEY:
141
+ type: api_key
142
+ value: staging_analytics_key_not_real
143
+ SENTRY_DSN:
144
+ type: password
145
+ value: https://fake@sentry.io/staging
61
146
 
62
- # Example 3: Production Environment (Encrypted - GPG)
147
+ # Example 4: Production Environment (Encrypted - GPG)
63
148
  # Use case: Production secrets encrypted with GPG for team access
64
149
  # Policy: allow_plain_secrets = false (enforce encryption)
65
150
  #
66
151
  # How to create:
67
- # 1. Create plaintext file with real secrets
152
+ # 1. Create plaintext file with real secrets (using credential objects)
68
153
  # 2. Run: fulsecrets encrypt secrets.yaml --gpg-key team@example.com
69
154
  # 3. Commit encrypted file to version control
70
155
  #
@@ -82,10 +167,18 @@ encryption:
82
167
  # When decrypted, it contains:
83
168
  # projects:
84
169
  # - project_slug: myapp-prod
85
- # secrets:
86
- # DATABASE_URL: postgres://prod-db.example.com:5432/myapp
87
- # API_KEY: sk_live_real_production_key
88
- # ...etc
170
+ # credentials:
171
+ # DATABASE_URL:
172
+ # type: password
173
+ # value: postgres://prod-db.example.com:5432/myapp
174
+ # API_KEY:
175
+ # type: api_key
176
+ # value: sk_live_real_production_key
177
+ # metadata:
178
+ # expires: "2026-01-01T00:00:00Z"
179
+ # rotation:
180
+ # interval: 90d
181
+ # method: auto
89
182
  ciphertext: |
90
183
  -----BEGIN PGP MESSAGE-----
91
184
 
@@ -95,7 +188,7 @@ ciphertext: |
95
188
  policies:
96
189
  allow_plain_secrets: false # Enforce encryption for production
97
190
 
98
- # Example 4: Production Environment (Encrypted - age)
191
+ # Example 5: Production Environment (Encrypted - age)
99
192
  # Use case: Modern encryption with age instead of GPG
100
193
  # Pattern: Same as GPG but using age public/private key pairs
101
194
  #
@@ -120,7 +213,7 @@ ciphertext: |
120
213
  policies:
121
214
  allow_plain_secrets: false
122
215
 
123
- # Example 5: Passphrase-Based Encryption (Simplest)
216
+ # Example 6: Passphrase-Based Encryption (Simplest)
124
217
  # Use case: Solo developer or small team with shared passphrase
125
218
  # Pattern: No key management needed, just a strong passphrase
126
219
  #
@@ -151,44 +244,70 @@ policies:
151
244
 
152
245
  # Best Practices & Security Notes:
153
246
  #
154
- # 1. NEVER commit plaintext production secrets to version control
247
+ # 1. Credential Types:
248
+ # - api_key: External service keys (Stripe, GitHub, AWS) - masked as "sk_live_...xyz"
249
+ # - token: Auth tokens, JWTs, bearer tokens - masked as "...1234"
250
+ # - password: Passwords, passphrases, DB URLs - fully redacted "***REDACTED***"
251
+ #
252
+ # 2. Value vs Ref:
253
+ # - Use 'value' for inline secrets (development, small deployments)
254
+ # - Use 'ref' for external secret managers (Vault, AWS Secrets Manager)
255
+ # - Never include both 'value' and 'ref' (mutually exclusive)
256
+ #
257
+ # 3. Metadata & Rotation:
258
+ # - Add 'metadata.expires' for time-based rotation tracking
259
+ # - Use 'rotation.interval' to document rotation policy (30d, 90d, 180d)
260
+ # - Set 'rotation.method: auto' for automated rotation, 'manual' otherwise
261
+ # - Tag critical credentials with 'tags: [critical]' for monitoring
262
+ #
263
+ # 4. NEVER commit plaintext production secrets to version control:
155
264
  # - Always encrypt production files before git add
156
265
  # - Use .gitignore for *-plain.yaml, *-decrypted.yaml patterns
266
+ # - Run 'git secrets --scan' or similar tools to prevent leaks
157
267
  #
158
- # 2. Policy enforcement:
268
+ # 5. Policy enforcement:
159
269
  # - Set allow_plain_secrets: false for staging/production
160
270
  # - Keep allow_plain_secrets: true for local development
161
271
  # - Use fulsecrets validate --strict to catch violations
162
272
  #
163
- # 3. Key management:
273
+ # 6. Key management:
164
274
  # - GPG: Good for teams with existing GPG infrastructure
165
275
  # - Age: Modern alternative, simpler key management
166
276
  # - Passphrase: Simplest for solo dev, store in password manager
167
277
  #
168
- # 4. CI/CD integration:
278
+ # 7. CI/CD integration:
169
279
  # - Store passphrases/keys in GitHub Secrets / GitLab CI Variables
170
280
  # - Use environment variables (FULSECRETS_PASSPHRASE) to avoid prompts
171
281
  # - Never echo/print secrets in CI logs
172
282
  #
173
- # 5. Secret rotation:
174
- # - Update secrets in plaintext, re-encrypt with same method
283
+ # 8. Secret rotation workflow:
284
+ # - Decrypt existing file: fulsecrets decrypt secrets.yaml
285
+ # - Update credential values and metadata.expires timestamps
286
+ # - Re-encrypt with same method: fulsecrets encrypt secrets.yaml
175
287
  # - For key rotation: decrypt, re-encrypt with new key
176
- # - Update encryption.encrypted_at to track rotation
177
288
  #
178
- # 6. Temporary files:
289
+ # 9. Temporary files:
179
290
  # - fulsecrets edit uses secure temp files (/dev/shm, 0600 perms)
180
291
  # - Manual workflow: always rm plaintext files after encryption
181
292
  # - Use shred/srm for sensitive cleanup if available
182
293
  #
183
- # 7. Environment variable naming:
184
- # - Use UPPER_SNAKE_CASE for secret keys
185
- # - Add env_prefix for namespacing (APP_, SERVICE_, etc.)
186
- # - Avoid generic names like "KEY" or "TOKEN" (use API_KEY, JWT_TOKEN)
294
+ # 10. Environment variable naming:
295
+ # - Use UPPER_SNAKE_CASE for credential keys
296
+ # - Add env_prefix for namespacing (APP_, SERVICE_, PROD_, etc.)
297
+ # - Avoid generic names like "KEY" or "TOKEN" (use API_KEY, JWT_TOKEN)
298
+ # - Global env_prefix applies to all projects, can override per-project
299
+ #
300
+ # 11. Project slugs:
301
+ # - Use lowercase alphanumeric + hyphens/underscores
302
+ # - Pattern: service-environment (api-staging, worker-prod)
303
+ # - Or: service_version-env (api_v2-staging, backend_legacy-prod)
304
+ # - Examples: backend-api, frontend_app, worker-staging, my_service-v2
187
305
  #
188
- # 8. Compliance / FIPS mode:
189
- # - Set allow_plain_secrets: false for compliance
190
- # - Use GPG with FIPS 140-2 validated crypto if required
191
- # - Document encryption method in security policy
306
+ # 12. Compliance / FIPS mode:
307
+ # - Set allow_plain_secrets: false for compliance
308
+ # - Use GPG with FIPS 140-2 validated crypto if required
309
+ # - Document encryption method in security policy
310
+ # - Track rotation with metadata.expires and rotation.interval
192
311
  #
193
312
  # Schema Documentation:
194
313
  # https://github.com/fulmenhq/crucible/blob/main/docs/standards/devsecops/project-secrets.md
@@ -44,6 +44,11 @@ $defs:
44
44
  - fulhash_hash_string_total
45
45
  - fulhash_bytes_hashed_total
46
46
  - fulhash_operation_ms
47
+ - http_requests_total
48
+ - http_request_duration_seconds
49
+ - http_request_size_bytes
50
+ - http_response_size_bytes
51
+ - http_active_requests
47
52
  metricUnit:
48
53
  type: string
49
54
  enum:
@@ -70,6 +75,16 @@ properties:
70
75
  description: Default millisecond buckets used when metric name ends with `_ms`.
71
76
  items:
72
77
  type: number
78
+ seconds_metrics:
79
+ type: array
80
+ description: Default second buckets used when metric unit is `s` (for HTTP latency and duration metrics).
81
+ items:
82
+ type: number
83
+ bytes_metrics:
84
+ type: array
85
+ description: Default byte buckets used when metric name ends with `_bytes` (for HTTP request/response size metrics).
86
+ items:
87
+ type: number
73
88
  additionalProperties: false
74
89
  additionalProperties: false
75
90
  metrics:
@@ -93,7 +108,7 @@ required:
93
108
  - version
94
109
  - metrics
95
110
  additionalProperties: false
96
- version: "0.2.15"
111
+ version: "0.2.18"
97
112
  defaults:
98
113
  histogram_buckets:
99
114
  ms_metrics:
@@ -106,6 +121,25 @@ defaults:
106
121
  - 1000
107
122
  - 5000
108
123
  - 10000
124
+ seconds_metrics:
125
+ - 0.005
126
+ - 0.01
127
+ - 0.025
128
+ - 0.05
129
+ - 0.1
130
+ - 0.25
131
+ - 0.5
132
+ - 1
133
+ - 2.5
134
+ - 5
135
+ - 10
136
+ bytes_metrics:
137
+ - 1024
138
+ - 10240
139
+ - 102400
140
+ - 1048576
141
+ - 10485760
142
+ - 104857600
109
143
  metrics:
110
144
  - name: schema_validations
111
145
  unit: count
@@ -269,3 +303,28 @@ metrics:
269
303
  unit: ms
270
304
  description: >
271
305
  Hash operation latency in milliseconds for all algorithms. Uses ADR-0007 buckets: [1, 5, 10, 50, 100, 500, 1000, 5000, 10000]. Enables performance benchmarking across XXH3-128 and SHA256.
306
+
307
+ - name: http_requests_total
308
+ unit: count
309
+ description: >
310
+ Total HTTP server requests received. Counter metric tracking all HTTP requests by method, route, status, and service. Required labels: method (GET/POST/etc), route (templated path like /users/:id to avoid cardinality), status (HTTP status code), service (service identifier). Optional labels: outcome (2xx/4xx/5xx grouping derived from status). IMPORTANT: Use normalized/templated routes (e.g., /users/:id, not /users/123) to prevent cardinality explosion. Helpers SHOULD provide route normalization utilities.
311
+
312
+ - name: http_request_duration_seconds
313
+ unit: s
314
+ description: >
315
+ HTTP server request duration in seconds. Histogram metric measuring request latency from receipt to response. Uses default seconds buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]. Required labels: method, route (templated), status, service. Optional labels: outcome. Helpers exposing millisecond APIs MUST document unit conversion (1 second = 1000 ms). Use templated routes to control cardinality.
316
+
317
+ - name: http_request_size_bytes
318
+ unit: bytes
319
+ description: >
320
+ HTTP server request body size in bytes. Histogram metric measuring incoming request payload sizes. Uses default bytes buckets: [1024, 10240, 102400, 1048576, 10485760, 104857600] (1KB to 100MB). Required labels: method, route (templated), service. Enables monitoring payload patterns and capacity planning. Use templated routes to avoid cardinality issues.
321
+
322
+ - name: http_response_size_bytes
323
+ unit: bytes
324
+ description: >
325
+ HTTP server response body size in bytes. Histogram metric measuring outgoing response payload sizes. Uses default bytes buckets: [1024, 10240, 102400, 1048576, 10485760, 104857600] (1KB to 100MB). Required labels: method, route (templated), status, service. Optional labels: outcome. Tracks bandwidth usage and response patterns. Use templated routes to prevent cardinality explosion.
326
+
327
+ - name: http_active_requests
328
+ unit: count
329
+ description: >
330
+ Number of HTTP requests currently being processed. Gauge metric tracking concurrent request load. Required labels: service. Intentionally minimal labels to avoid cardinality. Helps monitor server capacity and saturation. Increment on request start, decrement on completion.