@agentlensai/server 0.11.0 → 0.14.0
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/LICENSE +21 -0
- package/dist/app.d.ts +27 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +178 -0
- package/dist/app.js.map +1 -0
- package/dist/cloud/auth/rbac.d.ts +1 -1
- package/dist/cloud/auth/rbac.d.ts.map +1 -1
- package/dist/cloud/auth/rbac.js +2 -2
- package/dist/cloud/auth/rbac.js.map +1 -1
- package/dist/cloud/billing/stripe-client.d.ts.map +1 -1
- package/dist/cloud/billing/stripe-client.js +6 -1
- package/dist/cloud/billing/stripe-client.js.map +1 -1
- package/dist/cloud/ingestion/gateway.d.ts.map +1 -1
- package/dist/cloud/ingestion/gateway.js +0 -1
- package/dist/cloud/ingestion/gateway.js.map +1 -1
- package/dist/cloud/middleware/validate-org-access.d.ts +14 -0
- package/dist/cloud/middleware/validate-org-access.d.ts.map +1 -0
- package/dist/cloud/middleware/validate-org-access.js +38 -0
- package/dist/cloud/middleware/validate-org-access.js.map +1 -0
- package/dist/cloud/routes/index.d.ts +13 -0
- package/dist/cloud/routes/index.d.ts.map +1 -0
- package/dist/cloud/routes/index.js +98 -0
- package/dist/cloud/routes/index.js.map +1 -0
- package/dist/config.d.ts +29 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +74 -1
- package/dist/config.js.map +1 -1
- package/dist/db/api-key-lookup.d.ts +25 -0
- package/dist/db/api-key-lookup.d.ts.map +1 -0
- package/dist/db/api-key-lookup.js +38 -0
- package/dist/db/api-key-lookup.js.map +1 -0
- package/dist/db/connection.postgres.d.ts +44 -0
- package/dist/db/connection.postgres.d.ts.map +1 -0
- package/dist/db/connection.postgres.js +79 -0
- package/dist/db/connection.postgres.js.map +1 -0
- package/dist/db/cost-budget-store.d.ts +30 -0
- package/dist/db/cost-budget-store.d.ts.map +1 -0
- package/dist/db/cost-budget-store.js +201 -0
- package/dist/db/cost-budget-store.js.map +1 -0
- package/dist/db/drizzle/0000_initial.sql +336 -0
- package/dist/db/drizzle/0001_indexes.sql +20 -0
- package/dist/db/drizzle/0002_pgvector.sql +19 -0
- package/dist/db/drizzle/drizzle/0000_initial.sql +336 -0
- package/dist/db/drizzle/drizzle/0001_indexes.sql +20 -0
- package/dist/db/drizzle/drizzle/0002_pgvector.sql +19 -0
- package/dist/db/drizzle/drizzle/meta/0000_snapshot.json +2593 -0
- package/dist/db/drizzle/drizzle/meta/_journal.json +27 -0
- package/dist/db/drizzle/meta/0000_snapshot.json +2593 -0
- package/dist/db/drizzle/meta/_journal.json +27 -0
- package/dist/db/embedding-store.d.ts +2 -1
- package/dist/db/embedding-store.d.ts.map +1 -1
- package/dist/db/embedding-store.interface.d.ts +19 -0
- package/dist/db/embedding-store.interface.d.ts.map +1 -0
- package/dist/db/embedding-store.interface.js +7 -0
- package/dist/db/embedding-store.interface.js.map +1 -0
- package/dist/db/embedding-store.js +3 -1
- package/dist/db/embedding-store.js.map +1 -1
- package/dist/db/eval-store.d.ts +88 -0
- package/dist/db/eval-store.d.ts.map +1 -0
- package/dist/db/eval-store.js +408 -0
- package/dist/db/eval-store.js.map +1 -0
- package/dist/db/guardrail-store.d.ts +9 -0
- package/dist/db/guardrail-store.d.ts.map +1 -1
- package/dist/db/guardrail-store.js +57 -3
- package/dist/db/guardrail-store.js.map +1 -1
- package/dist/db/index.d.ts +7 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +4 -12
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrate.d.ts +5 -22
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +7 -637
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/migrate.postgres.d.ts +16 -0
- package/dist/db/migrate.postgres.d.ts.map +1 -0
- package/dist/db/migrate.postgres.js +23 -0
- package/dist/db/migrate.postgres.js.map +1 -0
- package/dist/db/migrate.sqlite.d.ts +26 -0
- package/dist/db/migrate.sqlite.d.ts.map +1 -0
- package/dist/db/migrate.sqlite.js +920 -0
- package/dist/db/migrate.sqlite.js.map +1 -0
- package/dist/db/postgres-embedding-store.d.ts +23 -0
- package/dist/db/postgres-embedding-store.d.ts.map +1 -0
- package/dist/db/postgres-embedding-store.js +218 -0
- package/dist/db/postgres-embedding-store.js.map +1 -0
- package/dist/db/postgres-store.d.ts +80 -0
- package/dist/db/postgres-store.d.ts.map +1 -0
- package/dist/db/postgres-store.js +910 -0
- package/dist/db/postgres-store.js.map +1 -0
- package/dist/db/prompt-store.d.ts +57 -0
- package/dist/db/prompt-store.d.ts.map +1 -0
- package/dist/db/prompt-store.js +300 -0
- package/dist/db/prompt-store.js.map +1 -0
- package/dist/db/repositories/agent-repository.d.ts +21 -0
- package/dist/db/repositories/agent-repository.d.ts.map +1 -0
- package/dist/db/repositories/agent-repository.js +142 -0
- package/dist/db/repositories/agent-repository.js.map +1 -0
- package/dist/db/repositories/alert-repository.d.ts +27 -0
- package/dist/db/repositories/alert-repository.d.ts.map +1 -0
- package/dist/db/repositories/alert-repository.js +164 -0
- package/dist/db/repositories/alert-repository.js.map +1 -0
- package/dist/db/repositories/analytics-repository.d.ts +24 -0
- package/dist/db/repositories/analytics-repository.d.ts.map +1 -0
- package/dist/db/repositories/analytics-repository.js +147 -0
- package/dist/db/repositories/analytics-repository.js.map +1 -0
- package/dist/db/repositories/event-repository.d.ts +81 -0
- package/dist/db/repositories/event-repository.d.ts.map +1 -0
- package/dist/db/repositories/event-repository.js +331 -0
- package/dist/db/repositories/event-repository.js.map +1 -0
- package/dist/db/repositories/notification-channel-repository.d.ts +28 -0
- package/dist/db/repositories/notification-channel-repository.d.ts.map +1 -0
- package/dist/db/repositories/notification-channel-repository.js +151 -0
- package/dist/db/repositories/notification-channel-repository.js.map +1 -0
- package/dist/db/repositories/session-repository.d.ts +26 -0
- package/dist/db/repositories/session-repository.d.ts.map +1 -0
- package/dist/db/repositories/session-repository.js +240 -0
- package/dist/db/repositories/session-repository.js.map +1 -0
- package/dist/db/schema.postgres.d.ts +4681 -0
- package/dist/db/schema.postgres.d.ts.map +1 -0
- package/dist/db/schema.postgres.js +458 -0
- package/dist/db/schema.postgres.js.map +1 -0
- package/dist/db/schema.sqlite.d.ts +2221 -671
- package/dist/db/schema.sqlite.d.ts.map +1 -1
- package/dist/db/schema.sqlite.js +137 -2
- package/dist/db/schema.sqlite.js.map +1 -1
- package/dist/db/services/retention-service.d.ts +13 -0
- package/dist/db/services/retention-service.d.ts.map +1 -0
- package/dist/db/services/retention-service.js +48 -0
- package/dist/db/services/retention-service.js.map +1 -0
- package/dist/db/shared/query-helpers.d.ts +32 -0
- package/dist/db/shared/query-helpers.d.ts.map +1 -0
- package/dist/db/shared/query-helpers.js +180 -0
- package/dist/db/shared/query-helpers.js.map +1 -0
- package/dist/db/sqlite-store.d.ts +48 -55
- package/dist/db/sqlite-store.d.ts.map +1 -1
- package/dist/db/sqlite-store.js +78 -945
- package/dist/db/sqlite-store.js.map +1 -1
- package/dist/db/tenant-scoped-store.d.ts +18 -1
- package/dist/db/tenant-scoped-store.d.ts.map +1 -1
- package/dist/db/tenant-scoped-store.js +6 -0
- package/dist/db/tenant-scoped-store.js.map +1 -1
- package/dist/health.d.ts +22 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +34 -0
- package/dist/health.js.map +1 -0
- package/dist/index.d.ts +35 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +161 -300
- package/dist/index.js.map +1 -1
- package/dist/lib/alert-engine.d.ts +10 -0
- package/dist/lib/alert-engine.d.ts.map +1 -1
- package/dist/lib/alert-engine.js +73 -20
- package/dist/lib/alert-engine.js.map +1 -1
- package/dist/lib/api-schema.d.ts +126 -0
- package/dist/lib/api-schema.d.ts.map +1 -0
- package/dist/lib/api-schema.js +69 -0
- package/dist/lib/api-schema.js.map +1 -0
- package/dist/lib/api-version.d.ts +21 -0
- package/dist/lib/api-version.d.ts.map +1 -0
- package/dist/lib/api-version.js +36 -0
- package/dist/lib/api-version.js.map +1 -0
- package/dist/lib/audit-verify.d.ts +40 -0
- package/dist/lib/audit-verify.d.ts.map +1 -0
- package/dist/lib/audit-verify.js +128 -0
- package/dist/lib/audit-verify.js.map +1 -0
- package/dist/lib/audit.d.ts +37 -0
- package/dist/lib/audit.d.ts.map +1 -0
- package/dist/lib/audit.js +59 -0
- package/dist/lib/audit.js.map +1 -0
- package/dist/lib/budget-engine.d.ts +26 -0
- package/dist/lib/budget-engine.d.ts.map +1 -0
- package/dist/lib/budget-engine.js +201 -0
- package/dist/lib/budget-engine.js.map +1 -0
- package/dist/lib/compliance-export.d.ts +41 -0
- package/dist/lib/compliance-export.d.ts.map +1 -0
- package/dist/lib/compliance-export.js +124 -0
- package/dist/lib/compliance-export.js.map +1 -0
- package/dist/lib/compliance-report.d.ts +87 -0
- package/dist/lib/compliance-report.d.ts.map +1 -0
- package/dist/lib/compliance-report.js +148 -0
- package/dist/lib/compliance-report.js.map +1 -0
- package/dist/lib/context/retrieval.d.ts +5 -3
- package/dist/lib/context/retrieval.d.ts.map +1 -1
- package/dist/lib/context/retrieval.js +5 -2
- package/dist/lib/context/retrieval.js.map +1 -1
- package/dist/lib/cost-anomaly-detector.d.ts +23 -0
- package/dist/lib/cost-anomaly-detector.d.ts.map +1 -0
- package/dist/lib/cost-anomaly-detector.js +108 -0
- package/dist/lib/cost-anomaly-detector.js.map +1 -0
- package/dist/lib/db-resilience.d.ts +15 -0
- package/dist/lib/db-resilience.d.ts.map +1 -0
- package/dist/lib/db-resilience.js +49 -0
- package/dist/lib/db-resilience.js.map +1 -0
- package/dist/lib/diagnostics/cache.d.ts +29 -0
- package/dist/lib/diagnostics/cache.d.ts.map +1 -0
- package/dist/lib/diagnostics/cache.js +88 -0
- package/dist/lib/diagnostics/cache.js.map +1 -0
- package/dist/lib/diagnostics/context-builder.d.ts +41 -0
- package/dist/lib/diagnostics/context-builder.d.ts.map +1 -0
- package/dist/lib/diagnostics/context-builder.js +135 -0
- package/dist/lib/diagnostics/context-builder.js.map +1 -0
- package/dist/lib/diagnostics/index.d.ts +34 -0
- package/dist/lib/diagnostics/index.d.ts.map +1 -0
- package/dist/lib/diagnostics/index.js +223 -0
- package/dist/lib/diagnostics/index.js.map +1 -0
- package/dist/lib/diagnostics/llm-client.d.ts +24 -0
- package/dist/lib/diagnostics/llm-client.d.ts.map +1 -0
- package/dist/lib/diagnostics/llm-client.js +42 -0
- package/dist/lib/diagnostics/llm-client.js.map +1 -0
- package/dist/lib/diagnostics/prompt-templates.d.ts +18 -0
- package/dist/lib/diagnostics/prompt-templates.d.ts.map +1 -0
- package/dist/lib/diagnostics/prompt-templates.js +144 -0
- package/dist/lib/diagnostics/prompt-templates.js.map +1 -0
- package/dist/lib/diagnostics/providers/anthropic.d.ts +8 -0
- package/dist/lib/diagnostics/providers/anthropic.d.ts.map +1 -0
- package/dist/lib/diagnostics/providers/anthropic.js +79 -0
- package/dist/lib/diagnostics/providers/anthropic.js.map +1 -0
- package/dist/lib/diagnostics/providers/openai.d.ts +8 -0
- package/dist/lib/diagnostics/providers/openai.d.ts.map +1 -0
- package/dist/lib/diagnostics/providers/openai.js +70 -0
- package/dist/lib/diagnostics/providers/openai.js.map +1 -0
- package/dist/lib/diagnostics/providers/types.d.ts +23 -0
- package/dist/lib/diagnostics/providers/types.d.ts.map +1 -0
- package/dist/lib/diagnostics/providers/types.js +5 -0
- package/dist/lib/diagnostics/providers/types.js.map +1 -0
- package/dist/lib/diagnostics/response-parser.d.ts +60 -0
- package/dist/lib/diagnostics/response-parser.d.ts.map +1 -0
- package/dist/lib/diagnostics/response-parser.js +55 -0
- package/dist/lib/diagnostics/response-parser.js.map +1 -0
- package/dist/lib/diagnostics/types.d.ts +60 -0
- package/dist/lib/diagnostics/types.d.ts.map +1 -0
- package/dist/lib/diagnostics/types.js +7 -0
- package/dist/lib/diagnostics/types.js.map +1 -0
- package/dist/lib/embeddings/index.d.ts +6 -3
- package/dist/lib/embeddings/index.d.ts.map +1 -1
- package/dist/lib/embeddings/index.js +7 -15
- package/dist/lib/embeddings/index.js.map +1 -1
- package/dist/lib/embeddings/worker.d.ts +2 -2
- package/dist/lib/embeddings/worker.d.ts.map +1 -1
- package/dist/lib/embeddings/worker.js +3 -1
- package/dist/lib/embeddings/worker.js.map +1 -1
- package/dist/lib/error-sanitizer.d.ts +28 -0
- package/dist/lib/error-sanitizer.d.ts.map +1 -0
- package/dist/lib/error-sanitizer.js +106 -0
- package/dist/lib/error-sanitizer.js.map +1 -0
- package/dist/lib/eval/index.d.ts +15 -0
- package/dist/lib/eval/index.d.ts.map +1 -0
- package/dist/lib/eval/index.js +24 -0
- package/dist/lib/eval/index.js.map +1 -0
- package/dist/lib/eval/runner.d.ts +28 -0
- package/dist/lib/eval/runner.d.ts.map +1 -0
- package/dist/lib/eval/runner.js +260 -0
- package/dist/lib/eval/runner.js.map +1 -0
- package/dist/lib/eval/scorers/contains.d.ts +10 -0
- package/dist/lib/eval/scorers/contains.d.ts.map +1 -0
- package/dist/lib/eval/scorers/contains.js +33 -0
- package/dist/lib/eval/scorers/contains.js.map +1 -0
- package/dist/lib/eval/scorers/exact-match.d.ts +10 -0
- package/dist/lib/eval/scorers/exact-match.d.ts.map +1 -0
- package/dist/lib/eval/scorers/exact-match.js +33 -0
- package/dist/lib/eval/scorers/exact-match.js.map +1 -0
- package/dist/lib/eval/scorers/index.d.ts +20 -0
- package/dist/lib/eval/scorers/index.d.ts.map +1 -0
- package/dist/lib/eval/scorers/index.js +19 -0
- package/dist/lib/eval/scorers/index.js.map +1 -0
- package/dist/lib/eval/scorers/llm-judge.d.ts +22 -0
- package/dist/lib/eval/scorers/llm-judge.d.ts.map +1 -0
- package/dist/lib/eval/scorers/llm-judge.js +79 -0
- package/dist/lib/eval/scorers/llm-judge.js.map +1 -0
- package/dist/lib/eval/scorers/regex.d.ts +10 -0
- package/dist/lib/eval/scorers/regex.d.ts.map +1 -0
- package/dist/lib/eval/scorers/regex.js +36 -0
- package/dist/lib/eval/scorers/regex.js.map +1 -0
- package/dist/lib/guardrails/actions.d.ts +6 -0
- package/dist/lib/guardrails/actions.d.ts.map +1 -1
- package/dist/lib/guardrails/actions.js +82 -0
- package/dist/lib/guardrails/actions.js.map +1 -1
- package/dist/lib/guardrails/conditions.d.ts +47 -0
- package/dist/lib/guardrails/conditions.d.ts.map +1 -1
- package/dist/lib/guardrails/conditions.js +55 -10
- package/dist/lib/guardrails/conditions.js.map +1 -1
- package/dist/lib/guardrails/content-engine.d.ts +19 -0
- package/dist/lib/guardrails/content-engine.d.ts.map +1 -0
- package/dist/lib/guardrails/content-engine.js +154 -0
- package/dist/lib/guardrails/content-engine.js.map +1 -0
- package/dist/lib/guardrails/engine.d.ts +33 -0
- package/dist/lib/guardrails/engine.d.ts.map +1 -1
- package/dist/lib/guardrails/engine.js +37 -2
- package/dist/lib/guardrails/engine.js.map +1 -1
- package/dist/lib/guardrails/scanners/base-scanner.d.ts +23 -0
- package/dist/lib/guardrails/scanners/base-scanner.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/base-scanner.js +7 -0
- package/dist/lib/guardrails/scanners/base-scanner.js.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.d.ts +13 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.js +49 -0
- package/dist/lib/guardrails/scanners/patterns/pii-patterns.js.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.d.ts +6 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.js +69 -0
- package/dist/lib/guardrails/scanners/patterns/secret-patterns.js.map +1 -0
- package/dist/lib/guardrails/scanners/pii-scanner.d.ts +10 -0
- package/dist/lib/guardrails/scanners/pii-scanner.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/pii-scanner.js +57 -0
- package/dist/lib/guardrails/scanners/pii-scanner.js.map +1 -0
- package/dist/lib/guardrails/scanners/scanner-registry.d.ts +14 -0
- package/dist/lib/guardrails/scanners/scanner-registry.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/scanner-registry.js +51 -0
- package/dist/lib/guardrails/scanners/scanner-registry.js.map +1 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.d.ts +9 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.d.ts.map +1 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.js +47 -0
- package/dist/lib/guardrails/scanners/secrets-scanner.js.map +1 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +31 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/lore-client.d.ts +80 -0
- package/dist/lib/lore-client.d.ts.map +1 -0
- package/dist/lib/lore-client.js +153 -0
- package/dist/lib/lore-client.js.map +1 -0
- package/dist/lib/mesh-client.d.ts +31 -0
- package/dist/lib/mesh-client.d.ts.map +1 -0
- package/dist/lib/mesh-client.js +72 -0
- package/dist/lib/mesh-client.js.map +1 -0
- package/dist/lib/notifications/grouping-buffer.d.ts +25 -0
- package/dist/lib/notifications/grouping-buffer.d.ts.map +1 -0
- package/dist/lib/notifications/grouping-buffer.js +73 -0
- package/dist/lib/notifications/grouping-buffer.js.map +1 -0
- package/dist/lib/notifications/provider.d.ts +10 -0
- package/dist/lib/notifications/provider.d.ts.map +1 -0
- package/dist/lib/notifications/provider.js +5 -0
- package/dist/lib/notifications/provider.js.map +1 -0
- package/dist/lib/notifications/providers/email.d.ts +14 -0
- package/dist/lib/notifications/providers/email.d.ts.map +1 -0
- package/dist/lib/notifications/providers/email.js +88 -0
- package/dist/lib/notifications/providers/email.js.map +1 -0
- package/dist/lib/notifications/providers/pagerduty.d.ts +16 -0
- package/dist/lib/notifications/providers/pagerduty.d.ts.map +1 -0
- package/dist/lib/notifications/providers/pagerduty.js +94 -0
- package/dist/lib/notifications/providers/pagerduty.js.map +1 -0
- package/dist/lib/notifications/providers/slack.d.ts +14 -0
- package/dist/lib/notifications/providers/slack.d.ts.map +1 -0
- package/dist/lib/notifications/providers/slack.js +106 -0
- package/dist/lib/notifications/providers/slack.js.map +1 -0
- package/dist/lib/notifications/providers/webhook.d.ts +16 -0
- package/dist/lib/notifications/providers/webhook.d.ts.map +1 -0
- package/dist/lib/notifications/providers/webhook.js +78 -0
- package/dist/lib/notifications/providers/webhook.js.map +1 -0
- package/dist/lib/notifications/router.d.ts +30 -0
- package/dist/lib/notifications/router.d.ts.map +1 -0
- package/dist/lib/notifications/router.js +137 -0
- package/dist/lib/notifications/router.js.map +1 -0
- package/dist/lib/notifications/ssrf.d.ts +13 -0
- package/dist/lib/notifications/ssrf.d.ts.map +1 -0
- package/dist/lib/notifications/ssrf.js +37 -0
- package/dist/lib/notifications/ssrf.js.map +1 -0
- package/dist/lib/optimization/analyzers/model-downgrade.d.ts +15 -0
- package/dist/lib/optimization/analyzers/model-downgrade.d.ts.map +1 -0
- package/dist/lib/optimization/analyzers/model-downgrade.js +58 -0
- package/dist/lib/optimization/analyzers/model-downgrade.js.map +1 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.d.ts +17 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.d.ts.map +1 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.js +160 -0
- package/dist/lib/optimization/analyzers/prompt-optimization.js.map +1 -0
- package/dist/lib/optimization/analyzers/types.d.ts +23 -0
- package/dist/lib/optimization/analyzers/types.d.ts.map +1 -0
- package/dist/lib/optimization/analyzers/types.js +5 -0
- package/dist/lib/optimization/analyzers/types.js.map +1 -0
- package/dist/lib/optimization/classifier.d.ts +4 -3
- package/dist/lib/optimization/classifier.d.ts.map +1 -1
- package/dist/lib/optimization/classifier.js +15 -9
- package/dist/lib/optimization/classifier.js.map +1 -1
- package/dist/lib/optimization/cost-optimizer.d.ts +21 -0
- package/dist/lib/optimization/cost-optimizer.d.ts.map +1 -0
- package/dist/lib/optimization/cost-optimizer.js +114 -0
- package/dist/lib/optimization/cost-optimizer.js.map +1 -0
- package/dist/lib/optimization/engine.d.ts.map +1 -1
- package/dist/lib/optimization/engine.js +45 -6
- package/dist/lib/optimization/engine.js.map +1 -1
- package/dist/lib/optimization/forecast.d.ts +39 -0
- package/dist/lib/optimization/forecast.d.ts.map +1 -0
- package/dist/lib/optimization/forecast.js +128 -0
- package/dist/lib/optimization/forecast.js.map +1 -0
- package/dist/lib/secrets.d.ts +30 -0
- package/dist/lib/secrets.d.ts.map +1 -0
- package/dist/lib/secrets.js +103 -0
- package/dist/lib/secrets.js.map +1 -0
- package/dist/lib/threshold-monitor.d.ts +53 -0
- package/dist/lib/threshold-monitor.d.ts.map +1 -0
- package/dist/lib/threshold-monitor.js +112 -0
- package/dist/lib/threshold-monitor.js.map +1 -0
- package/dist/middleware/audit.d.ts +16 -0
- package/dist/middleware/audit.d.ts.map +1 -0
- package/dist/middleware/audit.js +16 -0
- package/dist/middleware/audit.js.map +1 -0
- package/dist/middleware/auth-errors.d.ts +67 -0
- package/dist/middleware/auth-errors.d.ts.map +1 -0
- package/dist/middleware/auth-errors.js +84 -0
- package/dist/middleware/auth-errors.js.map +1 -0
- package/dist/middleware/auth.d.ts +5 -2
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +44 -17
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/body-limit.d.ts +9 -0
- package/dist/middleware/body-limit.d.ts.map +1 -0
- package/dist/middleware/body-limit.js +15 -0
- package/dist/middleware/body-limit.js.map +1 -0
- package/dist/middleware/cors-config.d.ts +30 -0
- package/dist/middleware/cors-config.d.ts.map +1 -0
- package/dist/middleware/cors-config.js +55 -0
- package/dist/middleware/cors-config.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +9 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +56 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/rbac.d.ts +30 -0
- package/dist/middleware/rbac.d.ts.map +1 -0
- package/dist/middleware/rbac.js +87 -0
- package/dist/middleware/rbac.js.map +1 -0
- package/dist/middleware/security-headers.d.ts +12 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +57 -0
- package/dist/middleware/security-headers.js.map +1 -0
- package/dist/middleware/unified-auth.d.ts +49 -0
- package/dist/middleware/unified-auth.d.ts.map +1 -0
- package/dist/middleware/unified-auth.js +246 -0
- package/dist/middleware/unified-auth.js.map +1 -0
- package/dist/middleware/validation.d.ts +31 -0
- package/dist/middleware/validation.d.ts.map +1 -0
- package/dist/middleware/validation.js +45 -0
- package/dist/middleware/validation.js.map +1 -0
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +73 -0
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/alerts.d.ts.map +1 -1
- package/dist/routes/alerts.js +15 -37
- package/dist/routes/alerts.js.map +1 -1
- package/dist/routes/analytics.d.ts +2 -1
- package/dist/routes/analytics.d.ts.map +1 -1
- package/dist/routes/analytics.js +268 -95
- package/dist/routes/analytics.js.map +1 -1
- package/dist/routes/api-keys.d.ts +5 -0
- package/dist/routes/api-keys.d.ts.map +1 -1
- package/dist/routes/api-keys.js +89 -8
- package/dist/routes/api-keys.js.map +1 -1
- package/dist/routes/api-version.d.ts +9 -0
- package/dist/routes/api-version.d.ts.map +1 -0
- package/dist/routes/api-version.js +19 -0
- package/dist/routes/api-version.js.map +1 -0
- package/dist/routes/audit-verify.d.ts +13 -0
- package/dist/routes/audit-verify.d.ts.map +1 -0
- package/dist/routes/audit-verify.js +137 -0
- package/dist/routes/audit-verify.js.map +1 -0
- package/dist/routes/audit.d.ts +4 -6
- package/dist/routes/audit.d.ts.map +1 -1
- package/dist/routes/audit.js +54 -157
- package/dist/routes/audit.js.map +1 -1
- package/dist/routes/auth.d.ts +21 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +235 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/benchmarks.d.ts.map +1 -1
- package/dist/routes/benchmarks.js +63 -11
- package/dist/routes/benchmarks.js.map +1 -1
- package/dist/routes/capabilities-top.d.ts.map +1 -1
- package/dist/routes/capabilities-top.js +1 -4
- package/dist/routes/capabilities-top.js.map +1 -1
- package/dist/routes/capabilities.d.ts.map +1 -1
- package/dist/routes/capabilities.js +1 -7
- package/dist/routes/capabilities.js.map +1 -1
- package/dist/routes/compliance.d.ts +17 -0
- package/dist/routes/compliance.d.ts.map +1 -0
- package/dist/routes/compliance.js +151 -0
- package/dist/routes/compliance.js.map +1 -0
- package/dist/routes/config.d.ts +1 -13
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/context.d.ts.map +1 -1
- package/dist/routes/context.js +6 -5
- package/dist/routes/context.js.map +1 -1
- package/dist/routes/cost-budgets.d.ts +20 -0
- package/dist/routes/cost-budgets.d.ts.map +1 -0
- package/dist/routes/cost-budgets.js +177 -0
- package/dist/routes/cost-budgets.js.map +1 -0
- package/dist/routes/delegation.d.ts.map +1 -1
- package/dist/routes/delegation.js +67 -41
- package/dist/routes/delegation.js.map +1 -1
- package/dist/routes/delegations-top.d.ts.map +1 -1
- package/dist/routes/delegations-top.js +1 -3
- package/dist/routes/delegations-top.js.map +1 -1
- package/dist/routes/diagnose.d.ts +16 -0
- package/dist/routes/diagnose.d.ts.map +1 -0
- package/dist/routes/diagnose.js +82 -0
- package/dist/routes/diagnose.js.map +1 -0
- package/dist/routes/discovery.d.ts.map +1 -1
- package/dist/routes/discovery.js +50 -38
- package/dist/routes/discovery.js.map +1 -1
- package/dist/routes/eval.d.ts +24 -0
- package/dist/routes/eval.d.ts.map +1 -0
- package/dist/routes/eval.js +281 -0
- package/dist/routes/eval.js.map +1 -0
- package/dist/routes/events.d.ts.map +1 -1
- package/dist/routes/events.js +11 -6
- package/dist/routes/events.js.map +1 -1
- package/dist/routes/guardrails.d.ts +2 -1
- package/dist/routes/guardrails.d.ts.map +1 -1
- package/dist/routes/guardrails.js +205 -50
- package/dist/routes/guardrails.js.map +1 -1
- package/dist/routes/health.d.ts +14 -11
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +181 -61
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/helpers.d.ts +27 -0
- package/dist/routes/helpers.d.ts.map +1 -0
- package/dist/routes/helpers.js +46 -0
- package/dist/routes/helpers.js.map +1 -0
- package/dist/routes/lore-proxy.d.ts +15 -0
- package/dist/routes/lore-proxy.d.ts.map +1 -0
- package/dist/routes/lore-proxy.js +75 -0
- package/dist/routes/lore-proxy.js.map +1 -0
- package/dist/routes/mcp-policies.d.ts +40 -0
- package/dist/routes/mcp-policies.d.ts.map +1 -0
- package/dist/routes/mcp-policies.js +200 -0
- package/dist/routes/mcp-policies.js.map +1 -0
- package/dist/routes/mesh-proxy.d.ts +7 -0
- package/dist/routes/mesh-proxy.d.ts.map +1 -0
- package/dist/routes/mesh-proxy.js +94 -0
- package/dist/routes/mesh-proxy.js.map +1 -0
- package/dist/routes/notifications.d.ts +19 -0
- package/dist/routes/notifications.d.ts.map +1 -0
- package/dist/routes/notifications.js +129 -0
- package/dist/routes/notifications.js.map +1 -0
- package/dist/routes/optimization-advisor.d.ts +13 -0
- package/dist/routes/optimization-advisor.d.ts.map +1 -0
- package/dist/routes/optimization-advisor.js +42 -0
- package/dist/routes/optimization-advisor.js.map +1 -0
- package/dist/routes/optimize.d.ts.map +1 -1
- package/dist/routes/optimize.js +44 -0
- package/dist/routes/optimize.js.map +1 -1
- package/dist/routes/otlp.d.ts +17 -0
- package/dist/routes/otlp.d.ts.map +1 -0
- package/dist/routes/otlp.js +544 -0
- package/dist/routes/otlp.js.map +1 -0
- package/dist/routes/prompts.d.ts +21 -0
- package/dist/routes/prompts.d.ts.map +1 -0
- package/dist/routes/prompts.js +173 -0
- package/dist/routes/prompts.js.map +1 -0
- package/dist/routes/recall.d.ts.map +1 -1
- package/dist/routes/recall.js +13 -7
- package/dist/routes/recall.js.map +1 -1
- package/dist/routes/registration.d.ts +27 -0
- package/dist/routes/registration.d.ts.map +1 -0
- package/dist/routes/registration.js +311 -0
- package/dist/routes/registration.js.map +1 -0
- package/dist/routes/replay.d.ts.map +1 -1
- package/dist/routes/replay.js +53 -1
- package/dist/routes/replay.js.map +1 -1
- package/dist/routes/server-info.d.ts +9 -0
- package/dist/routes/server-info.d.ts.map +1 -0
- package/dist/routes/server-info.js +18 -0
- package/dist/routes/server-info.js.map +1 -0
- package/dist/routes/sessions.d.ts +7 -7
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +112 -35
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/stats.d.ts.map +1 -1
- package/dist/routes/stats.js +40 -0
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/stream.d.ts +2 -2
- package/dist/routes/stream.d.ts.map +1 -1
- package/dist/routes/stream.js +7 -11
- package/dist/routes/stream.js.map +1 -1
- package/dist/routes/tenant-helper.d.ts +15 -10
- package/dist/routes/tenant-helper.d.ts.map +1 -1
- package/dist/routes/tenant-helper.js +36 -22
- package/dist/routes/tenant-helper.js.map +1 -1
- package/dist/routes/trust.d.ts.map +1 -1
- package/dist/routes/trust.js +1 -3
- package/dist/routes/trust.js.map +1 -1
- package/dist/schemas/api-keys.d.ts +11 -0
- package/dist/schemas/api-keys.d.ts.map +1 -0
- package/dist/schemas/api-keys.js +10 -0
- package/dist/schemas/api-keys.js.map +1 -0
- package/dist/schemas/common.d.ts +34 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +43 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/delegation.d.ts +23 -0
- package/dist/schemas/delegation.d.ts.map +1 -0
- package/dist/schemas/delegation.js +22 -0
- package/dist/schemas/delegation.js.map +1 -0
- package/dist/schemas/discovery.d.ts +17 -0
- package/dist/schemas/discovery.d.ts.map +1 -0
- package/dist/schemas/discovery.js +15 -0
- package/dist/schemas/discovery.js.map +1 -0
- package/dist/schemas/health.d.ts +75 -0
- package/dist/schemas/health.d.ts.map +1 -0
- package/dist/schemas/health.js +55 -0
- package/dist/schemas/health.js.map +1 -0
- package/dist/schemas/index.d.ts +6 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +6 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/sessions.d.ts +67 -0
- package/dist/schemas/sessions.d.ts.map +1 -0
- package/dist/schemas/sessions.js +58 -0
- package/dist/schemas/sessions.js.map +1 -0
- package/dist/services/delegation-service.d.ts +1 -4
- package/dist/services/delegation-service.d.ts.map +1 -1
- package/dist/services/delegation-service.js +5 -31
- package/dist/services/delegation-service.js.map +1 -1
- package/dist/services/optimization-advisor.d.ts +37 -0
- package/dist/services/optimization-advisor.d.ts.map +1 -0
- package/dist/services/optimization-advisor.js +239 -0
- package/dist/services/optimization-advisor.js.map +1 -0
- package/package.json +29 -19
- package/dist/db/lesson-store.d.ts +0 -57
- package/dist/db/lesson-store.d.ts.map +0 -1
- package/dist/db/lesson-store.js +0 -217
- package/dist/db/lesson-store.js.map +0 -1
- package/dist/lib/embeddings/local.d.ts +0 -15
- package/dist/lib/embeddings/local.d.ts.map +0 -1
- package/dist/lib/embeddings/local.js +0 -65
- package/dist/lib/embeddings/local.js.map +0 -1
- package/dist/lib/redaction/human-review-layer.d.ts +0 -37
- package/dist/lib/redaction/human-review-layer.d.ts.map +0 -1
- package/dist/lib/redaction/human-review-layer.js +0 -62
- package/dist/lib/redaction/human-review-layer.js.map +0 -1
- package/dist/lib/redaction/index.d.ts +0 -12
- package/dist/lib/redaction/index.d.ts.map +0 -1
- package/dist/lib/redaction/index.js +0 -12
- package/dist/lib/redaction/index.js.map +0 -1
- package/dist/lib/redaction/pii-detection-layer.d.ts +0 -30
- package/dist/lib/redaction/pii-detection-layer.d.ts.map +0 -1
- package/dist/lib/redaction/pii-detection-layer.js +0 -183
- package/dist/lib/redaction/pii-detection-layer.js.map +0 -1
- package/dist/lib/redaction/pipeline.d.ts +0 -26
- package/dist/lib/redaction/pipeline.d.ts.map +0 -1
- package/dist/lib/redaction/pipeline.js +0 -91
- package/dist/lib/redaction/pipeline.js.map +0 -1
- package/dist/lib/redaction/secret-detection-layer.d.ts +0 -10
- package/dist/lib/redaction/secret-detection-layer.d.ts.map +0 -1
- package/dist/lib/redaction/secret-detection-layer.js +0 -79
- package/dist/lib/redaction/secret-detection-layer.js.map +0 -1
- package/dist/lib/redaction/secret-patterns.d.ts +0 -29
- package/dist/lib/redaction/secret-patterns.d.ts.map +0 -1
- package/dist/lib/redaction/secret-patterns.js +0 -133
- package/dist/lib/redaction/secret-patterns.js.map +0 -1
- package/dist/lib/redaction/semantic-denylist-layer.d.ts +0 -10
- package/dist/lib/redaction/semantic-denylist-layer.d.ts.map +0 -1
- package/dist/lib/redaction/semantic-denylist-layer.js +0 -64
- package/dist/lib/redaction/semantic-denylist-layer.js.map +0 -1
- package/dist/lib/redaction/tenant-deidentification-layer.d.ts +0 -10
- package/dist/lib/redaction/tenant-deidentification-layer.d.ts.map +0 -1
- package/dist/lib/redaction/tenant-deidentification-layer.js +0 -64
- package/dist/lib/redaction/tenant-deidentification-layer.js.map +0 -1
- package/dist/lib/redaction/url-path-scrubbing-layer.d.ts +0 -14
- package/dist/lib/redaction/url-path-scrubbing-layer.d.ts.map +0 -1
- package/dist/lib/redaction/url-path-scrubbing-layer.js +0 -156
- package/dist/lib/redaction/url-path-scrubbing-layer.js.map +0 -1
- package/dist/routes/community.d.ts +0 -24
- package/dist/routes/community.d.ts.map +0 -1
- package/dist/routes/community.js +0 -272
- package/dist/routes/community.js.map +0 -1
- package/dist/routes/lessons.d.ts +0 -19
- package/dist/routes/lessons.d.ts.map +0 -1
- package/dist/routes/lessons.js +0 -164
- package/dist/routes/lessons.js.map +0 -1
- package/dist/routes/redaction-test.d.ts +0 -14
- package/dist/routes/redaction-test.d.ts.map +0 -1
- package/dist/routes/redaction-test.js +0 -33
- package/dist/routes/redaction-test.js.map +0 -1
- package/dist/services/community-service.d.ts +0 -283
- package/dist/services/community-service.d.ts.map +0 -1
- package/dist/services/community-service.js +0 -816
- package/dist/services/community-service.js.map +0 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SH-7: Secret Management Hardening
|
|
3
|
+
*
|
|
4
|
+
* Resolves secrets from 3 tiers:
|
|
5
|
+
* 1. process.env[name] — plain env var (default)
|
|
6
|
+
* 2. process.env[name + '_FILE'] — file path (Docker Secrets / K8s)
|
|
7
|
+
* 3. process.env[name + '_ARN'] — AWS Secrets Manager ARN
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { createLogger } from './logger.js';
|
|
11
|
+
const log = createLogger('Secrets');
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a single secret through the 3-tier hierarchy.
|
|
14
|
+
* Returns the resolved value or undefined.
|
|
15
|
+
*/
|
|
16
|
+
export async function resolveSecret(name) {
|
|
17
|
+
// Tier 1: plain env var
|
|
18
|
+
const plain = process.env[name];
|
|
19
|
+
if (plain !== undefined)
|
|
20
|
+
return plain;
|
|
21
|
+
// Tier 2: file-based (_FILE suffix)
|
|
22
|
+
const filePath = process.env[`${name}_FILE`];
|
|
23
|
+
if (filePath) {
|
|
24
|
+
try {
|
|
25
|
+
return readFileSync(filePath, 'utf-8').trim();
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
throw new Error(`Secret ${name}: failed to read file "${filePath}": ${err instanceof Error ? err.message : err}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Tier 3: AWS Secrets Manager (_ARN suffix)
|
|
32
|
+
const arn = process.env[`${name}_ARN`];
|
|
33
|
+
if (arn) {
|
|
34
|
+
return fetchFromAwsSecretsManager(arn, name);
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Lazy-import AWS SDK and fetch secret value.
|
|
40
|
+
*/
|
|
41
|
+
async function fetchFromAwsSecretsManager(arn, name) {
|
|
42
|
+
try {
|
|
43
|
+
// @ts-ignore — optional dependency; fails gracefully at runtime
|
|
44
|
+
const mod = await import('@aws-sdk/client-secrets-manager').catch(() => {
|
|
45
|
+
throw new Error(`Secret ${name}: install @aws-sdk/client-secrets-manager to use ARN-based secrets`);
|
|
46
|
+
});
|
|
47
|
+
const { SecretsManagerClient, GetSecretValueCommand } = mod;
|
|
48
|
+
const client = new SecretsManagerClient({});
|
|
49
|
+
const response = await client.send(new GetSecretValueCommand({ SecretId: arn }));
|
|
50
|
+
const value = response.SecretString;
|
|
51
|
+
if (!value) {
|
|
52
|
+
throw new Error(`Secret ${name}: ARN "${arn}" returned no SecretString`);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (err instanceof Error && err.message.startsWith(`Secret ${name}:`))
|
|
58
|
+
throw err;
|
|
59
|
+
throw new Error(`Secret ${name}: AWS Secrets Manager fetch failed for "${arn}": ${err instanceof Error ? err.message : err}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Well-known secret names managed by this module. */
|
|
63
|
+
export const MANAGED_SECRETS = [
|
|
64
|
+
{ name: 'JWT_SECRET', required: true },
|
|
65
|
+
{ name: 'OIDC_CLIENT_SECRET' },
|
|
66
|
+
{ name: 'DATABASE_URL' },
|
|
67
|
+
{ name: 'AGENTGATE_WEBHOOK_SECRET' },
|
|
68
|
+
{ name: 'FORMBRIDGE_WEBHOOK_SECRET' },
|
|
69
|
+
];
|
|
70
|
+
/**
|
|
71
|
+
* Resolve all managed secrets at startup.
|
|
72
|
+
* - Sets resolved values back into process.env for downstream consumers.
|
|
73
|
+
* - Fails fast in production if required secrets are missing.
|
|
74
|
+
* - Warns in production if all secrets are plain env vars (no file/ARN).
|
|
75
|
+
*/
|
|
76
|
+
export async function resolveAllSecrets() {
|
|
77
|
+
const isProduction = process.env['NODE_ENV'] === 'production';
|
|
78
|
+
const resolved = {};
|
|
79
|
+
let allPlainEnv = true;
|
|
80
|
+
for (const spec of MANAGED_SECRETS) {
|
|
81
|
+
const { name } = spec;
|
|
82
|
+
// Track whether any secret uses file or ARN tier
|
|
83
|
+
if (process.env[`${name}_FILE`] || process.env[`${name}_ARN`]) {
|
|
84
|
+
allPlainEnv = false;
|
|
85
|
+
}
|
|
86
|
+
const value = await resolveSecret(name);
|
|
87
|
+
if (value !== undefined) {
|
|
88
|
+
resolved[name] = value;
|
|
89
|
+
// Inject into process.env so downstream code (config.ts, middleware) just reads env
|
|
90
|
+
process.env[name] = value;
|
|
91
|
+
}
|
|
92
|
+
else if (spec.required && isProduction) {
|
|
93
|
+
throw new Error(`FATAL: Required secret "${name}" is not set. ` +
|
|
94
|
+
`Provide ${name}, ${name}_FILE, or ${name}_ARN.`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (isProduction && allPlainEnv) {
|
|
98
|
+
log.warn('⚠️ All secrets are plain environment variables. ' +
|
|
99
|
+
'Consider using _FILE (Docker/K8s) or _ARN (AWS) for production hardening.');
|
|
100
|
+
}
|
|
101
|
+
return resolved;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AAWpC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,wBAAwB;IACxB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEtC,oCAAoC;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;IAC7C,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,0BAA0B,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CACjG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC;IACvC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,0BAA0B,CAAC,GAAW,EAAE,IAAY;IACjE,IAAI,CAAC;QACH,gEAAgE;QAChE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACrE,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,oEAAoE,CACnF,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GAAG,GAAG,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAChC,IAAI,qBAAqB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAC7C,CAAC;QACF,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,UAAU,GAAG,4BAA4B,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,IAAI,GAAG,CAAC;YAAE,MAAM,GAAG,CAAC;QACjF,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,2CAA2C,GAAG,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAC7G,CAAC;IACJ,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC3C,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;IACtC,EAAE,IAAI,EAAE,oBAAoB,EAAE;IAC9B,EAAE,IAAI,EAAE,cAAc,EAAE;IACxB,EAAE,IAAI,EAAE,0BAA0B,EAAE;IACpC,EAAE,IAAI,EAAE,2BAA2B,EAAE;CACtC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,CAAC;IAC9D,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QAEtB,iDAAiD;QACjD,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC;YAC9D,WAAW,GAAG,KAAK,CAAC;QACtB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YACvB,oFAAoF;YACpF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,YAAY,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,2BAA2B,IAAI,gBAAgB;gBAC/C,WAAW,IAAI,KAAK,IAAI,aAAa,IAAI,OAAO,CACjD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,YAAY,IAAI,WAAW,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CACN,mDAAmD;YACnD,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threshold Monitor — detects metric breaches and fires webhooks.
|
|
3
|
+
*
|
|
4
|
+
* Part of the Proactive Guardrails feature (Batch 1, Story 1.2).
|
|
5
|
+
* Monitors configurable metric thresholds and fires webhooks on state transitions
|
|
6
|
+
* (ok→breached or breached→ok) to enable downstream systems (e.g. AgentGate)
|
|
7
|
+
* to tighten/relax approval policies automatically.
|
|
8
|
+
*/
|
|
9
|
+
export type MetricType = 'error_rate' | 'cost' | 'latency';
|
|
10
|
+
export type WindowSize = '5m' | '15m' | '1h';
|
|
11
|
+
export type ThresholdState = 'ok' | 'breached';
|
|
12
|
+
export interface ThresholdConfig {
|
|
13
|
+
metric: MetricType;
|
|
14
|
+
value: number;
|
|
15
|
+
window: WindowSize;
|
|
16
|
+
webhookUrl: string;
|
|
17
|
+
agentId?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface WebhookPayload {
|
|
20
|
+
event: 'breach' | 'recovery';
|
|
21
|
+
metric: MetricType;
|
|
22
|
+
currentValue: number;
|
|
23
|
+
threshold: number;
|
|
24
|
+
agentId: string | null;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
}
|
|
27
|
+
/** Function signature for fetching current metric values */
|
|
28
|
+
export type MetricsFetcher = (metric: MetricType, window: WindowSize, agentId?: string) => Promise<number>;
|
|
29
|
+
export declare class ThresholdMonitor {
|
|
30
|
+
private thresholds;
|
|
31
|
+
private fetchMetric;
|
|
32
|
+
private states;
|
|
33
|
+
private timer;
|
|
34
|
+
private readonly checkIntervalMs;
|
|
35
|
+
constructor(thresholds: ThresholdConfig[], fetchMetric: MetricsFetcher, options?: {
|
|
36
|
+
checkIntervalMs?: number;
|
|
37
|
+
});
|
|
38
|
+
/** Unique key for a threshold config */
|
|
39
|
+
private key;
|
|
40
|
+
/** Start periodic checking */
|
|
41
|
+
start(): void;
|
|
42
|
+
/** Stop periodic checking */
|
|
43
|
+
stop(): void;
|
|
44
|
+
/** Get current state for a threshold */
|
|
45
|
+
getState(t: ThresholdConfig): ThresholdState;
|
|
46
|
+
/** Check all thresholds once */
|
|
47
|
+
checkAll(): Promise<void>;
|
|
48
|
+
/** Check a single threshold */
|
|
49
|
+
private checkOne;
|
|
50
|
+
/** Fire webhook with 3x retry and exponential backoff */
|
|
51
|
+
fireWebhook(url: string, payload: WebhookPayload): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=threshold-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threshold-monitor.d.ts","sourceRoot":"","sources":["../../src/lib/threshold-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC;AAC7C,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,UAAU,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,MAAM,CAAC,CAAC;AAQrB,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;IANrB,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAG/B,UAAU,EAAE,eAAe,EAAE,EAC7B,WAAW,EAAE,cAAc,EACnC,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE;IAUxC,wCAAwC;IACxC,OAAO,CAAC,GAAG;IAIX,8BAA8B;IAC9B,KAAK,IAAI,IAAI;IAOb,6BAA6B;IAC7B,IAAI,IAAI,IAAI;IAOZ,wCAAwC;IACxC,QAAQ,CAAC,CAAC,EAAE,eAAe,GAAG,cAAc;IAI5C,gCAAgC;IAC1B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,+BAA+B;YACjB,QAAQ;IA0BtB,yDAAyD;IACnD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA+BvE"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threshold Monitor — detects metric breaches and fires webhooks.
|
|
3
|
+
*
|
|
4
|
+
* Part of the Proactive Guardrails feature (Batch 1, Story 1.2).
|
|
5
|
+
* Monitors configurable metric thresholds and fires webhooks on state transitions
|
|
6
|
+
* (ok→breached or breached→ok) to enable downstream systems (e.g. AgentGate)
|
|
7
|
+
* to tighten/relax approval policies automatically.
|
|
8
|
+
*/
|
|
9
|
+
import { createLogger } from './logger.js';
|
|
10
|
+
import { isWebhookUrlAllowed } from './alert-engine.js';
|
|
11
|
+
const log = createLogger('ThresholdMonitor');
|
|
12
|
+
// ─── ThresholdMonitor ───────────────────────────────────────────────
|
|
13
|
+
const DEFAULT_CHECK_INTERVAL_MS = 60_000;
|
|
14
|
+
const MAX_RETRIES = 3;
|
|
15
|
+
const BASE_RETRY_DELAY_MS = 1_000;
|
|
16
|
+
export class ThresholdMonitor {
|
|
17
|
+
thresholds;
|
|
18
|
+
fetchMetric;
|
|
19
|
+
states = new Map();
|
|
20
|
+
timer = null;
|
|
21
|
+
checkIntervalMs;
|
|
22
|
+
constructor(thresholds, fetchMetric, options) {
|
|
23
|
+
this.thresholds = thresholds;
|
|
24
|
+
this.fetchMetric = fetchMetric;
|
|
25
|
+
this.checkIntervalMs = options?.checkIntervalMs ?? DEFAULT_CHECK_INTERVAL_MS;
|
|
26
|
+
// Initialize all thresholds to 'ok'
|
|
27
|
+
for (const t of thresholds) {
|
|
28
|
+
this.states.set(this.key(t), 'ok');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Unique key for a threshold config */
|
|
32
|
+
key(t) {
|
|
33
|
+
return `${t.metric}:${t.window}:${t.agentId ?? '*'}`;
|
|
34
|
+
}
|
|
35
|
+
/** Start periodic checking */
|
|
36
|
+
start() {
|
|
37
|
+
if (this.timer)
|
|
38
|
+
return;
|
|
39
|
+
this.timer = setInterval(() => this.checkAll(), this.checkIntervalMs);
|
|
40
|
+
this.timer.unref();
|
|
41
|
+
log.info(`ThresholdMonitor started (${this.thresholds.length} thresholds, ${this.checkIntervalMs}ms interval)`);
|
|
42
|
+
}
|
|
43
|
+
/** Stop periodic checking */
|
|
44
|
+
stop() {
|
|
45
|
+
if (this.timer) {
|
|
46
|
+
clearInterval(this.timer);
|
|
47
|
+
this.timer = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Get current state for a threshold */
|
|
51
|
+
getState(t) {
|
|
52
|
+
return this.states.get(this.key(t)) ?? 'ok';
|
|
53
|
+
}
|
|
54
|
+
/** Check all thresholds once */
|
|
55
|
+
async checkAll() {
|
|
56
|
+
await Promise.allSettled(this.thresholds.map((t) => this.checkOne(t)));
|
|
57
|
+
}
|
|
58
|
+
/** Check a single threshold */
|
|
59
|
+
async checkOne(t) {
|
|
60
|
+
try {
|
|
61
|
+
const currentValue = await this.fetchMetric(t.metric, t.window, t.agentId);
|
|
62
|
+
const k = this.key(t);
|
|
63
|
+
const prevState = this.states.get(k) ?? 'ok';
|
|
64
|
+
const newState = currentValue > t.value ? 'breached' : 'ok';
|
|
65
|
+
if (prevState !== newState) {
|
|
66
|
+
this.states.set(k, newState);
|
|
67
|
+
const payload = {
|
|
68
|
+
event: newState === 'breached' ? 'breach' : 'recovery',
|
|
69
|
+
metric: t.metric,
|
|
70
|
+
currentValue,
|
|
71
|
+
threshold: t.value,
|
|
72
|
+
agentId: t.agentId ?? null,
|
|
73
|
+
timestamp: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
log.info(`Threshold ${newState}: ${t.metric} = ${currentValue} (threshold: ${t.value})`);
|
|
76
|
+
await this.fireWebhook(t.webhookUrl, payload);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
log.error(`Failed to check threshold ${t.metric}: ${err}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Fire webhook with 3x retry and exponential backoff */
|
|
84
|
+
async fireWebhook(url, payload) {
|
|
85
|
+
if (!isWebhookUrlAllowed(url)) {
|
|
86
|
+
log.error(`Webhook URL blocked by SSRF protection: ${url}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
90
|
+
try {
|
|
91
|
+
const res = await fetch(url, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: { 'Content-Type': 'application/json' },
|
|
94
|
+
body: JSON.stringify(payload),
|
|
95
|
+
});
|
|
96
|
+
if (res.ok) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
log.warn(`Webhook attempt ${attempt + 1} failed: HTTP ${res.status}`);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
log.warn(`Webhook attempt ${attempt + 1} error: ${err}`);
|
|
103
|
+
}
|
|
104
|
+
if (attempt < MAX_RETRIES - 1) {
|
|
105
|
+
const delay = BASE_RETRY_DELAY_MS * Math.pow(2, attempt);
|
|
106
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
log.error(`Webhook delivery failed after ${MAX_RETRIES} attempts: ${url}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=threshold-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"threshold-monitor.js","sourceRoot":"","sources":["../../src/lib/threshold-monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Logger Middleware (SH-2)
|
|
3
|
+
*
|
|
4
|
+
* Injects the audit logger into Hono context as `c.get('audit')`.
|
|
5
|
+
*/
|
|
6
|
+
import type { AuditLogger } from '../lib/audit.js';
|
|
7
|
+
export type AuditVariables = {
|
|
8
|
+
audit: AuditLogger;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Create middleware that injects the audit logger into context.
|
|
12
|
+
*/
|
|
13
|
+
export declare function auditMiddleware(auditLogger: AuditLogger): import("hono").MiddlewareHandler<{
|
|
14
|
+
Variables: AuditVariables;
|
|
15
|
+
}, string, {}, Response>;
|
|
16
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/middleware/audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW;eACjB,cAAc;yBAIpD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Logger Middleware (SH-2)
|
|
3
|
+
*
|
|
4
|
+
* Injects the audit logger into Hono context as `c.get('audit')`.
|
|
5
|
+
*/
|
|
6
|
+
import { createMiddleware } from 'hono/factory';
|
|
7
|
+
/**
|
|
8
|
+
* Create middleware that injects the audit logger into context.
|
|
9
|
+
*/
|
|
10
|
+
export function auditMiddleware(auditLogger) {
|
|
11
|
+
return createMiddleware(async (c, next) => {
|
|
12
|
+
c.set('audit', auditLogger);
|
|
13
|
+
return next();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/middleware/audit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOhD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAwB;IACtD,OAAO,gBAAgB,CAAgC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC5B,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized auth error response builders (Story 6 / PRD §R5).
|
|
3
|
+
*
|
|
4
|
+
* All 401/403 responses share a consistent JSON structure with
|
|
5
|
+
* actionable `hint` fields. No stack traces or internals leaked.
|
|
6
|
+
*/
|
|
7
|
+
import type { Context } from 'hono';
|
|
8
|
+
export declare function missingCredentials(c: Context): Response & import("hono").TypedResponse<{
|
|
9
|
+
error: string;
|
|
10
|
+
hint: string;
|
|
11
|
+
docs: string;
|
|
12
|
+
status: number;
|
|
13
|
+
}, 401, "json">;
|
|
14
|
+
export declare function invalidApiKey(c: Context): Response & import("hono").TypedResponse<{
|
|
15
|
+
error: string;
|
|
16
|
+
hint: string;
|
|
17
|
+
status: number;
|
|
18
|
+
}, 401, "json">;
|
|
19
|
+
export declare function expiredApiKey(c: Context): Response & import("hono").TypedResponse<{
|
|
20
|
+
error: string;
|
|
21
|
+
hint: string;
|
|
22
|
+
status: number;
|
|
23
|
+
}, 401, "json">;
|
|
24
|
+
export declare function expiredJwt(c: Context): Response & import("hono").TypedResponse<{
|
|
25
|
+
error: string;
|
|
26
|
+
hint: string;
|
|
27
|
+
status: number;
|
|
28
|
+
}, 401, "json">;
|
|
29
|
+
export declare function invalidJwt(c: Context): Response & import("hono").TypedResponse<{
|
|
30
|
+
error: string;
|
|
31
|
+
hint: string;
|
|
32
|
+
docs: string;
|
|
33
|
+
status: number;
|
|
34
|
+
}, 401, "json">;
|
|
35
|
+
export declare function invalidCloudKey(c: Context): Response & import("hono").TypedResponse<{
|
|
36
|
+
error: string;
|
|
37
|
+
hint: string;
|
|
38
|
+
status: number;
|
|
39
|
+
}, 401, "json">;
|
|
40
|
+
export declare function authRequired(c: Context): Response & import("hono").TypedResponse<{
|
|
41
|
+
error: string;
|
|
42
|
+
hint: string;
|
|
43
|
+
status: number;
|
|
44
|
+
}, 401, "json">;
|
|
45
|
+
export declare function otlpAuthRequired(c: Context): Response & import("hono").TypedResponse<{
|
|
46
|
+
error: string;
|
|
47
|
+
hint: string;
|
|
48
|
+
docs: string;
|
|
49
|
+
status: number;
|
|
50
|
+
}, 401, "json">;
|
|
51
|
+
export declare function otlpInvalidToken(c: Context): Response & import("hono").TypedResponse<{
|
|
52
|
+
error: string;
|
|
53
|
+
hint: string;
|
|
54
|
+
status: number;
|
|
55
|
+
}, 401, "json">;
|
|
56
|
+
export declare function insufficientPermissions(c: Context, opts: {
|
|
57
|
+
required: string;
|
|
58
|
+
current: string;
|
|
59
|
+
hint?: string;
|
|
60
|
+
}): Response & import("hono").TypedResponse<{
|
|
61
|
+
error: string;
|
|
62
|
+
hint: string;
|
|
63
|
+
required: string;
|
|
64
|
+
current: string;
|
|
65
|
+
status: number;
|
|
66
|
+
}, 403, "json">;
|
|
67
|
+
//# sourceMappingURL=auth-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-errors.d.ts","sourceRoot":"","sources":["../../src/middleware/auth-errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAIpC,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO;;;;;gBAO5C;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO;;;;gBAMvC;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO;;;;gBAMvC;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO;;;;gBAMpC;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO;;;;;gBAOpC;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO;;;;gBAMzC;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO;;;;gBAMtC;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO;;;;;gBAO1C;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO;;;;gBAM1C;AAID,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;;;;;gBAQA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized auth error response builders (Story 6 / PRD §R5).
|
|
3
|
+
*
|
|
4
|
+
* All 401/403 responses share a consistent JSON structure with
|
|
5
|
+
* actionable `hint` fields. No stack traces or internals leaked.
|
|
6
|
+
*/
|
|
7
|
+
// ── 401 Responses ──────────────────────────────────────────
|
|
8
|
+
export function missingCredentials(c) {
|
|
9
|
+
return c.json({
|
|
10
|
+
error: 'Authentication required',
|
|
11
|
+
hint: "Provide an API key via 'Authorization: Bearer als_...' header, or log in via /auth/login",
|
|
12
|
+
docs: '/docs/authentication',
|
|
13
|
+
status: 401,
|
|
14
|
+
}, 401);
|
|
15
|
+
}
|
|
16
|
+
export function invalidApiKey(c) {
|
|
17
|
+
return c.json({
|
|
18
|
+
error: 'Invalid or revoked API key',
|
|
19
|
+
hint: 'This API key is no longer valid. Generate a new key at /api/keys.',
|
|
20
|
+
status: 401,
|
|
21
|
+
}, 401);
|
|
22
|
+
}
|
|
23
|
+
export function expiredApiKey(c) {
|
|
24
|
+
return c.json({
|
|
25
|
+
error: 'API key expired',
|
|
26
|
+
hint: 'This API key has been rotated and is no longer valid. Please use the new key.',
|
|
27
|
+
status: 401,
|
|
28
|
+
}, 401);
|
|
29
|
+
}
|
|
30
|
+
export function expiredJwt(c) {
|
|
31
|
+
return c.json({
|
|
32
|
+
error: 'Token expired',
|
|
33
|
+
hint: 'Your session has expired. Refresh via POST /auth/refresh or log in again.',
|
|
34
|
+
status: 401,
|
|
35
|
+
}, 401);
|
|
36
|
+
}
|
|
37
|
+
export function invalidJwt(c) {
|
|
38
|
+
return c.json({
|
|
39
|
+
error: 'Invalid token',
|
|
40
|
+
hint: 'The provided token is invalid. Log in again via /auth/login.',
|
|
41
|
+
docs: '/docs/authentication',
|
|
42
|
+
status: 401,
|
|
43
|
+
}, 401);
|
|
44
|
+
}
|
|
45
|
+
export function invalidCloudKey(c) {
|
|
46
|
+
return c.json({
|
|
47
|
+
error: 'Invalid or revoked API key',
|
|
48
|
+
hint: 'This cloud API key is no longer valid. Generate a new key in the dashboard.',
|
|
49
|
+
status: 401,
|
|
50
|
+
}, 401);
|
|
51
|
+
}
|
|
52
|
+
export function authRequired(c) {
|
|
53
|
+
return c.json({
|
|
54
|
+
error: 'Authentication required',
|
|
55
|
+
hint: 'No auth context found. This is likely a middleware ordering issue.',
|
|
56
|
+
status: 401,
|
|
57
|
+
}, 401);
|
|
58
|
+
}
|
|
59
|
+
export function otlpAuthRequired(c) {
|
|
60
|
+
return c.json({
|
|
61
|
+
error: 'Authentication required',
|
|
62
|
+
hint: "OTLP authentication is enabled. Provide a token via 'Authorization: Bearer <token>' header.",
|
|
63
|
+
docs: '/docs/otlp-auth',
|
|
64
|
+
status: 401,
|
|
65
|
+
}, 401);
|
|
66
|
+
}
|
|
67
|
+
export function otlpInvalidToken(c) {
|
|
68
|
+
return c.json({
|
|
69
|
+
error: 'Invalid OTLP token',
|
|
70
|
+
hint: 'The provided OTLP auth token does not match. Check your OTLP_AUTH_TOKEN configuration.',
|
|
71
|
+
status: 401,
|
|
72
|
+
}, 401);
|
|
73
|
+
}
|
|
74
|
+
// ── 403 Responses ──────────────────────────────────────────
|
|
75
|
+
export function insufficientPermissions(c, opts) {
|
|
76
|
+
return c.json({
|
|
77
|
+
error: 'Insufficient permissions',
|
|
78
|
+
hint: opts.hint ?? `This action requires '${opts.required}' role or higher. Your current role is '${opts.current}'.`,
|
|
79
|
+
required: opts.required,
|
|
80
|
+
current: opts.current,
|
|
81
|
+
status: 403,
|
|
82
|
+
}, 403);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=auth-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-errors.js","sourceRoot":"","sources":["../../src/middleware/auth-errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,8DAA8D;AAE9D,MAAM,UAAU,kBAAkB,CAAC,CAAU;IAC3C,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,0FAA0F;QAChG,IAAI,EAAE,sBAAsB;QAC5B,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,4BAA4B;QACnC,IAAI,EAAE,mEAAmE;QACzE,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,iBAAiB;QACxB,IAAI,EAAE,+EAA+E;QACrF,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,eAAe;QACtB,IAAI,EAAE,2EAA2E;QACjF,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,eAAe;QACtB,IAAI,EAAE,8DAA8D;QACpE,IAAI,EAAE,sBAAsB;QAC5B,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,4BAA4B;QACnC,IAAI,EAAE,6EAA6E;QACnF,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,oEAAoE;QAC1E,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,yBAAyB;QAChC,IAAI,EAAE,6FAA6F;QACnG,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,oBAAoB;QAC3B,IAAI,EAAE,wFAAwF;QAC9F,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC;AAED,8DAA8D;AAE9D,MAAM,UAAU,uBAAuB,CAAC,CAAU,EAAE,IAInD;IACC,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,KAAK,EAAE,0BAA0B;QACjC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,yBAAyB,IAAI,CAAC,QAAQ,2CAA2C,IAAI,CAAC,OAAO,IAAI;QACpH,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,GAAG;KACZ,EAAE,GAAG,CAAC,CAAC;AACV,CAAC"}
|
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
* with SHA-256 and looking it up in the apiKeys table.
|
|
6
6
|
*
|
|
7
7
|
* When AUTH_DISABLED=true, authentication is skipped (dev mode).
|
|
8
|
+
*
|
|
9
|
+
* Supports both SQLite (sync) and PostgreSQL (async) backends via IApiKeyLookup.
|
|
8
10
|
*/
|
|
9
11
|
import type { SqliteDb } from '../db/index.js';
|
|
12
|
+
import type { IApiKeyLookup } from '../db/api-key-lookup.js';
|
|
10
13
|
/**
|
|
11
14
|
* API key info attached to the Hono context.
|
|
12
15
|
*/
|
|
@@ -29,10 +32,10 @@ export declare function hashApiKey(raw: string): string;
|
|
|
29
32
|
/**
|
|
30
33
|
* Create the auth middleware.
|
|
31
34
|
*
|
|
32
|
-
* @param
|
|
35
|
+
* @param dbOrLookup - Drizzle SQLite database instance OR IApiKeyLookup
|
|
33
36
|
* @param authDisabled - If true, skip authentication (dev mode)
|
|
34
37
|
*/
|
|
35
|
-
export declare function authMiddleware(
|
|
38
|
+
export declare function authMiddleware(dbOrLookup: SqliteDb | IApiKeyLookup, authDisabled: boolean): import("hono").MiddlewareHandler<{
|
|
36
39
|
Variables: AuthVariables;
|
|
37
40
|
}, string, {}, Response>;
|
|
38
41
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,QAAQ,GAAG,aAAa,EAAE,YAAY,EAAE,OAAO;eACnD,aAAa;yBAgFnD"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* with SHA-256 and looking it up in the apiKeys table.
|
|
6
6
|
*
|
|
7
7
|
* When AUTH_DISABLED=true, authentication is skipped (dev mode).
|
|
8
|
+
*
|
|
9
|
+
* Supports both SQLite (sync) and PostgreSQL (async) backends via IApiKeyLookup.
|
|
8
10
|
*/
|
|
9
11
|
import { createHash } from 'node:crypto';
|
|
10
12
|
import { createMiddleware } from 'hono/factory';
|
|
@@ -19,10 +21,10 @@ export function hashApiKey(raw) {
|
|
|
19
21
|
/**
|
|
20
22
|
* Create the auth middleware.
|
|
21
23
|
*
|
|
22
|
-
* @param
|
|
24
|
+
* @param dbOrLookup - Drizzle SQLite database instance OR IApiKeyLookup
|
|
23
25
|
* @param authDisabled - If true, skip authentication (dev mode)
|
|
24
26
|
*/
|
|
25
|
-
export function authMiddleware(
|
|
27
|
+
export function authMiddleware(dbOrLookup, authDisabled) {
|
|
26
28
|
return createMiddleware(async (c, next) => {
|
|
27
29
|
// Dev mode: skip auth
|
|
28
30
|
if (authDisabled) {
|
|
@@ -39,7 +41,37 @@ export function authMiddleware(db, authDisabled) {
|
|
|
39
41
|
}
|
|
40
42
|
const rawKey = match[1];
|
|
41
43
|
const keyHash = hashApiKey(rawKey);
|
|
42
|
-
//
|
|
44
|
+
// Determine if we have an IApiKeyLookup or a raw SQLite db
|
|
45
|
+
if ('findByHash' in dbOrLookup) {
|
|
46
|
+
// IApiKeyLookup path (works for both SQLite and PostgreSQL)
|
|
47
|
+
const lookup = dbOrLookup;
|
|
48
|
+
const row = await lookup.findByHash(keyHash);
|
|
49
|
+
if (!row) {
|
|
50
|
+
return c.json({ error: 'Invalid or revoked API key', status: 401 }, 401);
|
|
51
|
+
}
|
|
52
|
+
if (row.expiresAt) {
|
|
53
|
+
const now = Math.floor(Date.now() / 1000);
|
|
54
|
+
if (now > row.expiresAt) {
|
|
55
|
+
return c.json({ error: 'This API key has been rotated and is no longer valid. Please use the new key.', status: 401 }, 401);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Fire-and-forget lastUsedAt update
|
|
59
|
+
void lookup.updateLastUsed(row.id);
|
|
60
|
+
const scopes = (() => {
|
|
61
|
+
if (Array.isArray(row.scopes))
|
|
62
|
+
return row.scopes;
|
|
63
|
+
try {
|
|
64
|
+
return JSON.parse(row.scopes);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
})();
|
|
70
|
+
c.set('apiKey', { id: row.id, name: row.name, scopes, tenantId: row.tenantId });
|
|
71
|
+
return next();
|
|
72
|
+
}
|
|
73
|
+
// Legacy SQLite db path (backward compatible)
|
|
74
|
+
const db = dbOrLookup;
|
|
43
75
|
const row = db
|
|
44
76
|
.select()
|
|
45
77
|
.from(apiKeys)
|
|
@@ -48,17 +80,17 @@ export function authMiddleware(db, authDisabled) {
|
|
|
48
80
|
if (!row) {
|
|
49
81
|
return c.json({ error: 'Invalid or revoked API key', status: 401 }, 401);
|
|
50
82
|
}
|
|
51
|
-
|
|
83
|
+
if (row.expiresAt) {
|
|
84
|
+
const now = Math.floor(Date.now() / 1000);
|
|
85
|
+
if (now > row.expiresAt) {
|
|
86
|
+
return c.json({ error: 'This API key has been rotated and is no longer valid. Please use the new key.', status: 401 }, 401);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
52
89
|
const now = Math.floor(Date.now() / 1000);
|
|
53
90
|
try {
|
|
54
|
-
db.update(apiKeys)
|
|
55
|
-
.set({ lastUsedAt: now })
|
|
56
|
-
.where(eq(apiKeys.id, row.id))
|
|
57
|
-
.run();
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Non-critical — don't fail the request
|
|
91
|
+
db.update(apiKeys).set({ lastUsedAt: now }).where(eq(apiKeys.id, row.id)).run();
|
|
61
92
|
}
|
|
93
|
+
catch { /* non-critical */ }
|
|
62
94
|
const scopes = (() => {
|
|
63
95
|
try {
|
|
64
96
|
return JSON.parse(row.scopes);
|
|
@@ -67,12 +99,7 @@ export function authMiddleware(db, authDisabled) {
|
|
|
67
99
|
return [];
|
|
68
100
|
}
|
|
69
101
|
})();
|
|
70
|
-
c.set('apiKey', {
|
|
71
|
-
id: row.id,
|
|
72
|
-
name: row.name,
|
|
73
|
-
scopes,
|
|
74
|
-
tenantId: row.tenantId,
|
|
75
|
-
});
|
|
102
|
+
c.set('apiKey', { id: row.id, name: row.name, scopes, tenantId: row.tenantId });
|
|
76
103
|
return next();
|
|
77
104
|
});
|
|
78
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SH-3: Global Body Limit Middleware
|
|
3
|
+
*
|
|
4
|
+
* Applies a 1MB default body size limit to all API routes.
|
|
5
|
+
* Individual routes can override with their own bodyLimit (e.g., events uses 10MB).
|
|
6
|
+
*/
|
|
7
|
+
/** 1MB default body limit for API routes */
|
|
8
|
+
export declare const apiBodyLimit: import("hono").MiddlewareHandler;
|
|
9
|
+
//# sourceMappingURL=body-limit.d.ts.map
|