@prism-d1/cli 1.0.27 → 1.0.28
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/assets/eval-harness/README.md +114 -0
- package/dist/assets/eval-harness/eval-config.json +10 -0
- package/dist/assets/eval-harness/rubrics/agent-quality.json +79 -0
- package/dist/assets/eval-harness/rubrics/api-response-quality.json +45 -0
- package/dist/assets/eval-harness/rubrics/code-quality.json +98 -0
- package/dist/assets/eval-harness/rubrics/security-compliance.json +145 -0
- package/dist/assets/eval-harness/rubrics/spec-compliance.json +67 -0
- package/dist/assets/eval-harness/run-eval.sh +122 -0
- package/dist/assets/github-workflows/README.md +110 -0
- package/dist/assets/github-workflows/prism-agent-eval.yml +313 -0
- package/dist/assets/github-workflows/prism-ai-metrics.yml +261 -0
- package/dist/assets/github-workflows/prism-dora-weekly.yml +334 -0
- package/dist/assets/github-workflows/prism-eval-gate.yml +310 -0
- package/dist/assets/infra/bin/app.ts +56 -0
- package/dist/assets/infra/cdk.json +12 -0
- package/dist/assets/infra/lib/api-stack.ts +347 -0
- package/dist/assets/infra/lib/constructs/bedrock-guardrail-construct.ts +201 -0
- package/dist/assets/infra/lib/constructs/guardrail-enforcer-construct.ts +59 -0
- package/dist/assets/infra/lib/constructs/prism-vpc-construct.ts +75 -0
- package/dist/assets/infra/lib/constructs/security-agent-construct.ts +266 -0
- package/dist/assets/infra/lib/dashboard-stack.ts +1392 -0
- package/dist/assets/infra/lib/lambda/api-handler.ts +477 -0
- package/dist/assets/infra/lib/lambda/defect-correlator.ts +142 -0
- package/dist/assets/infra/lib/lambda/exfiltration-detector.ts +100 -0
- package/dist/assets/infra/lib/lambda/layers/guardrail-enforcer/nodejs/guardrail-enforcer.js +53 -0
- package/dist/assets/infra/lib/lambda/metrics-processor.ts +748 -0
- package/dist/assets/infra/lib/lambda/security-agent-processor.ts +231 -0
- package/dist/assets/infra/lib/lambda/security-remediation-tracker.ts +120 -0
- package/dist/assets/infra/lib/lambda/security-response-automator.ts +130 -0
- package/dist/assets/infra/lib/lambda/spec-to-code-calculator.ts +123 -0
- package/dist/assets/infra/lib/metrics-pipeline-stack.ts +701 -0
- package/dist/assets/infra/package.json +23 -0
- package/dist/assets/infra/tsconfig.json +24 -0
- package/dist/src/commands/bootstrapper/install-eval-harness.d.ts.map +1 -1
- package/dist/src/commands/bootstrapper/install-eval-harness.js +3 -4
- package/dist/src/commands/bootstrapper/install-eval-harness.js.map +1 -1
- package/dist/src/commands/bootstrapper/install-git-hooks.d.ts.map +1 -1
- package/dist/src/commands/bootstrapper/install-git-hooks.js +2 -5
- package/dist/src/commands/bootstrapper/install-git-hooks.js.map +1 -1
- package/dist/src/commands/securityagent/setup.d.ts.map +1 -1
- package/dist/src/commands/securityagent/setup.js +2 -3
- package/dist/src/commands/securityagent/setup.js.map +1 -1
- package/dist/src/commands/workshop/deploy-infra.d.ts.map +1 -1
- package/dist/src/commands/workshop/deploy-infra.js +2 -3
- package/dist/src/commands/workshop/deploy-infra.js.map +1 -1
- package/dist/src/commands/workshop/generate-demo-data.d.ts.map +1 -1
- package/dist/src/commands/workshop/generate-demo-data.js +3 -8
- package/dist/src/commands/workshop/generate-demo-data.js.map +1 -1
- package/dist/src/commands/workshop/perform-pen-test.d.ts.map +1 -1
- package/dist/src/commands/workshop/perform-pen-test.js +5 -14
- package/dist/src/commands/workshop/perform-pen-test.js.map +1 -1
- package/dist/src/utils/root.d.ts +6 -0
- package/dist/src/utils/root.d.ts.map +1 -1
- package/dist/src/utils/root.js +29 -0
- package/dist/src/utils/root.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EventBridgeClient,
|
|
3
|
+
PutEventsCommand,
|
|
4
|
+
} from '@aws-sdk/client-eventbridge';
|
|
5
|
+
|
|
6
|
+
const eventBridgeClient = new EventBridgeClient({});
|
|
7
|
+
const EVENT_BUS_NAME = process.env.EVENT_BUS_NAME!;
|
|
8
|
+
const ALERT_THRESHOLD_READS = parseInt(process.env.ALERT_THRESHOLD_READS ?? '100', 10);
|
|
9
|
+
|
|
10
|
+
interface CloudTrailDynamoDBEvent {
|
|
11
|
+
detail: {
|
|
12
|
+
eventSource: string;
|
|
13
|
+
eventName: string;
|
|
14
|
+
eventTime: string;
|
|
15
|
+
userIdentity: {
|
|
16
|
+
type: string;
|
|
17
|
+
arn: string;
|
|
18
|
+
principalId: string;
|
|
19
|
+
accountId: string;
|
|
20
|
+
};
|
|
21
|
+
requestParameters?: {
|
|
22
|
+
tableName?: string;
|
|
23
|
+
};
|
|
24
|
+
responseElements?: unknown;
|
|
25
|
+
readOnly?: boolean;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Simple in-memory rate tracking (reset on cold start)
|
|
30
|
+
const readCounts = new Map<string, { count: number; firstSeen: string }>();
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Monitors CloudTrail DynamoDB read events for anomalous patterns.
|
|
34
|
+
* Emits prism.d1.security events when thresholds are exceeded.
|
|
35
|
+
*/
|
|
36
|
+
export async function handler(event: CloudTrailDynamoDBEvent): Promise<void> {
|
|
37
|
+
const detail = event.detail;
|
|
38
|
+
|
|
39
|
+
// Only process read operations on PRISM tables
|
|
40
|
+
const tableName = detail.requestParameters?.tableName ?? '';
|
|
41
|
+
if (!tableName.startsWith('prism-')) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const principal = detail.userIdentity?.arn ?? 'unknown';
|
|
46
|
+
const key = `${principal}:${tableName}`;
|
|
47
|
+
|
|
48
|
+
// Track read count per principal per table
|
|
49
|
+
const existing = readCounts.get(key);
|
|
50
|
+
if (existing) {
|
|
51
|
+
existing.count += 1;
|
|
52
|
+
} else {
|
|
53
|
+
readCounts.set(key, { count: 1, firstSeen: detail.eventTime });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const current = readCounts.get(key)!;
|
|
57
|
+
|
|
58
|
+
// Check if threshold exceeded
|
|
59
|
+
if (current.count >= ALERT_THRESHOLD_READS) {
|
|
60
|
+
console.warn(
|
|
61
|
+
`Exfiltration alert: ${principal} made ${current.count} reads on ${tableName} since ${current.firstSeen}`,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const securityEvent = {
|
|
65
|
+
team_id: 'security',
|
|
66
|
+
repo: 'platform',
|
|
67
|
+
timestamp: detail.eventTime,
|
|
68
|
+
prism_level: 1,
|
|
69
|
+
metric: {
|
|
70
|
+
name: 'ExfiltrationAlertCount',
|
|
71
|
+
value: current.count,
|
|
72
|
+
unit: 'count',
|
|
73
|
+
},
|
|
74
|
+
security: {
|
|
75
|
+
alert_type: 'high_read_volume',
|
|
76
|
+
table_name: tableName,
|
|
77
|
+
principal_arn: principal,
|
|
78
|
+
read_count: current.count,
|
|
79
|
+
window_start: current.firstSeen,
|
|
80
|
+
window_end: detail.eventTime,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
await eventBridgeClient.send(
|
|
85
|
+
new PutEventsCommand({
|
|
86
|
+
Entries: [
|
|
87
|
+
{
|
|
88
|
+
Source: 'prism.d1.velocity',
|
|
89
|
+
DetailType: 'prism.d1.security',
|
|
90
|
+
EventBusName: EVENT_BUS_NAME,
|
|
91
|
+
Detail: JSON.stringify(securityEvent),
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// Reset counter after alert
|
|
98
|
+
readCounts.delete(key);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRISM D1 Guardrail Enforcer — Lambda layer for Bedrock Guardrail enforcement.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const { enforceGuardrail } = require('guardrail-enforcer');
|
|
6
|
+
* const result = await enforceGuardrail(inputText);
|
|
7
|
+
* if (result.blocked) { ... }
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { BedrockRuntimeClient, ApplyGuardrailCommand } = require('@aws-sdk/client-bedrock-runtime');
|
|
11
|
+
|
|
12
|
+
const client = new BedrockRuntimeClient({});
|
|
13
|
+
const GUARDRAIL_ID = process.env.GUARDRAIL_ID;
|
|
14
|
+
const GUARDRAIL_VERSION = process.env.GUARDRAIL_VERSION || 'DRAFT';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Apply the PRISM guardrail to input or output text.
|
|
18
|
+
* @param {string} text - The text to check
|
|
19
|
+
* @param {'INPUT'|'OUTPUT'} source - Whether this is input or output
|
|
20
|
+
* @returns {Promise<{blocked: boolean, action: string, outputs: any[]}>}
|
|
21
|
+
*/
|
|
22
|
+
async function enforceGuardrail(text, source = 'INPUT') {
|
|
23
|
+
if (!GUARDRAIL_ID) {
|
|
24
|
+
console.warn('GUARDRAIL_ID not set, skipping enforcement');
|
|
25
|
+
return { blocked: false, action: 'NONE', outputs: [] };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const response = await client.send(
|
|
30
|
+
new ApplyGuardrailCommand({
|
|
31
|
+
guardrailIdentifier: GUARDRAIL_ID,
|
|
32
|
+
guardrailVersion: GUARDRAIL_VERSION,
|
|
33
|
+
source,
|
|
34
|
+
content: [{ text: { text } }],
|
|
35
|
+
}),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const action = response.action || 'NONE';
|
|
39
|
+
const blocked = action === 'GUARDRAIL_INTERVENED';
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
blocked,
|
|
43
|
+
action,
|
|
44
|
+
outputs: response.outputs || [],
|
|
45
|
+
assessments: response.assessments || [],
|
|
46
|
+
};
|
|
47
|
+
} catch (err) {
|
|
48
|
+
console.error('Guardrail enforcement failed:', err);
|
|
49
|
+
return { blocked: false, action: 'ERROR', outputs: [], error: err.message };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = { enforceGuardrail };
|