guardrail-core 1.0.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/dist/__tests__/autopilot.test.d.ts +7 -0
- package/dist/__tests__/autopilot.test.d.ts.map +1 -0
- package/dist/__tests__/autopilot.test.js +156 -0
- package/dist/__tests__/tier-config.test.d.ts +9 -0
- package/dist/__tests__/tier-config.test.d.ts.map +1 -0
- package/dist/__tests__/tier-config.test.js +230 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts +2 -0
- package/dist/__tests__/utils/hash-inline.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash-inline.test.js +62 -0
- package/dist/__tests__/utils/hash.test.d.ts +3 -0
- package/dist/__tests__/utils/hash.test.d.ts.map +1 -0
- package/dist/__tests__/utils/hash.test.js +95 -0
- package/dist/__tests__/utils/simple.test.d.ts +1 -0
- package/dist/__tests__/utils/simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/simple.test.js +10 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts +1 -0
- package/dist/__tests__/utils/utils-simple.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils-simple.test.js +6 -0
- package/dist/__tests__/utils/utils.test.d.ts +15 -0
- package/dist/__tests__/utils/utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/utils.test.js +172 -0
- package/dist/autopilot/autopilot-runner.d.ts +33 -0
- package/dist/autopilot/autopilot-runner.d.ts.map +1 -0
- package/dist/autopilot/autopilot-runner.js +479 -0
- package/dist/autopilot/index.d.ts +6 -0
- package/dist/autopilot/index.d.ts.map +1 -0
- package/dist/autopilot/index.js +25 -0
- package/dist/autopilot/types.d.ts +102 -0
- package/dist/autopilot/types.d.ts.map +1 -0
- package/dist/autopilot/types.js +18 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +22 -0
- package/dist/cache/redis-cache.d.ts +145 -0
- package/dist/cache/redis-cache.d.ts.map +1 -0
- package/dist/cache/redis-cache.js +459 -0
- package/dist/ci/github-actions.d.ts +77 -0
- package/dist/ci/github-actions.d.ts.map +1 -0
- package/dist/ci/github-actions.js +277 -0
- package/dist/ci/index.d.ts +12 -0
- package/dist/ci/index.d.ts.map +1 -0
- package/dist/ci/index.js +27 -0
- package/dist/ci/pre-commit.d.ts +65 -0
- package/dist/ci/pre-commit.d.ts.map +1 -0
- package/dist/ci/pre-commit.js +286 -0
- package/dist/entitlements.d.ts +149 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +464 -0
- package/dist/env.d.ts +113 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +204 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts +7 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.d.ts.map +1 -0
- package/dist/fix-packs/__tests__/generate-fix-packs.test.js +250 -0
- package/dist/fix-packs/generate-fix-packs.d.ts +15 -0
- package/dist/fix-packs/generate-fix-packs.d.ts.map +1 -0
- package/dist/fix-packs/generate-fix-packs.js +505 -0
- package/dist/fix-packs/index.d.ts +8 -0
- package/dist/fix-packs/index.d.ts.map +1 -0
- package/dist/fix-packs/index.js +23 -0
- package/dist/fix-packs/types.d.ts +113 -0
- package/dist/fix-packs/types.d.ts.map +1 -0
- package/dist/fix-packs/types.js +71 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/metrics/prometheus.d.ts +99 -0
- package/dist/metrics/prometheus.d.ts.map +1 -0
- package/dist/metrics/prometheus.js +306 -0
- package/dist/quota-ledger.d.ts +119 -0
- package/dist/quota-ledger.d.ts.map +1 -0
- package/dist/quota-ledger.js +462 -0
- package/dist/rbac/__tests__/permissions.test.d.ts +8 -0
- package/dist/rbac/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/rbac/__tests__/permissions.test.js +350 -0
- package/dist/rbac/index.d.ts +9 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +32 -0
- package/dist/rbac/permissions.d.ts +71 -0
- package/dist/rbac/permissions.d.ts.map +1 -0
- package/dist/rbac/permissions.js +247 -0
- package/dist/rbac/types.d.ts +69 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +213 -0
- package/dist/tier-config.d.ts +203 -0
- package/dist/tier-config.d.ts.map +1 -0
- package/dist/tier-config.js +675 -0
- package/dist/types.d.ts +365 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/utils.d.ts +36 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +127 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/format-validator.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/format-validator.test.js +285 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/pipeline.test.js +389 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/repo-fingerprint.test.js +236 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts +11 -0
- package/dist/verified-autofix/__tests__/workspace.test.d.ts.map +1 -0
- package/dist/verified-autofix/__tests__/workspace.test.js +314 -0
- package/dist/verified-autofix/format-validator.d.ts +101 -0
- package/dist/verified-autofix/format-validator.d.ts.map +1 -0
- package/dist/verified-autofix/format-validator.js +446 -0
- package/dist/verified-autofix/index.d.ts +14 -0
- package/dist/verified-autofix/index.d.ts.map +1 -0
- package/dist/verified-autofix/index.js +39 -0
- package/dist/verified-autofix/pipeline.d.ts +68 -0
- package/dist/verified-autofix/pipeline.d.ts.map +1 -0
- package/dist/verified-autofix/pipeline.js +330 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts +56 -0
- package/dist/verified-autofix/repo-fingerprint.d.ts.map +1 -0
- package/dist/verified-autofix/repo-fingerprint.js +396 -0
- package/dist/verified-autofix/workspace.d.ts +83 -0
- package/dist/verified-autofix/workspace.d.ts.map +1 -0
- package/dist/verified-autofix/workspace.js +454 -0
- package/dist/verified-autofix.d.ts +182 -0
- package/dist/verified-autofix.d.ts.map +1 -0
- package/dist/verified-autofix.js +1021 -0
- package/dist/visualization/dependency-graph.d.ts +79 -0
- package/dist/visualization/dependency-graph.d.ts.map +1 -0
- package/dist/visualization/dependency-graph.js +399 -0
- package/dist/visualization/index.d.ts +5 -0
- package/dist/visualization/index.d.ts.map +1 -0
- package/dist/visualization/index.js +20 -0
- package/package.json +29 -0
- package/src/__tests__/autopilot.test.ts +196 -0
- package/src/__tests__/tier-config.test.ts +289 -0
- package/src/__tests__/utils/hash-inline.test.ts +76 -0
- package/src/__tests__/utils/hash.test.ts +119 -0
- package/src/__tests__/utils/simple.test.ts +10 -0
- package/src/__tests__/utils/utils-simple.test.ts +5 -0
- package/src/__tests__/utils/utils.test.ts +203 -0
- package/src/autopilot/autopilot-runner.ts +503 -0
- package/src/autopilot/index.ts +6 -0
- package/src/autopilot/types.ts +119 -0
- package/src/cache/index.ts +7 -0
- package/src/cache/redis-cache.d.ts +155 -0
- package/src/cache/redis-cache.d.ts.map +1 -0
- package/src/cache/redis-cache.ts +517 -0
- package/src/ci/github-actions.ts +335 -0
- package/src/ci/index.ts +12 -0
- package/src/ci/pre-commit.ts +338 -0
- package/src/db/usage-schema.prisma +114 -0
- package/src/entitlements.ts +570 -0
- package/src/env.d.ts +68 -0
- package/src/env.d.ts.map +1 -0
- package/src/env.ts +247 -0
- package/src/fix-packs/__tests__/generate-fix-packs.test.ts +317 -0
- package/src/fix-packs/generate-fix-packs.ts +577 -0
- package/src/fix-packs/index.ts +8 -0
- package/src/fix-packs/types.ts +206 -0
- package/src/index.d.ts +7 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.ts +12 -0
- package/src/metrics/prometheus.d.ts +104 -0
- package/src/metrics/prometheus.d.ts.map +1 -0
- package/src/metrics/prometheus.ts +446 -0
- package/src/quota-ledger.ts +548 -0
- package/src/rbac/__tests__/permissions.test.ts +446 -0
- package/src/rbac/index.ts +46 -0
- package/src/rbac/permissions.ts +301 -0
- package/src/rbac/types.ts +298 -0
- package/src/tier-config.json +157 -0
- package/src/tier-config.ts +815 -0
- package/src/types.d.ts +365 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.ts +441 -0
- package/src/utils.d.ts +36 -0
- package/src/utils.d.ts.map +1 -0
- package/src/utils.ts +140 -0
- package/src/verified-autofix/__tests__/format-validator.test.ts +335 -0
- package/src/verified-autofix/__tests__/pipeline.test.ts +419 -0
- package/src/verified-autofix/__tests__/repo-fingerprint.test.ts +241 -0
- package/src/verified-autofix/__tests__/workspace.test.ts +373 -0
- package/src/verified-autofix/format-validator.ts +517 -0
- package/src/verified-autofix/index.ts +63 -0
- package/src/verified-autofix/pipeline.ts +403 -0
- package/src/verified-autofix/repo-fingerprint.ts +459 -0
- package/src/verified-autofix/workspace.ts +531 -0
- package/src/verified-autofix.ts +1187 -0
- package/src/visualization/dependency-graph.d.ts +85 -0
- package/src/visualization/dependency-graph.d.ts.map +1 -0
- package/src/visualization/dependency-graph.ts +495 -0
- package/src/visualization/index.ts +5 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fix Packs Types
|
|
4
|
+
*
|
|
5
|
+
* First-class objects that group findings into actionable batches.
|
|
6
|
+
* Used by CLI, Autopilot, and Verified AutoFix.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FIX_STRATEGIES = exports.SEVERITY_ORDER = exports.SEVERITY_LEVELS = exports.FINDING_CATEGORIES = void 0;
|
|
10
|
+
exports.compareSeverity = compareSeverity;
|
|
11
|
+
exports.isHigherSeverity = isHigherSeverity;
|
|
12
|
+
exports.getHighestSeverity = getHighestSeverity;
|
|
13
|
+
exports.generatePackId = generatePackId;
|
|
14
|
+
exports.sortPacksBySeverity = sortPacksBySeverity;
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// FINDING CATEGORY ENUM
|
|
17
|
+
// ============================================================================
|
|
18
|
+
exports.FINDING_CATEGORIES = [
|
|
19
|
+
'secrets',
|
|
20
|
+
'routes',
|
|
21
|
+
'mocks',
|
|
22
|
+
'auth',
|
|
23
|
+
'placeholders',
|
|
24
|
+
'deps',
|
|
25
|
+
'types',
|
|
26
|
+
'tests',
|
|
27
|
+
'security',
|
|
28
|
+
'performance',
|
|
29
|
+
];
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// SEVERITY LEVELS
|
|
32
|
+
// ============================================================================
|
|
33
|
+
exports.SEVERITY_LEVELS = ['critical', 'high', 'medium', 'low', 'info'];
|
|
34
|
+
exports.SEVERITY_ORDER = {
|
|
35
|
+
critical: 0,
|
|
36
|
+
high: 1,
|
|
37
|
+
medium: 2,
|
|
38
|
+
low: 3,
|
|
39
|
+
info: 4,
|
|
40
|
+
};
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// FIX STRATEGY
|
|
43
|
+
// ============================================================================
|
|
44
|
+
exports.FIX_STRATEGIES = [
|
|
45
|
+
'auto', // Fully automated fix
|
|
46
|
+
'guided', // AI-guided with human review
|
|
47
|
+
'manual', // Requires manual intervention
|
|
48
|
+
'ai-assisted', // AI generates suggestions
|
|
49
|
+
];
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// HELPER FUNCTIONS
|
|
52
|
+
// ============================================================================
|
|
53
|
+
function compareSeverity(a, b) {
|
|
54
|
+
return exports.SEVERITY_ORDER[a] - exports.SEVERITY_ORDER[b];
|
|
55
|
+
}
|
|
56
|
+
function isHigherSeverity(a, b) {
|
|
57
|
+
return compareSeverity(a, b) < 0;
|
|
58
|
+
}
|
|
59
|
+
function getHighestSeverity(severities) {
|
|
60
|
+
if (severities.length === 0)
|
|
61
|
+
return 'info';
|
|
62
|
+
return severities.reduce((highest, current) => isHigherSeverity(current, highest) ? current : highest);
|
|
63
|
+
}
|
|
64
|
+
function generatePackId(category, index, hash) {
|
|
65
|
+
const categoryPrefix = category.slice(0, 3).toUpperCase();
|
|
66
|
+
const hashSuffix = hash.slice(0, 6);
|
|
67
|
+
return `FP-${categoryPrefix}-${String(index).padStart(3, '0')}-${hashSuffix}`;
|
|
68
|
+
}
|
|
69
|
+
function sortPacksBySeverity(packs) {
|
|
70
|
+
return [...packs].sort((a, b) => compareSeverity(a.severity, b.severity));
|
|
71
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./cache/redis-cache";
|
|
2
|
+
export * from "./entitlements";
|
|
3
|
+
export * from "./env";
|
|
4
|
+
export * from "./fix-packs";
|
|
5
|
+
export * from "./metrics/prometheus";
|
|
6
|
+
export * from "./rbac";
|
|
7
|
+
export * from "./tier-config";
|
|
8
|
+
export * from "./types";
|
|
9
|
+
export * from "./utils";
|
|
10
|
+
export * from "./visualization/dependency-graph";
|
|
11
|
+
export * from "./autopilot";
|
|
12
|
+
export * from "./verified-autofix";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,OAAO,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,kCAAkC,CAAC;AACjD,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./cache/redis-cache"), exports);
|
|
18
|
+
__exportStar(require("./entitlements"), exports);
|
|
19
|
+
__exportStar(require("./env"), exports);
|
|
20
|
+
__exportStar(require("./fix-packs"), exports);
|
|
21
|
+
__exportStar(require("./metrics/prometheus"), exports);
|
|
22
|
+
__exportStar(require("./rbac"), exports);
|
|
23
|
+
__exportStar(require("./tier-config"), exports);
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
__exportStar(require("./utils"), exports);
|
|
26
|
+
__exportStar(require("./visualization/dependency-graph"), exports);
|
|
27
|
+
__exportStar(require("./autopilot"), exports);
|
|
28
|
+
__exportStar(require("./verified-autofix"), exports);
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus Metrics
|
|
3
|
+
*
|
|
4
|
+
* Production-ready metrics collection for Guardrail AI
|
|
5
|
+
* Exposes metrics in Prometheus format for monitoring and alerting
|
|
6
|
+
*/
|
|
7
|
+
export interface MetricLabels {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
}
|
|
10
|
+
export interface MetricValue {
|
|
11
|
+
value: number;
|
|
12
|
+
labels: MetricLabels;
|
|
13
|
+
timestamp?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface Metric {
|
|
16
|
+
name: string;
|
|
17
|
+
help: string;
|
|
18
|
+
type: "counter" | "gauge" | "histogram" | "summary";
|
|
19
|
+
values: MetricValue[];
|
|
20
|
+
}
|
|
21
|
+
declare class Counter {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly help: string;
|
|
24
|
+
readonly labelNames: string[];
|
|
25
|
+
private values;
|
|
26
|
+
constructor(name: string, help: string, labelNames?: string[]);
|
|
27
|
+
inc(labels?: MetricLabels, value?: number): void;
|
|
28
|
+
get(labels?: MetricLabels): number;
|
|
29
|
+
reset(): void;
|
|
30
|
+
collect(): MetricValue[];
|
|
31
|
+
private labelsToKey;
|
|
32
|
+
private keyToLabels;
|
|
33
|
+
}
|
|
34
|
+
declare class Gauge {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly help: string;
|
|
37
|
+
readonly labelNames: string[];
|
|
38
|
+
private values;
|
|
39
|
+
constructor(name: string, help: string, labelNames?: string[]);
|
|
40
|
+
set(labels: MetricLabels, value: number): void;
|
|
41
|
+
set(value: number): void;
|
|
42
|
+
inc(labels?: MetricLabels, value?: number): void;
|
|
43
|
+
dec(labels?: MetricLabels, value?: number): void;
|
|
44
|
+
get(labels?: MetricLabels): number;
|
|
45
|
+
collect(): MetricValue[];
|
|
46
|
+
private labelsToKey;
|
|
47
|
+
private keyToLabels;
|
|
48
|
+
}
|
|
49
|
+
declare class Histogram {
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly help: string;
|
|
52
|
+
readonly labelNames: string[];
|
|
53
|
+
private buckets;
|
|
54
|
+
private values;
|
|
55
|
+
constructor(name: string, help: string, labelNames?: string[], buckets?: number[]);
|
|
56
|
+
observe(labels: MetricLabels, value: number): void;
|
|
57
|
+
observe(value: number): void;
|
|
58
|
+
startTimer(labels?: MetricLabels): () => number;
|
|
59
|
+
collect(): MetricValue[];
|
|
60
|
+
private labelsToKey;
|
|
61
|
+
private keyToLabels;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Guardrail Metrics Registry
|
|
65
|
+
*/
|
|
66
|
+
declare class MetricsRegistry {
|
|
67
|
+
readonly scansTotal: Counter;
|
|
68
|
+
readonly scanDuration: Histogram;
|
|
69
|
+
readonly injectionsDetected: Counter;
|
|
70
|
+
readonly injectionScanDuration: Histogram;
|
|
71
|
+
readonly vulnerabilitiesFound: Counter;
|
|
72
|
+
readonly vulnerablePackages: Gauge;
|
|
73
|
+
readonly secretsDetected: Counter;
|
|
74
|
+
readonly complianceScore: Gauge;
|
|
75
|
+
readonly complianceViolations: Counter;
|
|
76
|
+
readonly apiRequestsTotal: Counter;
|
|
77
|
+
readonly apiRequestDuration: Histogram;
|
|
78
|
+
readonly agentActionsTotal: Counter;
|
|
79
|
+
readonly agentActionsBlocked: Counter;
|
|
80
|
+
readonly cacheHits: Counter;
|
|
81
|
+
readonly cacheMisses: Counter;
|
|
82
|
+
readonly activeConnections: Gauge;
|
|
83
|
+
readonly memoryUsageBytes: Gauge;
|
|
84
|
+
/**
|
|
85
|
+
* Generate Prometheus-formatted output
|
|
86
|
+
*/
|
|
87
|
+
generatePrometheusOutput(): string;
|
|
88
|
+
/**
|
|
89
|
+
* Update system metrics
|
|
90
|
+
*/
|
|
91
|
+
updateSystemMetrics(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Reset all metrics (for testing)
|
|
94
|
+
*/
|
|
95
|
+
resetAll(): void;
|
|
96
|
+
}
|
|
97
|
+
export declare const metrics: MetricsRegistry;
|
|
98
|
+
export { Counter, Gauge, Histogram };
|
|
99
|
+
//# sourceMappingURL=prometheus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prometheus.d.ts","sourceRoot":"","sources":["../../src/metrics/prometheus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Prometheus Metrics
|
|
4
|
+
*
|
|
5
|
+
* Production-ready metrics collection for Guardrail AI
|
|
6
|
+
* Exposes metrics in Prometheus format for monitoring and alerting
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.Histogram = exports.Gauge = exports.Counter = exports.metrics = void 0;
|
|
10
|
+
class Counter {
|
|
11
|
+
name;
|
|
12
|
+
help;
|
|
13
|
+
labelNames;
|
|
14
|
+
values = new Map();
|
|
15
|
+
constructor(name, help, labelNames = []) {
|
|
16
|
+
this.name = name;
|
|
17
|
+
this.help = help;
|
|
18
|
+
this.labelNames = labelNames;
|
|
19
|
+
}
|
|
20
|
+
inc(labels = {}, value = 1) {
|
|
21
|
+
const key = this.labelsToKey(labels);
|
|
22
|
+
const current = this.values.get(key) || 0;
|
|
23
|
+
this.values.set(key, current + value);
|
|
24
|
+
}
|
|
25
|
+
get(labels = {}) {
|
|
26
|
+
const key = this.labelsToKey(labels);
|
|
27
|
+
return this.values.get(key) || 0;
|
|
28
|
+
}
|
|
29
|
+
reset() {
|
|
30
|
+
this.values.clear();
|
|
31
|
+
}
|
|
32
|
+
collect() {
|
|
33
|
+
const result = [];
|
|
34
|
+
for (const [key, value] of this.values) {
|
|
35
|
+
result.push({
|
|
36
|
+
value,
|
|
37
|
+
labels: this.keyToLabels(key),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
labelsToKey(labels) {
|
|
43
|
+
return this.labelNames.map((name) => labels[name] || "").join("|");
|
|
44
|
+
}
|
|
45
|
+
keyToLabels(key) {
|
|
46
|
+
const values = key.split("|");
|
|
47
|
+
const labels = {};
|
|
48
|
+
this.labelNames.forEach((name, i) => {
|
|
49
|
+
if (values[i]) {
|
|
50
|
+
labels[name] = values[i];
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return labels;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.Counter = Counter;
|
|
57
|
+
class Gauge {
|
|
58
|
+
name;
|
|
59
|
+
help;
|
|
60
|
+
labelNames;
|
|
61
|
+
values = new Map();
|
|
62
|
+
constructor(name, help, labelNames = []) {
|
|
63
|
+
this.name = name;
|
|
64
|
+
this.help = help;
|
|
65
|
+
this.labelNames = labelNames;
|
|
66
|
+
}
|
|
67
|
+
set(labelsOrValue, value) {
|
|
68
|
+
if (typeof labelsOrValue === "number") {
|
|
69
|
+
this.values.set("", labelsOrValue);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const key = this.labelsToKey(labelsOrValue);
|
|
73
|
+
this.values.set(key, value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
inc(labels = {}, value = 1) {
|
|
77
|
+
const key = this.labelsToKey(labels);
|
|
78
|
+
const current = this.values.get(key) || 0;
|
|
79
|
+
this.values.set(key, current + value);
|
|
80
|
+
}
|
|
81
|
+
dec(labels = {}, value = 1) {
|
|
82
|
+
const key = this.labelsToKey(labels);
|
|
83
|
+
const current = this.values.get(key) || 0;
|
|
84
|
+
this.values.set(key, current - value);
|
|
85
|
+
}
|
|
86
|
+
get(labels = {}) {
|
|
87
|
+
const key = this.labelsToKey(labels);
|
|
88
|
+
return this.values.get(key) || 0;
|
|
89
|
+
}
|
|
90
|
+
collect() {
|
|
91
|
+
const result = [];
|
|
92
|
+
for (const [key, value] of this.values) {
|
|
93
|
+
result.push({
|
|
94
|
+
value,
|
|
95
|
+
labels: this.keyToLabels(key),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
labelsToKey(labels) {
|
|
101
|
+
return this.labelNames.map((name) => labels[name] || "").join("|");
|
|
102
|
+
}
|
|
103
|
+
keyToLabels(key) {
|
|
104
|
+
const values = key.split("|");
|
|
105
|
+
const labels = {};
|
|
106
|
+
this.labelNames.forEach((name, i) => {
|
|
107
|
+
if (values[i]) {
|
|
108
|
+
labels[name] = values[i];
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return labels;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.Gauge = Gauge;
|
|
115
|
+
class Histogram {
|
|
116
|
+
name;
|
|
117
|
+
help;
|
|
118
|
+
labelNames;
|
|
119
|
+
buckets;
|
|
120
|
+
values = new Map();
|
|
121
|
+
constructor(name, help, labelNames = [], buckets) {
|
|
122
|
+
this.name = name;
|
|
123
|
+
this.help = help;
|
|
124
|
+
this.labelNames = labelNames;
|
|
125
|
+
this.buckets = buckets || [
|
|
126
|
+
0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
observe(labelsOrValue, value) {
|
|
130
|
+
let labels;
|
|
131
|
+
let observedValue;
|
|
132
|
+
if (typeof labelsOrValue === "number") {
|
|
133
|
+
labels = {};
|
|
134
|
+
observedValue = labelsOrValue;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
labels = labelsOrValue;
|
|
138
|
+
observedValue = value;
|
|
139
|
+
}
|
|
140
|
+
const key = this.labelsToKey(labels);
|
|
141
|
+
let data = this.values.get(key);
|
|
142
|
+
if (!data) {
|
|
143
|
+
data = {
|
|
144
|
+
sum: 0,
|
|
145
|
+
count: 0,
|
|
146
|
+
buckets: new Array(this.buckets.length).fill(0),
|
|
147
|
+
};
|
|
148
|
+
this.values.set(key, data);
|
|
149
|
+
}
|
|
150
|
+
data.sum += observedValue;
|
|
151
|
+
data.count++;
|
|
152
|
+
for (let i = 0; i < this.buckets.length; i++) {
|
|
153
|
+
const bucket = this.buckets[i];
|
|
154
|
+
if (bucket !== undefined && observedValue <= bucket) {
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
data.buckets[i]++;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
startTimer(labels = {}) {
|
|
161
|
+
const start = process.hrtime.bigint();
|
|
162
|
+
return () => {
|
|
163
|
+
const end = process.hrtime.bigint();
|
|
164
|
+
const durationMs = Number(end - start) / 1e6;
|
|
165
|
+
this.observe(labels, durationMs / 1000); // Convert to seconds
|
|
166
|
+
return durationMs;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
collect() {
|
|
170
|
+
const result = [];
|
|
171
|
+
for (const [key, data] of this.values) {
|
|
172
|
+
const labels = this.keyToLabels(key);
|
|
173
|
+
// Add bucket values
|
|
174
|
+
for (let i = 0; i < this.buckets.length; i++) {
|
|
175
|
+
const bucketValue = data.buckets[i] ?? 0;
|
|
176
|
+
const bucketLimit = this.buckets[i] ?? 0;
|
|
177
|
+
result.push({
|
|
178
|
+
value: bucketValue,
|
|
179
|
+
labels: { ...labels, le: String(bucketLimit) },
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// Add +Inf bucket
|
|
183
|
+
result.push({
|
|
184
|
+
value: data.count,
|
|
185
|
+
labels: { ...labels, le: "+Inf" },
|
|
186
|
+
});
|
|
187
|
+
// Add sum and count
|
|
188
|
+
result.push({
|
|
189
|
+
value: data.sum,
|
|
190
|
+
labels: { ...labels, quantile: "sum" },
|
|
191
|
+
});
|
|
192
|
+
result.push({
|
|
193
|
+
value: data.count,
|
|
194
|
+
labels: { ...labels, quantile: "count" },
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
labelsToKey(labels) {
|
|
200
|
+
return this.labelNames.map((name) => labels[name] || "").join("|");
|
|
201
|
+
}
|
|
202
|
+
keyToLabels(key) {
|
|
203
|
+
const values = key.split("|");
|
|
204
|
+
const labels = {};
|
|
205
|
+
this.labelNames.forEach((name, i) => {
|
|
206
|
+
if (values[i]) {
|
|
207
|
+
labels[name] = values[i];
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
return labels;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
exports.Histogram = Histogram;
|
|
214
|
+
/**
|
|
215
|
+
* Guardrail Metrics Registry
|
|
216
|
+
*/
|
|
217
|
+
class MetricsRegistry {
|
|
218
|
+
// Scan metrics
|
|
219
|
+
scansTotal = new Counter("Guardrail_scans_total", "Total number of security scans performed", ["scan_type", "status"]);
|
|
220
|
+
scanDuration = new Histogram("Guardrail_scan_duration_seconds", "Duration of security scans in seconds", ["scan_type"], [0.1, 0.5, 1, 2, 5, 10, 30, 60]);
|
|
221
|
+
// Injection detection metrics
|
|
222
|
+
injectionsDetected = new Counter("Guardrail_injections_detected_total", "Total number of prompt injection attempts detected", ["severity", "type"]);
|
|
223
|
+
injectionScanDuration = new Histogram("Guardrail_injection_scan_duration_seconds", "Duration of injection scans in seconds", ["content_type"]);
|
|
224
|
+
// Vulnerability metrics
|
|
225
|
+
vulnerabilitiesFound = new Counter("Guardrail_vulnerabilities_found_total", "Total number of vulnerabilities found", ["severity", "source"]);
|
|
226
|
+
vulnerablePackages = new Gauge("Guardrail_vulnerable_packages", "Current number of vulnerable packages", ["project_id"]);
|
|
227
|
+
// Secret detection metrics
|
|
228
|
+
secretsDetected = new Counter("Guardrail_secrets_detected_total", "Total number of secrets detected", ["secret_type", "severity"]);
|
|
229
|
+
// Compliance metrics
|
|
230
|
+
complianceScore = new Gauge("Guardrail_compliance_score", "Current compliance score (0-100)", ["framework", "project_id"]);
|
|
231
|
+
complianceViolations = new Counter("Guardrail_compliance_violations_total", "Total number of compliance violations", ["framework", "severity"]);
|
|
232
|
+
// API metrics
|
|
233
|
+
apiRequestsTotal = new Counter("Guardrail_api_requests_total", "Total number of API requests", ["method", "endpoint", "status_code"]);
|
|
234
|
+
apiRequestDuration = new Histogram("Guardrail_api_request_duration_seconds", "Duration of API requests in seconds", ["method", "endpoint"]);
|
|
235
|
+
// Agent metrics
|
|
236
|
+
agentActionsTotal = new Counter("Guardrail_agent_actions_total", "Total number of agent actions", ["agent_id", "action_type", "status"]);
|
|
237
|
+
agentActionsBlocked = new Counter("Guardrail_agent_actions_blocked_total", "Total number of agent actions blocked", ["agent_id", "reason"]);
|
|
238
|
+
// Cache metrics
|
|
239
|
+
cacheHits = new Counter("Guardrail_cache_hits_total", "Total number of cache hits", ["cache_type"]);
|
|
240
|
+
cacheMisses = new Counter("Guardrail_cache_misses_total", "Total number of cache misses", ["cache_type"]);
|
|
241
|
+
// System metrics
|
|
242
|
+
activeConnections = new Gauge("Guardrail_active_connections", "Number of active WebSocket connections", []);
|
|
243
|
+
memoryUsageBytes = new Gauge("Guardrail_memory_usage_bytes", "Current memory usage in bytes", ["type"]);
|
|
244
|
+
/**
|
|
245
|
+
* Generate Prometheus-formatted output
|
|
246
|
+
*/
|
|
247
|
+
generatePrometheusOutput() {
|
|
248
|
+
const lines = [];
|
|
249
|
+
const metrics = [
|
|
250
|
+
{ metric: this.scansTotal, type: "counter" },
|
|
251
|
+
{ metric: this.scanDuration, type: "histogram" },
|
|
252
|
+
{ metric: this.injectionsDetected, type: "counter" },
|
|
253
|
+
{ metric: this.injectionScanDuration, type: "histogram" },
|
|
254
|
+
{ metric: this.vulnerabilitiesFound, type: "counter" },
|
|
255
|
+
{ metric: this.vulnerablePackages, type: "gauge" },
|
|
256
|
+
{ metric: this.secretsDetected, type: "counter" },
|
|
257
|
+
{ metric: this.complianceScore, type: "gauge" },
|
|
258
|
+
{ metric: this.complianceViolations, type: "counter" },
|
|
259
|
+
{ metric: this.apiRequestsTotal, type: "counter" },
|
|
260
|
+
{ metric: this.apiRequestDuration, type: "histogram" },
|
|
261
|
+
{ metric: this.agentActionsTotal, type: "counter" },
|
|
262
|
+
{ metric: this.agentActionsBlocked, type: "counter" },
|
|
263
|
+
{ metric: this.cacheHits, type: "counter" },
|
|
264
|
+
{ metric: this.cacheMisses, type: "counter" },
|
|
265
|
+
{ metric: this.activeConnections, type: "gauge" },
|
|
266
|
+
{ metric: this.memoryUsageBytes, type: "gauge" },
|
|
267
|
+
];
|
|
268
|
+
for (const { metric, type } of metrics) {
|
|
269
|
+
lines.push(`# HELP ${metric.name} ${metric.help}`);
|
|
270
|
+
lines.push(`# TYPE ${metric.name} ${type}`);
|
|
271
|
+
const values = metric.collect();
|
|
272
|
+
for (const { value, labels } of values) {
|
|
273
|
+
const labelStr = Object.entries(labels)
|
|
274
|
+
.map(([k, v]) => `${k}="${v}"`)
|
|
275
|
+
.join(",");
|
|
276
|
+
if (labelStr) {
|
|
277
|
+
lines.push(`${metric.name}{${labelStr}} ${value}`);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
lines.push(`${metric.name} ${value}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
lines.push("");
|
|
284
|
+
}
|
|
285
|
+
return lines.join("\n");
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Update system metrics
|
|
289
|
+
*/
|
|
290
|
+
updateSystemMetrics() {
|
|
291
|
+
const memUsage = process.memoryUsage();
|
|
292
|
+
this.memoryUsageBytes.set({ type: "heap_used" }, memUsage.heapUsed);
|
|
293
|
+
this.memoryUsageBytes.set({ type: "heap_total" }, memUsage.heapTotal);
|
|
294
|
+
this.memoryUsageBytes.set({ type: "rss" }, memUsage.rss);
|
|
295
|
+
this.memoryUsageBytes.set({ type: "external" }, memUsage.external);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Reset all metrics (for testing)
|
|
299
|
+
*/
|
|
300
|
+
resetAll() {
|
|
301
|
+
this.scansTotal.reset();
|
|
302
|
+
// Add reset for other metrics as needed
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// Export singleton registry
|
|
306
|
+
exports.metrics = new MetricsRegistry();
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quota Ledger - Server-Authoritative Usage Tracking
|
|
3
|
+
*
|
|
4
|
+
* Implements idempotent usage recording with request IDs to prevent double-counting.
|
|
5
|
+
* All quota checks are validated server-side before allowing operations.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY: CLI cannot bypass quota checks by modifying local files.
|
|
8
|
+
* The server is the single source of truth for usage data.
|
|
9
|
+
*/
|
|
10
|
+
export type UsageActionType = 'scan' | 'scan_truth' | 'reality' | 'agent' | 'fix' | 'gate';
|
|
11
|
+
export interface UsageEntry {
|
|
12
|
+
id: string;
|
|
13
|
+
action: UsageActionType;
|
|
14
|
+
count: number;
|
|
15
|
+
timestamp: string;
|
|
16
|
+
synced: boolean;
|
|
17
|
+
projectId?: string;
|
|
18
|
+
metadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export interface QuotaLimits {
|
|
21
|
+
scans: number;
|
|
22
|
+
reality: number;
|
|
23
|
+
agent: number;
|
|
24
|
+
}
|
|
25
|
+
export interface UsageSummary {
|
|
26
|
+
tier: string;
|
|
27
|
+
period: {
|
|
28
|
+
start: string;
|
|
29
|
+
end: string;
|
|
30
|
+
};
|
|
31
|
+
usage: {
|
|
32
|
+
scans: number;
|
|
33
|
+
reality: number;
|
|
34
|
+
agent: number;
|
|
35
|
+
fix: number;
|
|
36
|
+
gate: number;
|
|
37
|
+
};
|
|
38
|
+
limits: QuotaLimits;
|
|
39
|
+
remaining: {
|
|
40
|
+
scans: number;
|
|
41
|
+
reality: number;
|
|
42
|
+
agent: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface QuotaCheckResult {
|
|
46
|
+
allowed: boolean;
|
|
47
|
+
current: number;
|
|
48
|
+
limit: number;
|
|
49
|
+
remaining: number;
|
|
50
|
+
reason?: string;
|
|
51
|
+
source: 'server' | 'cache' | 'offline';
|
|
52
|
+
requestId: string;
|
|
53
|
+
}
|
|
54
|
+
export interface RecordResult {
|
|
55
|
+
success: boolean;
|
|
56
|
+
requestId: string;
|
|
57
|
+
newUsage: number;
|
|
58
|
+
remaining: number;
|
|
59
|
+
source: 'server' | 'queued';
|
|
60
|
+
error?: string;
|
|
61
|
+
}
|
|
62
|
+
export declare class QuotaLedger {
|
|
63
|
+
private configDir;
|
|
64
|
+
private ledgerFile;
|
|
65
|
+
private cacheFile;
|
|
66
|
+
private apiUrl;
|
|
67
|
+
private apiKey;
|
|
68
|
+
constructor();
|
|
69
|
+
/**
|
|
70
|
+
* Generate unique request ID for idempotency
|
|
71
|
+
*/
|
|
72
|
+
generateRequestId(): string;
|
|
73
|
+
/**
|
|
74
|
+
* Check if action is allowed based on quota
|
|
75
|
+
* Always validates with server when possible
|
|
76
|
+
*/
|
|
77
|
+
checkQuota(action: UsageActionType): Promise<QuotaCheckResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Record usage with idempotency guarantee
|
|
80
|
+
* Uses request ID to prevent double-counting on retries
|
|
81
|
+
*/
|
|
82
|
+
recordUsage(action: UsageActionType, count?: number, requestId?: string): Promise<RecordResult>;
|
|
83
|
+
/**
|
|
84
|
+
* Get usage summary for current billing period
|
|
85
|
+
*/
|
|
86
|
+
getUsageSummary(): Promise<UsageSummary | null>;
|
|
87
|
+
/**
|
|
88
|
+
* Sync pending offline usage to server
|
|
89
|
+
*/
|
|
90
|
+
syncPendingUsage(): Promise<{
|
|
91
|
+
synced: number;
|
|
92
|
+
failed: number;
|
|
93
|
+
errors: string[];
|
|
94
|
+
}>;
|
|
95
|
+
/**
|
|
96
|
+
* Get count of pending offline usage
|
|
97
|
+
*/
|
|
98
|
+
getPendingCount(): Promise<number>;
|
|
99
|
+
private ensureDir;
|
|
100
|
+
private saveLedgerEntry;
|
|
101
|
+
private updateLedgerEntry;
|
|
102
|
+
private getUnsyncedEntries;
|
|
103
|
+
private isDuplicateRequest;
|
|
104
|
+
private getExistingResult;
|
|
105
|
+
private cacheQuotaResult;
|
|
106
|
+
private getCachedQuota;
|
|
107
|
+
private getLocalSummary;
|
|
108
|
+
}
|
|
109
|
+
export declare const quotaLedger: QuotaLedger;
|
|
110
|
+
export declare const checkQuota: (action: UsageActionType) => Promise<QuotaCheckResult>;
|
|
111
|
+
export declare const recordUsage: (action: UsageActionType, count?: number, requestId?: string) => Promise<RecordResult>;
|
|
112
|
+
export declare const getUsageSummary: () => Promise<UsageSummary | null>;
|
|
113
|
+
export declare const syncPendingUsage: () => Promise<{
|
|
114
|
+
synced: number;
|
|
115
|
+
failed: number;
|
|
116
|
+
errors: string[];
|
|
117
|
+
}>;
|
|
118
|
+
export declare const getPendingCount: () => Promise<number>;
|
|
119
|
+
//# sourceMappingURL=quota-ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-ledger.d.ts","sourceRoot":"","sources":["../src/quota-ledger.ts"],"names":[],"mappings":"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"}
|