@riocrypto/common-server 1.0.2935 → 1.0.2936

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.
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSecurityBotAuditEvent = exports.SecurityBotAuditType = void 0;
4
+ // Every model call and every admin action on security-bot, with token
5
+ // counts, so the daily and monthly budgets are computed from the same rows
6
+ // that would be reviewed after an incident.
7
+ var SecurityBotAuditType;
8
+ (function (SecurityBotAuditType) {
9
+ SecurityBotAuditType["SweepStarted"] = "sweepStarted";
10
+ SecurityBotAuditType["SweepToolCall"] = "sweepToolCall";
11
+ SecurityBotAuditType["SweepCompleted"] = "sweepCompleted";
12
+ SecurityBotAuditType["SweepFailed"] = "sweepFailed";
13
+ SecurityBotAuditType["Triage"] = "triage";
14
+ SecurityBotAuditType["FindingStatusChanged"] = "findingStatusChanged";
15
+ SecurityBotAuditType["RuleMuted"] = "ruleMuted";
16
+ SecurityBotAuditType["RuleUnmuted"] = "ruleUnmuted";
17
+ SecurityBotAuditType["ControlsChanged"] = "controlsChanged";
18
+ SecurityBotAuditType["BudgetPaused"] = "budgetPaused";
19
+ SecurityBotAuditType["InjectionRejected"] = "injectionRejected";
20
+ })(SecurityBotAuditType = exports.SecurityBotAuditType || (exports.SecurityBotAuditType = {}));
21
+ const buildSecurityBotAuditEvent = (mongoose) => {
22
+ if (mongoose.models.SecurityBotAuditEvent) {
23
+ return mongoose.model("SecurityBotAuditEvent");
24
+ }
25
+ const schema = new mongoose.Schema({
26
+ type: { type: String, enum: Object.values(SecurityBotAuditType), required: true },
27
+ sweepRunId: { type: String },
28
+ findingId: { type: String },
29
+ adminAuthId: { type: String },
30
+ adminAuthEmail: { type: String },
31
+ toolName: { type: String },
32
+ toolInput: { type: mongoose.Schema.Types.Mixed },
33
+ ok: { type: Boolean },
34
+ durationMs: { type: Number },
35
+ error: { type: String },
36
+ detail: { type: String },
37
+ redactionCounts: { type: mongoose.Schema.Types.Mixed },
38
+ modelId: { type: String },
39
+ inputTokens: { type: Number },
40
+ outputTokens: { type: Number },
41
+ estimatedUsd: { type: Number },
42
+ }, {
43
+ timestamps: { createdAt: true, updatedAt: false },
44
+ collection: "securityBotAuditEvents",
45
+ });
46
+ schema.index({ type: 1, createdAt: -1 });
47
+ schema.index({ sweepRunId: 1, createdAt: 1 });
48
+ schema.index({ findingId: 1, createdAt: 1 });
49
+ return mongoose.model("SecurityBotAuditEvent", schema);
50
+ };
51
+ exports.buildSecurityBotAuditEvent = buildSecurityBotAuditEvent;
@@ -0,0 +1,23 @@
1
+ import mongoose from "mongoose";
2
+ export declare const SECURITY_BOT_CONTROLS_KEY = "global";
3
+ export interface SecurityBotMutedRule {
4
+ ruleId: string;
5
+ until: Date;
6
+ mutedBy: string;
7
+ reason?: string;
8
+ }
9
+ export interface SecurityBotControlsDoc extends mongoose.Document {
10
+ key: string;
11
+ disabled: boolean;
12
+ disabledAt?: Date;
13
+ disabledBy?: string;
14
+ reason?: string;
15
+ sweepsPaused: boolean;
16
+ sweepsPausedAt?: Date;
17
+ sweepsPausedBy?: string;
18
+ sweepsPausedReason?: string;
19
+ mutedRules: SecurityBotMutedRule[];
20
+ }
21
+ export type SecurityBotControlsModel = mongoose.Model<SecurityBotControlsDoc>;
22
+ declare const buildSecurityBotControls: (mongoose: typeof mongoose) => SecurityBotControlsModel;
23
+ export { buildSecurityBotControls };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSecurityBotControls = exports.SECURITY_BOT_CONTROLS_KEY = void 0;
4
+ // Singleton (key "global"). Read before every sweep and every rule
5
+ // evaluation so the switch and the mutes work without a redeploy. Flipped by
6
+ // a super admin from the dashboard or by the bot itself when a budget cap
7
+ // is hit.
8
+ exports.SECURITY_BOT_CONTROLS_KEY = "global";
9
+ const buildSecurityBotControls = (mongoose) => {
10
+ if (mongoose.models.SecurityBotControls) {
11
+ return mongoose.model("SecurityBotControls");
12
+ }
13
+ const mutedRuleSchema = new mongoose.Schema({
14
+ ruleId: { type: String, required: true },
15
+ until: { type: Date, required: true },
16
+ mutedBy: { type: String, required: true },
17
+ reason: { type: String },
18
+ }, { _id: false });
19
+ const schema = new mongoose.Schema({
20
+ key: { type: String, required: true, unique: true },
21
+ disabled: { type: Boolean, default: false },
22
+ disabledAt: { type: Date },
23
+ disabledBy: { type: String },
24
+ reason: { type: String },
25
+ sweepsPaused: { type: Boolean, default: false },
26
+ sweepsPausedAt: { type: Date },
27
+ sweepsPausedBy: { type: String },
28
+ sweepsPausedReason: { type: String },
29
+ mutedRules: { type: [mutedRuleSchema], default: [] },
30
+ }, {
31
+ collection: "securityBotControls",
32
+ toJSON: {
33
+ transform(_doc, ret) {
34
+ delete ret._id;
35
+ delete ret.__v;
36
+ delete ret.key;
37
+ },
38
+ },
39
+ });
40
+ return mongoose.model("SecurityBotControls", schema);
41
+ };
42
+ exports.buildSecurityBotControls = buildSecurityBotControls;
@@ -0,0 +1,38 @@
1
+ import mongoose from "mongoose";
2
+ import { SecurityFindingSeverity, SecurityFindingSource, SecurityFindingStatus } from "@riocrypto/common";
3
+ export interface SecurityFindingEvidence {
4
+ kind: string;
5
+ ref: string;
6
+ note?: string;
7
+ }
8
+ export interface SecurityFindingEntity {
9
+ kind: string;
10
+ id: string;
11
+ }
12
+ export interface SecurityFindingDoc extends mongoose.Document {
13
+ fingerprint: string;
14
+ ruleId: string;
15
+ source: SecurityFindingSource;
16
+ severity: SecurityFindingSeverity;
17
+ status: SecurityFindingStatus;
18
+ title: string;
19
+ summary: string;
20
+ evidence: SecurityFindingEvidence[];
21
+ entity?: SecurityFindingEntity;
22
+ lens?: string;
23
+ sweepRunId?: string;
24
+ confidence?: number;
25
+ firstSeenAt: Date;
26
+ lastSeenAt: Date;
27
+ count: number;
28
+ resolvedAt?: Date;
29
+ resolvedBy?: string;
30
+ resolutionNote?: string;
31
+ triageNote?: string;
32
+ triagedAt?: Date;
33
+ createdAt: Date;
34
+ updatedAt: Date;
35
+ }
36
+ export type SecurityFindingModel = mongoose.Model<SecurityFindingDoc>;
37
+ declare const buildSecurityFinding: (mongoose: typeof mongoose) => SecurityFindingModel;
38
+ export { buildSecurityFinding };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSecurityFinding = void 0;
4
+ const common_1 = require("@riocrypto/common");
5
+ const buildSecurityFinding = (mongoose) => {
6
+ if (mongoose.models.SecurityFinding) {
7
+ return mongoose.model("SecurityFinding");
8
+ }
9
+ const evidenceSchema = new mongoose.Schema({
10
+ kind: { type: String, required: true },
11
+ ref: { type: String, required: true },
12
+ note: { type: String },
13
+ }, { _id: false });
14
+ const schema = new mongoose.Schema({
15
+ fingerprint: { type: String, required: true, unique: true },
16
+ ruleId: { type: String, required: true },
17
+ source: { type: String, enum: Object.values(common_1.SecurityFindingSource), required: true },
18
+ severity: { type: String, enum: Object.values(common_1.SecurityFindingSeverity), required: true },
19
+ status: {
20
+ type: String,
21
+ enum: Object.values(common_1.SecurityFindingStatus),
22
+ required: true,
23
+ default: common_1.SecurityFindingStatus.Open,
24
+ },
25
+ title: { type: String, required: true },
26
+ summary: { type: String, default: "" },
27
+ evidence: { type: [evidenceSchema], default: [] },
28
+ entity: {
29
+ type: new mongoose.Schema({ kind: { type: String, required: true }, id: { type: String, required: true } }, { _id: false }),
30
+ },
31
+ lens: { type: String },
32
+ sweepRunId: { type: String },
33
+ confidence: { type: Number },
34
+ firstSeenAt: { type: Date, required: true },
35
+ lastSeenAt: { type: Date, required: true },
36
+ count: { type: Number, default: 1 },
37
+ resolvedAt: { type: Date },
38
+ resolvedBy: { type: String },
39
+ resolutionNote: { type: String },
40
+ triageNote: { type: String },
41
+ triagedAt: { type: Date },
42
+ }, {
43
+ timestamps: true,
44
+ collection: "securityFindings",
45
+ toJSON: {
46
+ transform(_doc, ret) {
47
+ ret.id = ret._id;
48
+ delete ret._id;
49
+ delete ret.__v;
50
+ },
51
+ },
52
+ });
53
+ schema.index({ status: 1, severity: 1, lastSeenAt: -1 });
54
+ schema.index({ ruleId: 1, lastSeenAt: -1 });
55
+ schema.index({ "entity.kind": 1, "entity.id": 1, lastSeenAt: -1 });
56
+ schema.index({ source: 1, lastSeenAt: -1 });
57
+ return mongoose.model("SecurityFinding", schema);
58
+ };
59
+ exports.buildSecurityFinding = buildSecurityFinding;
@@ -0,0 +1,12 @@
1
+ import mongoose from "mongoose";
2
+ export interface SecurityKnownPatternDoc extends mongoose.Document {
3
+ lens: string;
4
+ ruleId?: string;
5
+ text: string;
6
+ createdBy: string;
7
+ findingId?: string;
8
+ createdAt: Date;
9
+ }
10
+ export type SecurityKnownPatternModel = mongoose.Model<SecurityKnownPatternDoc>;
11
+ declare const buildSecurityKnownPattern: (mongoose: typeof mongoose) => SecurityKnownPatternModel;
12
+ export { buildSecurityKnownPattern };
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSecurityKnownPattern = void 0;
4
+ const buildSecurityKnownPattern = (mongoose) => {
5
+ if (mongoose.models.SecurityKnownPattern) {
6
+ return mongoose.model("SecurityKnownPattern");
7
+ }
8
+ const schema = new mongoose.Schema({
9
+ lens: { type: String, required: true },
10
+ ruleId: { type: String },
11
+ text: { type: String, required: true },
12
+ createdBy: { type: String, required: true },
13
+ findingId: { type: String },
14
+ }, {
15
+ timestamps: { createdAt: true, updatedAt: false },
16
+ collection: "securityKnownPatterns",
17
+ toJSON: {
18
+ transform(_doc, ret) {
19
+ ret.id = ret._id;
20
+ delete ret._id;
21
+ delete ret.__v;
22
+ },
23
+ },
24
+ });
25
+ schema.index({ lens: 1, createdAt: -1 });
26
+ return mongoose.model("SecurityKnownPattern", schema);
27
+ };
28
+ exports.buildSecurityKnownPattern = buildSecurityKnownPattern;
@@ -0,0 +1,41 @@
1
+ import mongoose from "mongoose";
2
+ export declare enum SecuritySweepRunStatus {
3
+ Running = "running",
4
+ Completed = "completed",
5
+ Failed = "failed",
6
+ Skipped = "skipped"
7
+ }
8
+ export declare enum SecuritySweepTrigger {
9
+ Schedule = "schedule",
10
+ Signal = "signal",
11
+ Manual = "manual"
12
+ }
13
+ export interface SecuritySweepRunDoc extends mongoose.Document {
14
+ lens: string;
15
+ trigger: SecuritySweepTrigger;
16
+ triggerDetail?: string;
17
+ windowStart: Date;
18
+ windowEnd: Date;
19
+ status: SecuritySweepRunStatus;
20
+ modelId: string;
21
+ escalated: boolean;
22
+ inputSnapshot?: string;
23
+ output?: string;
24
+ findingIds: string[];
25
+ toolCalls: number;
26
+ toolErrors: number;
27
+ toolsAvailable: string[];
28
+ sourcesUnavailable: string[];
29
+ inputTokens: number;
30
+ outputTokens: number;
31
+ estimatedUsd: number;
32
+ error?: string;
33
+ requestedBy?: string;
34
+ leaseUntil?: Date;
35
+ startedAt: Date;
36
+ finishedAt?: Date;
37
+ createdAt: Date;
38
+ }
39
+ export type SecuritySweepRunModel = mongoose.Model<SecuritySweepRunDoc>;
40
+ declare const buildSecuritySweepRun: (mongoose: typeof mongoose) => SecuritySweepRunModel;
41
+ export { buildSecuritySweepRun };
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSecuritySweepRun = exports.SecuritySweepTrigger = exports.SecuritySweepRunStatus = void 0;
4
+ // One row per AI sweep. The redacted input snapshot is kept next to the
5
+ // output so a false positive can be diagnosed by looking at exactly what the
6
+ // model saw, and so a prompt change can be replayed against stored inputs.
7
+ // Both are stripped from toJSON; the super admin trace route exposes them.
8
+ var SecuritySweepRunStatus;
9
+ (function (SecuritySweepRunStatus) {
10
+ SecuritySweepRunStatus["Running"] = "running";
11
+ SecuritySweepRunStatus["Completed"] = "completed";
12
+ SecuritySweepRunStatus["Failed"] = "failed";
13
+ SecuritySweepRunStatus["Skipped"] = "skipped";
14
+ })(SecuritySweepRunStatus = exports.SecuritySweepRunStatus || (exports.SecuritySweepRunStatus = {}));
15
+ var SecuritySweepTrigger;
16
+ (function (SecuritySweepTrigger) {
17
+ SecuritySweepTrigger["Schedule"] = "schedule";
18
+ SecuritySweepTrigger["Signal"] = "signal";
19
+ SecuritySweepTrigger["Manual"] = "manual";
20
+ })(SecuritySweepTrigger = exports.SecuritySweepTrigger || (exports.SecuritySweepTrigger = {}));
21
+ const buildSecuritySweepRun = (mongoose) => {
22
+ if (mongoose.models.SecuritySweepRun) {
23
+ return mongoose.model("SecuritySweepRun");
24
+ }
25
+ const schema = new mongoose.Schema({
26
+ lens: { type: String, required: true },
27
+ trigger: { type: String, enum: Object.values(SecuritySweepTrigger), required: true },
28
+ triggerDetail: { type: String },
29
+ windowStart: { type: Date, required: true },
30
+ windowEnd: { type: Date, required: true },
31
+ status: { type: String, enum: Object.values(SecuritySweepRunStatus), required: true },
32
+ modelId: { type: String, default: "" },
33
+ escalated: { type: Boolean, default: false },
34
+ inputSnapshot: { type: String },
35
+ output: { type: String },
36
+ findingIds: { type: [String], default: [] },
37
+ toolCalls: { type: Number, default: 0 },
38
+ toolErrors: { type: Number, default: 0 },
39
+ toolsAvailable: { type: [String], default: [] },
40
+ sourcesUnavailable: { type: [String], default: [] },
41
+ inputTokens: { type: Number, default: 0 },
42
+ outputTokens: { type: Number, default: 0 },
43
+ estimatedUsd: { type: Number, default: 0 },
44
+ error: { type: String },
45
+ requestedBy: { type: String },
46
+ leaseUntil: { type: Date },
47
+ startedAt: { type: Date, required: true },
48
+ finishedAt: { type: Date },
49
+ }, {
50
+ timestamps: { createdAt: true, updatedAt: false },
51
+ collection: "securitySweepRuns",
52
+ toJSON: {
53
+ transform(_doc, ret) {
54
+ ret.id = ret._id;
55
+ delete ret._id;
56
+ delete ret.__v;
57
+ delete ret.inputSnapshot;
58
+ delete ret.output;
59
+ },
60
+ },
61
+ });
62
+ schema.index({ startedAt: -1 });
63
+ schema.index({ lens: 1, startedAt: -1 });
64
+ schema.index({ trigger: 1, startedAt: -1 });
65
+ return mongoose.model("SecuritySweepRun", schema);
66
+ };
67
+ exports.buildSecuritySweepRun = buildSecuritySweepRun;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riocrypto/common-server",
3
- "version": "1.0.2935",
3
+ "version": "1.0.2936",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "@google-cloud/secret-manager": "^5.6.0",
29
29
  "@google-cloud/storage": "^7.19.0",
30
30
  "@hyperdx/node-opentelemetry": "^0.10.3",
31
- "@riocrypto/common": "1.0.2729",
31
+ "@riocrypto/common": "1.0.2732",
32
32
  "@slack/web-api": "^7.15.0",
33
33
  "@types/express": "^4.17.25",
34
34
  "axios": "1.18.1",
@@ -37,6 +37,7 @@
37
37
  "express-rate-limit": "^7.5.1",
38
38
  "express-validator": "^6.15.0",
39
39
  "fireblocks-sdk": "^5.38.0",
40
+ "google-auth-library": "9.15.1",
40
41
  "googleapis": "^135.1.0",
41
42
  "he": "^1.2.0",
42
43
  "jose": "^6.2.2",