@valence-ai/sdk 0.1.0 → 0.2.1
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/README.md +178 -21
- package/dist/client.d.ts +5 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/local-scan-rules.d.ts +3 -0
- package/dist/local-scan-rules.d.ts.map +1 -0
- package/dist/local-scan-rules.js +115 -0
- package/dist/local-scan-rules.js.map +1 -0
- package/dist/local-scan.d.ts +3 -0
- package/dist/local-scan.d.ts.map +1 -0
- package/dist/local-scan.js +197 -0
- package/dist/local-scan.js.map +1 -0
- package/dist/runtime-findings.d.ts +14 -0
- package/dist/runtime-findings.d.ts.map +1 -0
- package/dist/runtime-findings.js +115 -0
- package/dist/runtime-findings.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# Valence SDK
|
|
2
2
|
|
|
3
|
-
The Valence SDK
|
|
3
|
+
The Valence SDK is the integration layer for connecting an application to Valence AI.
|
|
4
4
|
|
|
5
|
-
It
|
|
5
|
+
It is designed for teams that need a single integration path across development, CI, and live environments. The SDK provides the primitives required to run or report security scans, ingest security issues into Valence AI, stream live runtime telemetry, and optionally enforce review gates around sensitive actions. The objective is to connect an application directly to the Valence AI control plane without requiring persistent repository handover.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- `BLOCK`
|
|
9
|
-
- `REQUIRES_APPROVAL`
|
|
7
|
+
It supports the full Valence AI flow:
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- run local or CI security scans
|
|
10
|
+
- ingest security issues into Valence AI
|
|
11
|
+
- send live runtime signals from local, staging, or production
|
|
12
|
+
- add runtime review hooks for sensitive actions when needed
|
|
13
|
+
|
|
14
|
+
Valence AI is security-issue first. Start with scan ingestion and runtime reporting, then enable runtime review controls only for workflows that require pre-execution validation.
|
|
12
15
|
|
|
13
16
|
## Package
|
|
14
17
|
|
|
@@ -23,14 +26,20 @@ npm install @valence-ai/sdk
|
|
|
23
26
|
## Environment variables
|
|
24
27
|
|
|
25
28
|
```env
|
|
26
|
-
VALENCE_API_BASE_URL=
|
|
29
|
+
VALENCE_API_BASE_URL=https://www.valenceai.co
|
|
27
30
|
VALENCE_API_KEY=valence_pk_...
|
|
28
31
|
VALENCE_WORKSPACE_ID=workspace-id
|
|
29
32
|
VALENCE_PROJECT_ID=project-id
|
|
30
|
-
|
|
33
|
+
VALENCE_SERVICE_NAME=web-app
|
|
31
34
|
VALENCE_ENVIRONMENT=staging
|
|
32
35
|
```
|
|
33
36
|
|
|
37
|
+
Optional for agent-control workflows:
|
|
38
|
+
|
|
39
|
+
```env
|
|
40
|
+
VALENCE_AGENT_NAME=incidentos-agent
|
|
41
|
+
```
|
|
42
|
+
|
|
34
43
|
## Create a client
|
|
35
44
|
|
|
36
45
|
```ts
|
|
@@ -42,9 +51,153 @@ const client = createValenceClient({
|
|
|
42
51
|
});
|
|
43
52
|
```
|
|
44
53
|
|
|
45
|
-
##
|
|
54
|
+
## Run a local scan
|
|
55
|
+
|
|
56
|
+
Use `runLocalSecurityScan` to scan the current project and ingest security issues into Valence AI through the shared issue pipeline.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { createValenceClient, runLocalSecurityScan } from '@valence-ai/sdk';
|
|
60
|
+
|
|
61
|
+
const client = createValenceClient({
|
|
62
|
+
baseUrl: process.env.VALENCE_API_BASE_URL!,
|
|
63
|
+
apiKey: process.env.VALENCE_API_KEY!,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const result = await runLocalSecurityScan(
|
|
67
|
+
{
|
|
68
|
+
baseUrl: process.env.VALENCE_API_BASE_URL!,
|
|
69
|
+
apiKey: process.env.VALENCE_API_KEY!,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
cwd: process.cwd(),
|
|
73
|
+
environment: process.env.VALENCE_ENVIRONMENT as 'production' | 'staging' | 'sandbox',
|
|
74
|
+
projectId: process.env.VALENCE_PROJECT_ID!,
|
|
75
|
+
workspaceId: process.env.VALENCE_WORKSPACE_ID,
|
|
76
|
+
metadata: {
|
|
77
|
+
sourceLabel: 'Local developer scan',
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
console.log(`Uploaded ${result.findings.length} security issues`);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Current local scan coverage includes:
|
|
86
|
+
|
|
87
|
+
- codebase checks for a narrow set of high-signal web-app issues
|
|
88
|
+
- public environment variable exposure checks
|
|
89
|
+
- dependency issues from `npm audit`
|
|
90
|
+
|
|
91
|
+
## Report security issues directly
|
|
46
92
|
|
|
47
|
-
|
|
93
|
+
If your CI job or custom scanner already produced issue records, upload them directly with `reportFindings`.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
await client.reportFindings({
|
|
97
|
+
projectId: process.env.VALENCE_PROJECT_ID!,
|
|
98
|
+
workspaceId: process.env.VALENCE_WORKSPACE_ID,
|
|
99
|
+
environment: process.env.VALENCE_ENVIRONMENT as 'production' | 'staging' | 'sandbox',
|
|
100
|
+
source: 'CI_SCAN',
|
|
101
|
+
metadata: {
|
|
102
|
+
branch: process.env.GITHUB_REF_NAME,
|
|
103
|
+
commitSha: process.env.GITHUB_SHA,
|
|
104
|
+
},
|
|
105
|
+
findings: [
|
|
106
|
+
{
|
|
107
|
+
category: 'auth',
|
|
108
|
+
checkId: 'missing-httponly-cookie',
|
|
109
|
+
fingerprint: 'cookie-flag:session',
|
|
110
|
+
locationPath: 'app/api/session/route.ts',
|
|
111
|
+
locationLine: 18,
|
|
112
|
+
remediation: 'Set HttpOnly and Secure on session cookies.',
|
|
113
|
+
severity: 'HIGH',
|
|
114
|
+
summary: 'The session cookie appears to be missing one or more protective flags.',
|
|
115
|
+
title: 'Session cookie missing security flags',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Report runtime security issues
|
|
122
|
+
|
|
123
|
+
Use the runtime issue helpers when you want live application behavior to appear in Valence AI alongside scan results.
|
|
124
|
+
|
|
125
|
+
### Hook runtime decisions automatically
|
|
126
|
+
|
|
127
|
+
Use `createRuntimeFindingHooks` to convert runtime decisions into security issues ingested through the shared `/api/findings` pipeline.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import {
|
|
131
|
+
createRuntimeFindingHooks,
|
|
132
|
+
createToolExecutionGuard,
|
|
133
|
+
createValenceClient,
|
|
134
|
+
} from '@valence-ai/sdk';
|
|
135
|
+
|
|
136
|
+
const client = createValenceClient({
|
|
137
|
+
baseUrl: process.env.VALENCE_API_BASE_URL!,
|
|
138
|
+
apiKey: process.env.VALENCE_API_KEY!,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const runtimeHooks = createRuntimeFindingHooks(client, {
|
|
142
|
+
minimumRisk: 'HIGH',
|
|
143
|
+
serviceName: process.env.VALENCE_SERVICE_NAME ?? 'web-app',
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const guard = createToolExecutionGuard(
|
|
147
|
+
client,
|
|
148
|
+
{
|
|
149
|
+
workspaceId: process.env.VALENCE_WORKSPACE_ID!,
|
|
150
|
+
projectId: process.env.VALENCE_PROJECT_ID!,
|
|
151
|
+
agentName: process.env.VALENCE_SERVICE_NAME ?? 'web-app',
|
|
152
|
+
environment: process.env.VALENCE_ENVIRONMENT as 'production' | 'staging' | 'sandbox',
|
|
153
|
+
goal: 'serve customer dashboard',
|
|
154
|
+
},
|
|
155
|
+
runtimeHooks
|
|
156
|
+
);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
By default, runtime security issues are created for:
|
|
160
|
+
|
|
161
|
+
- blocked actions
|
|
162
|
+
- review-required actions
|
|
163
|
+
|
|
164
|
+
Enable `includeAllowDecisions` if you also want to retain allowed but high-risk actions.
|
|
165
|
+
|
|
166
|
+
### Report a runtime decision directly
|
|
167
|
+
|
|
168
|
+
If your application already has a decision and event object, you can report it directly.
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import {
|
|
172
|
+
createValenceClient,
|
|
173
|
+
reportRuntimeDecisionFinding,
|
|
174
|
+
} from '@valence-ai/sdk';
|
|
175
|
+
|
|
176
|
+
await reportRuntimeDecisionFinding(
|
|
177
|
+
client,
|
|
178
|
+
{
|
|
179
|
+
workspaceId: process.env.VALENCE_WORKSPACE_ID!,
|
|
180
|
+
projectId: process.env.VALENCE_PROJECT_ID!,
|
|
181
|
+
agentName: process.env.VALENCE_SERVICE_NAME ?? 'web-app',
|
|
182
|
+
environment: 'production',
|
|
183
|
+
goal: 'export invoices',
|
|
184
|
+
tool: 'billing_export',
|
|
185
|
+
action: 'export',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
decision: 'REQUIRES_APPROVAL',
|
|
189
|
+
reason: 'Billing exports require review in production.',
|
|
190
|
+
risk: 'HIGH',
|
|
191
|
+
policyId: 'policy_123',
|
|
192
|
+
approvalId: 'approval_123',
|
|
193
|
+
latencyMs: 14,
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Add runtime review controls
|
|
199
|
+
|
|
200
|
+
This is the optional advanced integration model for sensitive workflows and agentic products.
|
|
48
201
|
|
|
49
202
|
```ts
|
|
50
203
|
import { createToolExecutionGuard } from '@valence-ai/sdk';
|
|
@@ -52,14 +205,14 @@ import { createToolExecutionGuard } from '@valence-ai/sdk';
|
|
|
52
205
|
const guard = createToolExecutionGuard(client, {
|
|
53
206
|
workspaceId: process.env.VALENCE_WORKSPACE_ID!,
|
|
54
207
|
projectId: process.env.VALENCE_PROJECT_ID!,
|
|
55
|
-
agentName: process.env.
|
|
208
|
+
agentName: process.env.VALENCE_SERVICE_NAME ?? 'web-app',
|
|
56
209
|
environment: process.env.VALENCE_ENVIRONMENT as 'production' | 'staging' | 'sandbox',
|
|
57
210
|
goal: 'resolve_incident',
|
|
58
211
|
sessionId: 'session-123',
|
|
59
212
|
});
|
|
60
213
|
```
|
|
61
214
|
|
|
62
|
-
## Run a
|
|
215
|
+
## Run a protected action
|
|
63
216
|
|
|
64
217
|
```ts
|
|
65
218
|
const result = await guard.runTool(
|
|
@@ -74,7 +227,7 @@ const result = await guard.runTool(
|
|
|
74
227
|
);
|
|
75
228
|
```
|
|
76
229
|
|
|
77
|
-
## Use `withValenceGuard` for
|
|
230
|
+
## Use `withValenceGuard` for one sensitive action
|
|
78
231
|
|
|
79
232
|
```ts
|
|
80
233
|
import { withValenceGuard } from '@valence-ai/sdk';
|
|
@@ -94,7 +247,7 @@ const incident = await guardedReadIncident(async () => {
|
|
|
94
247
|
});
|
|
95
248
|
```
|
|
96
249
|
|
|
97
|
-
##
|
|
250
|
+
## Runtime request contract
|
|
98
251
|
|
|
99
252
|
```ts
|
|
100
253
|
type ToolEvent = {
|
|
@@ -128,13 +281,13 @@ type DecisionResponse = {
|
|
|
128
281
|
|
|
129
282
|
## Runtime behavior
|
|
130
283
|
|
|
131
|
-
-
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
- `
|
|
284
|
+
- local scan issues go to `/api/findings`
|
|
285
|
+
- CI issues go to `/api/findings`
|
|
286
|
+
- runtime issues go to `/api/findings`
|
|
287
|
+
- sensitive runtime reviews go to `/api/decide`
|
|
288
|
+
- `dryRun: true` uses `/api/simulate`
|
|
136
289
|
|
|
137
|
-
|
|
290
|
+
The primary product path is security-issue ingestion. The decision endpoints only matter when you enable runtime review hooks for sensitive actions.
|
|
138
291
|
|
|
139
292
|
## Error handling
|
|
140
293
|
|
|
@@ -178,12 +331,16 @@ const decision = await guard.runTool(
|
|
|
178
331
|
);
|
|
179
332
|
```
|
|
180
333
|
|
|
181
|
-
Use dry-run when you want to preview the
|
|
334
|
+
Use dry-run when you want to preview the runtime-control outcome without committing to a real operation.
|
|
182
335
|
|
|
183
336
|
## Exported API
|
|
184
337
|
|
|
185
338
|
```ts
|
|
186
339
|
createValenceClient
|
|
340
|
+
runLocalSecurityScan
|
|
341
|
+
createRuntimeFindingHooks
|
|
342
|
+
reportRuntimeDecisionFinding
|
|
343
|
+
buildRuntimeDecisionFinding
|
|
187
344
|
createToolExecutionGuard
|
|
188
345
|
guardToolExecution
|
|
189
346
|
withValenceGuard
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type { DecisionResponse, ToolEvent, ValenceClientOptions } from './types.js';
|
|
1
|
+
import type { DecisionResponse, FindingBatch, ToolEvent, ValenceClientOptions } from './types.js';
|
|
2
2
|
export declare function createValenceClient(options: ValenceClientOptions): {
|
|
3
3
|
decide(event: ToolEvent): Promise<DecisionResponse>;
|
|
4
|
+
reportFindings(batch: FindingBatch): Promise<{
|
|
5
|
+
ingested: number;
|
|
6
|
+
ok: true;
|
|
7
|
+
}>;
|
|
4
8
|
};
|
|
5
9
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACvB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB;kBAOrC,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;0BAwC9C,YAAY,GACpB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;EAoBjD"}
|
package/dist/client.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export function createValenceClient(options) {
|
|
2
2
|
const request = options.fetch ?? fetch;
|
|
3
3
|
const decidePath = options.decidePath ?? '/api/decide';
|
|
4
|
+
const findingsPath = options.findingsPath ?? '/api/findings';
|
|
4
5
|
const simulatePath = options.simulatePath ?? '/api/simulate';
|
|
5
6
|
return {
|
|
6
7
|
async decide(event) {
|
|
@@ -36,6 +37,21 @@ export function createValenceClient(options) {
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
},
|
|
40
|
+
async reportFindings(batch) {
|
|
41
|
+
const response = await request(`${options.baseUrl}${findingsPath}`, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: {
|
|
44
|
+
'Content-Type': 'application/json',
|
|
45
|
+
'x-api-key': options.apiKey,
|
|
46
|
+
...options.headers,
|
|
47
|
+
},
|
|
48
|
+
body: JSON.stringify(batch),
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new Error(`Valence findings request failed with ${response.status}`);
|
|
52
|
+
}
|
|
53
|
+
return (await response.json());
|
|
54
|
+
},
|
|
39
55
|
};
|
|
40
56
|
}
|
|
41
57
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IACvC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,aAAa,CAAC;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,eAAe,CAAC;IAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,eAAe,CAAC;IAE7D,OAAO;QACH,KAAK,CAAC,MAAM,CAAC,KAAgB;YACzB,MAAM,UAAU,GACZ,OAAO,eAAe,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1E,MAAM,OAAO,GACT,UAAU,IAAI,OAAO,CAAC,SAAS;gBAC3B,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC;gBACzD,CAAC,CAAC,IAAI,CAAC;YAEf,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;gBACtD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;oBACxD,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACL,cAAc,EAAE,kBAAkB;wBAClC,WAAW,EAAE,OAAO,CAAC,MAAM;wBAC3B,GAAG,OAAO,CAAC,OAAO;qBACrB;oBACD,MAAM,EAAE,UAAU,EAAE,MAAM;oBAC1B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACjB,GAAG,KAAK;wBACR,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBACtD,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK;wBAC7B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;qBACrC,CAAC;iBACL,CAAC,CAAC;gBAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CACX,wCAAwC,QAAQ,CAAC,MAAM,EAAE,CAC5D,CAAC;gBACN,CAAC;gBAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAqB,CAAC;YACvD,CAAC;oBAAS,CAAC;gBACP,IAAI,OAAO,EAAE,CAAC;oBACV,YAAY,CAAC,OAAO,CAAC,CAAC;gBAC1B,CAAC;YACL,CAAC;QACL,CAAC;QACD,KAAK,CAAC,cAAc,CAChB,KAAmB;YAEnB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,YAAY,EAAE,EAAE;gBAChE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACL,cAAc,EAAE,kBAAkB;oBAClC,WAAW,EAAE,OAAO,CAAC,MAAM;oBAC3B,GAAG,OAAO,CAAC,OAAO;iBACrB;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;aAC9B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACX,wCAAwC,QAAQ,CAAC,MAAM,EAAE,CAC5D,CAAC;YACN,CAAC;YAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmC,CAAC;QACrE,CAAC;KACJ,CAAC;AACN,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { createValenceClient } from './client.js';
|
|
2
|
+
export { runLocalSecurityScan } from './local-scan.js';
|
|
3
|
+
export { buildRuntimeDecisionFinding, createRuntimeFindingHooks, reportRuntimeDecisionFinding, } from './runtime-findings.js';
|
|
2
4
|
export { createToolExecutionGuard, guardToolExecution, withValenceGuard, } from './wrap-tool.js';
|
|
3
5
|
export { ValenceApprovalRequiredError, ValenceBlockError, ValenceDecisionError, isValenceDecisionError, } from './errors.js';
|
|
4
|
-
export type { DecisionResponse, ToolDefinition, ToolEvent, ToolExecutionContext, ToolExecutionHooks, ToolExecutionRequest, ToolParameters, ValenceClientOptions, ValenceDecision, ValenceEnvironment, ValenceRisk, } from './types.js';
|
|
6
|
+
export type { DecisionResponse, FindingBatch, FindingSeverity, FindingSource, ToolDefinition, ToolEvent, ToolExecutionContext, ToolExecutionHooks, ToolExecutionRequest, ToolParameters, ValenceClientOptions, ValenceDecision, ValenceEnvironment, ValenceFinding, ValenceLocalScanOptions, ValenceLocalScanResult, ValenceRuntimeFindingOptions, ValenceRisk, } from './types.js';
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACH,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,4BAA4B,EAC5B,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,aAAa,CAAC;AACrB,YAAY,EACR,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,WAAW,GACd,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACH,2BAA2B,EAC3B,yBAAyB,EACzB,4BAA4B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACH,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,4BAA4B,EAC5B,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,aAAa,CAAC;AACrB,YAAY,EACR,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,4BAA4B,EAC5B,WAAW,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { createValenceClient } from './client.js';
|
|
2
|
+
export { runLocalSecurityScan } from './local-scan.js';
|
|
3
|
+
export { buildRuntimeDecisionFinding, createRuntimeFindingHooks, reportRuntimeDecisionFinding, } from './runtime-findings.js';
|
|
2
4
|
export { createToolExecutionGuard, guardToolExecution, withValenceGuard, } from './wrap-tool.js';
|
|
3
5
|
export { ValenceApprovalRequiredError, ValenceBlockError, ValenceDecisionError, isValenceDecisionError, } from './errors.js';
|
|
4
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACH,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,4BAA4B,EAC5B,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACH,2BAA2B,EAC3B,yBAAyB,EACzB,4BAA4B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACH,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,4BAA4B,EAC5B,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-scan-rules.d.ts","sourceRoot":"","sources":["../src/local-scan-rules.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,oBAO9E"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export function findCodebaseFindings(file, content, cwd) {
|
|
3
|
+
return [
|
|
4
|
+
...findDangerouslySetInnerHtml(file, content, cwd),
|
|
5
|
+
...findTargetBlankWithoutRel(file, content, cwd),
|
|
6
|
+
...findUnsafeRedirects(file, content, cwd),
|
|
7
|
+
...findCookiesMissingSecurityFlags(file, content, cwd),
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
function findDangerouslySetInnerHtml(file, content, cwd) {
|
|
11
|
+
const findings = [];
|
|
12
|
+
const lines = content.split(/\r?\n/);
|
|
13
|
+
lines.forEach((line, index) => {
|
|
14
|
+
if (!line.includes('dangerouslySetInnerHTML')) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
findings.push({
|
|
18
|
+
category: 'app-security',
|
|
19
|
+
checkId: 'dangerously-set-inner-html',
|
|
20
|
+
fingerprint: fingerprint(`${file}:${index + 1}:dangerously-set-inner-html`),
|
|
21
|
+
locationLine: index + 1,
|
|
22
|
+
locationPath: normalizePath(cwd, file),
|
|
23
|
+
remediation: 'Avoid rendering raw HTML where possible. If required, sanitize the content before rendering and document the trust boundary.',
|
|
24
|
+
severity: 'HIGH',
|
|
25
|
+
summary: 'Direct HTML injection can introduce XSS risk when untrusted content reaches rendered markup.',
|
|
26
|
+
title: 'Potential XSS risk from dangerouslySetInnerHTML',
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
return findings;
|
|
30
|
+
}
|
|
31
|
+
function findTargetBlankWithoutRel(file, content, cwd) {
|
|
32
|
+
const findings = [];
|
|
33
|
+
const lines = content.split(/\r?\n/);
|
|
34
|
+
lines.forEach((line, index) => {
|
|
35
|
+
if (!line.includes('target="_blank"')) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (line.includes('rel="noopener noreferrer"')) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
findings.push({
|
|
42
|
+
category: 'app-security',
|
|
43
|
+
checkId: 'target-blank-without-rel',
|
|
44
|
+
fingerprint: fingerprint(`${file}:${index + 1}:target-blank-without-rel`),
|
|
45
|
+
locationLine: index + 1,
|
|
46
|
+
locationPath: normalizePath(cwd, file),
|
|
47
|
+
remediation: 'Add rel="noopener noreferrer" to links that open a new tab to prevent reverse-tabnabbing and opener access.',
|
|
48
|
+
severity: 'MEDIUM',
|
|
49
|
+
summary: 'Links that open a new tab without rel protection can expose opener-related security issues.',
|
|
50
|
+
title: 'External link opens in new tab without rel protection',
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
return findings;
|
|
54
|
+
}
|
|
55
|
+
function findUnsafeRedirects(file, content, cwd) {
|
|
56
|
+
const findings = [];
|
|
57
|
+
const lines = content.split(/\r?\n/);
|
|
58
|
+
lines.forEach((line, index) => {
|
|
59
|
+
const hasRedirectCall = line.includes('redirect(') ||
|
|
60
|
+
line.includes('router.push(') ||
|
|
61
|
+
line.includes('window.location');
|
|
62
|
+
const hasUntrustedInput = line.includes('searchParams.get(') ||
|
|
63
|
+
line.includes('nextUrl.searchParams.get(') ||
|
|
64
|
+
line.includes('params.get(');
|
|
65
|
+
if (!hasRedirectCall || !hasUntrustedInput) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
findings.push({
|
|
69
|
+
category: 'app-security',
|
|
70
|
+
checkId: 'unsafe-redirect-input',
|
|
71
|
+
fingerprint: fingerprint(`${file}:${index + 1}:unsafe-redirect-input`),
|
|
72
|
+
locationLine: index + 1,
|
|
73
|
+
locationPath: normalizePath(cwd, file),
|
|
74
|
+
remediation: 'Validate redirect targets against an allowlist or restrict them to safe internal paths before redirecting.',
|
|
75
|
+
severity: 'HIGH',
|
|
76
|
+
summary: 'Redirect logic appears to consume URL parameters directly, which can introduce open-redirect issues.',
|
|
77
|
+
title: 'Potential open redirect from untrusted URL input',
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
return findings;
|
|
81
|
+
}
|
|
82
|
+
function findCookiesMissingSecurityFlags(file, content, cwd) {
|
|
83
|
+
const findings = [];
|
|
84
|
+
const lines = content.split(/\r?\n/);
|
|
85
|
+
lines.forEach((line, index) => {
|
|
86
|
+
if (!line.includes('cookies().set(') && !line.includes('Set-Cookie')) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const context = lines.slice(index, index + 4).join('\n');
|
|
90
|
+
const hasHttpOnly = context.includes('httpOnly: true') || context.includes('HttpOnly');
|
|
91
|
+
const hasSecure = context.includes('secure: true') || context.includes('Secure');
|
|
92
|
+
if (hasHttpOnly && hasSecure) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
findings.push({
|
|
96
|
+
category: 'app-security',
|
|
97
|
+
checkId: 'cookie-missing-security-flags',
|
|
98
|
+
fingerprint: fingerprint(`${file}:${index + 1}:cookie-missing-security-flags`),
|
|
99
|
+
locationLine: index + 1,
|
|
100
|
+
locationPath: normalizePath(cwd, file),
|
|
101
|
+
remediation: 'Set sensitive cookies with both HttpOnly and Secure flags and review SameSite behavior for the session flow.',
|
|
102
|
+
severity: 'HIGH',
|
|
103
|
+
summary: 'Cookie-setting logic appears to miss one or more important security flags.',
|
|
104
|
+
title: 'Sensitive cookie may be missing security flags',
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
return findings;
|
|
108
|
+
}
|
|
109
|
+
function normalizePath(cwd, file) {
|
|
110
|
+
return file.replace(`${cwd}\\`, '').split('\\').join('/');
|
|
111
|
+
}
|
|
112
|
+
function fingerprint(input) {
|
|
113
|
+
return createHash('sha256').update(input).digest('hex');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=local-scan-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-scan-rules.js","sourceRoot":"","sources":["../src/local-scan-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ValenceClientOptions, ValenceLocalScanOptions, ValenceLocalScanResult } from './types.js';
|
|
2
|
+
export declare function runLocalSecurityScan(clientOptions: ValenceClientOptions, options: ValenceLocalScanOptions): Promise<ValenceLocalScanResult>;
|
|
3
|
+
//# sourceMappingURL=local-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-scan.d.ts","sourceRoot":"","sources":["../src/local-scan.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,oBAAoB,EAEpB,uBAAuB,EACvB,sBAAsB,EACzB,MAAM,YAAY,CAAC;AAcpB,wBAAsB,oBAAoB,CACtC,aAAa,EAAE,oBAAoB,EACnC,OAAO,EAAE,uBAAuB,GACjC,OAAO,CAAC,sBAAsB,CAAC,CAwBjC"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { promises as fs } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import { createValenceClient } from './client.js';
|
|
7
|
+
import { findCodebaseFindings } from './local-scan-rules.js';
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const MAX_FILE_BYTES = 256000;
|
|
10
|
+
const CODE_FILE_EXTENSIONS = new Set(['.js', '.jsx', '.ts', '.tsx']);
|
|
11
|
+
const IGNORE_SEGMENTS = new Set([
|
|
12
|
+
'.git',
|
|
13
|
+
'.next',
|
|
14
|
+
'coverage',
|
|
15
|
+
'dist',
|
|
16
|
+
'node_modules',
|
|
17
|
+
]);
|
|
18
|
+
const SECRET_KEYWORDS = ['API_KEY', 'PASSWORD', 'PRIVATE_KEY', 'SECRET', 'TOKEN'];
|
|
19
|
+
export async function runLocalSecurityScan(clientOptions, options) {
|
|
20
|
+
const cwd = options.cwd ?? process.cwd();
|
|
21
|
+
const findings = dedupeFindings([
|
|
22
|
+
...(await scanCodebase(cwd)),
|
|
23
|
+
...(await scanEnvironmentFiles(cwd)),
|
|
24
|
+
...(await scanDependencyAudit(cwd)),
|
|
25
|
+
]);
|
|
26
|
+
if (findings.length > 0) {
|
|
27
|
+
const client = createValenceClient(clientOptions);
|
|
28
|
+
await client.reportFindings({
|
|
29
|
+
environment: options.environment,
|
|
30
|
+
findings,
|
|
31
|
+
metadata: options.metadata,
|
|
32
|
+
projectId: options.projectId,
|
|
33
|
+
source: 'LOCAL_SCAN',
|
|
34
|
+
workspaceId: options.workspaceId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
findings,
|
|
39
|
+
uploaded: findings.length > 0,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async function scanCodebase(cwd) {
|
|
43
|
+
const files = await collectFiles(cwd);
|
|
44
|
+
const findings = [];
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
const ext = path.extname(file);
|
|
47
|
+
if (!CODE_FILE_EXTENSIONS.has(ext)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const content = await safeReadFile(file);
|
|
51
|
+
if (!content) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
findings.push(...findCodebaseFindings(file, content, cwd));
|
|
55
|
+
}
|
|
56
|
+
return findings;
|
|
57
|
+
}
|
|
58
|
+
async function scanEnvironmentFiles(cwd) {
|
|
59
|
+
const entries = await fs.readdir(cwd, { withFileTypes: true });
|
|
60
|
+
const findings = [];
|
|
61
|
+
for (const entry of entries) {
|
|
62
|
+
if (!entry.isFile() || !entry.name.startsWith('.env')) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const absolutePath = path.join(cwd, entry.name);
|
|
66
|
+
const content = await safeReadFile(absolutePath);
|
|
67
|
+
if (!content) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const lines = content.split(/\r?\n/);
|
|
71
|
+
lines.forEach((line, index) => {
|
|
72
|
+
const trimmed = line.trim();
|
|
73
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const equalsIndex = trimmed.indexOf('=');
|
|
77
|
+
if (equalsIndex === -1) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const key = trimmed.slice(0, equalsIndex).trim();
|
|
81
|
+
if (!key.startsWith('NEXT_PUBLIC_')) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const upperKey = key.toUpperCase();
|
|
85
|
+
if (!SECRET_KEYWORDS.some((keyword) => upperKey.includes(keyword))) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
findings.push({
|
|
89
|
+
category: 'secrets',
|
|
90
|
+
checkId: 'public-env-secret',
|
|
91
|
+
fingerprint: fingerprint(`${absolutePath}:${key}:public-env-secret`),
|
|
92
|
+
locationLine: index + 1,
|
|
93
|
+
locationPath: normalizePath(cwd, absolutePath),
|
|
94
|
+
remediation: 'Move this value to a server-only environment variable and remove the public client exposure.',
|
|
95
|
+
severity: 'CRITICAL',
|
|
96
|
+
summary: 'A public environment variable appears to expose a credential-like value to the client bundle.',
|
|
97
|
+
title: 'Potential secret exposed through public environment variable',
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return findings;
|
|
102
|
+
}
|
|
103
|
+
async function scanDependencyAudit(cwd) {
|
|
104
|
+
try {
|
|
105
|
+
await fs.access(path.join(cwd, 'package.json'));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
let stdout = '';
|
|
111
|
+
try {
|
|
112
|
+
const result = await execFileAsync('npm', ['audit', '--json', '--omit=dev'], {
|
|
113
|
+
cwd,
|
|
114
|
+
windowsHide: true,
|
|
115
|
+
});
|
|
116
|
+
stdout = result.stdout;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
const failure = error;
|
|
120
|
+
stdout = failure.stdout ?? '';
|
|
121
|
+
}
|
|
122
|
+
if (!stdout) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const audit = JSON.parse(stdout);
|
|
127
|
+
return Object.entries(audit.vulnerabilities ?? {}).map(([pkg, details]) => {
|
|
128
|
+
const advisory = details.via?.find((item) => typeof item === 'object' && item !== null)?.title;
|
|
129
|
+
return {
|
|
130
|
+
category: 'dependencies',
|
|
131
|
+
checkId: 'npm-audit',
|
|
132
|
+
fingerprint: fingerprint(`npm-audit:${pkg}:${details.severity ?? 'low'}:${advisory ?? 'unknown'}`),
|
|
133
|
+
metadata: {
|
|
134
|
+
advisory: advisory ?? null,
|
|
135
|
+
fixAvailable: Boolean(details.fixAvailable),
|
|
136
|
+
packageName: pkg,
|
|
137
|
+
},
|
|
138
|
+
remediation: 'Upgrade the package to a fixed version or replace it if no supported fix is available.',
|
|
139
|
+
severity: normalizeAuditSeverity(details.severity),
|
|
140
|
+
summary: advisory
|
|
141
|
+
? `${pkg} has a known vulnerability reported by npm audit: ${advisory}.`
|
|
142
|
+
: `${pkg} has a known vulnerability reported by npm audit.`,
|
|
143
|
+
title: `Vulnerable dependency detected in ${pkg}`,
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function collectFiles(dir) {
|
|
152
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
153
|
+
const results = [];
|
|
154
|
+
for (const entry of entries) {
|
|
155
|
+
if (IGNORE_SEGMENTS.has(entry.name)) {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const absolutePath = path.join(dir, entry.name);
|
|
159
|
+
if (entry.isDirectory()) {
|
|
160
|
+
results.push(...(await collectFiles(absolutePath)));
|
|
161
|
+
}
|
|
162
|
+
else if (entry.isFile()) {
|
|
163
|
+
results.push(absolutePath);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return results;
|
|
167
|
+
}
|
|
168
|
+
async function safeReadFile(file) {
|
|
169
|
+
const stat = await fs.stat(file);
|
|
170
|
+
if (stat.size > MAX_FILE_BYTES) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return fs.readFile(file, 'utf8');
|
|
174
|
+
}
|
|
175
|
+
function normalizePath(cwd, file) {
|
|
176
|
+
return path.relative(cwd, file).split(path.sep).join('/');
|
|
177
|
+
}
|
|
178
|
+
function normalizeAuditSeverity(severity) {
|
|
179
|
+
switch ((severity ?? '').toLowerCase()) {
|
|
180
|
+
case 'critical':
|
|
181
|
+
return 'CRITICAL';
|
|
182
|
+
case 'high':
|
|
183
|
+
return 'HIGH';
|
|
184
|
+
case 'moderate':
|
|
185
|
+
case 'medium':
|
|
186
|
+
return 'MEDIUM';
|
|
187
|
+
default:
|
|
188
|
+
return 'LOW';
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function dedupeFindings(findings) {
|
|
192
|
+
return [...new Map(findings.map((item) => [item.fingerprint, item])).values()];
|
|
193
|
+
}
|
|
194
|
+
function fingerprint(input) {
|
|
195
|
+
return createHash('sha256').update(input).digest('hex');
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=local-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-scan.js","sourceRoot":"","sources":["../src/local-scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DecisionResponse, ToolEvent, ToolExecutionHooks, ValenceFinding, ValenceRuntimeFindingOptions } from './types.js';
|
|
2
|
+
import { createValenceClient } from './client.js';
|
|
3
|
+
type ValenceClient = Pick<ReturnType<typeof createValenceClient>, 'reportFindings'>;
|
|
4
|
+
export declare function buildRuntimeDecisionFinding(event: ToolEvent, decision: DecisionResponse, options?: ValenceRuntimeFindingOptions): ValenceFinding | null;
|
|
5
|
+
export declare function reportRuntimeDecisionFinding(client: ValenceClient, event: ToolEvent, decision: DecisionResponse, options?: ValenceRuntimeFindingOptions): Promise<{
|
|
6
|
+
reported: false;
|
|
7
|
+
finding?: undefined;
|
|
8
|
+
} | {
|
|
9
|
+
finding: ValenceFinding;
|
|
10
|
+
reported: true;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function createRuntimeFindingHooks(client: ValenceClient, options?: ValenceRuntimeFindingOptions): ToolExecutionHooks<unknown>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=runtime-findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-findings.d.ts","sourceRoot":"","sources":["../src/runtime-findings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACR,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,4BAA4B,EAE/B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,KAAK,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,CAAC;AAQpF,wBAAgB,2BAA2B,CACvC,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,4BAAiC,GAC3C,cAAc,GAAG,IAAI,CAwCvB;AAED,wBAAsB,4BAA4B,CAC9C,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,4BAAiC;;;;;;GAgB7C;AAED,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,4BAAiC,GAC3C,kBAAkB,CAAC,OAAO,CAAC,CAM7B"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
const riskOrder = {
|
|
3
|
+
LOW: 0,
|
|
4
|
+
MEDIUM: 1,
|
|
5
|
+
HIGH: 2,
|
|
6
|
+
};
|
|
7
|
+
export function buildRuntimeDecisionFinding(event, decision, options = {}) {
|
|
8
|
+
if (!shouldReportDecision(decision, options)) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const runtimeName = options.serviceName ?? event.agentName ?? 'unknown-runtime';
|
|
12
|
+
const title = getRuntimeFindingTitle(decision);
|
|
13
|
+
const summary = getRuntimeFindingSummary(event, decision, runtimeName);
|
|
14
|
+
return {
|
|
15
|
+
category: options.category ?? 'runtime-security',
|
|
16
|
+
checkId: options.checkId ?? `runtime-${decision.decision.toLowerCase()}`,
|
|
17
|
+
fingerprint: fingerprint([
|
|
18
|
+
event.projectId ?? 'unknown-project',
|
|
19
|
+
event.environment,
|
|
20
|
+
runtimeName,
|
|
21
|
+
event.tool,
|
|
22
|
+
event.action,
|
|
23
|
+
decision.decision,
|
|
24
|
+
decision.reason,
|
|
25
|
+
].join(':')),
|
|
26
|
+
metadata: {
|
|
27
|
+
action: event.action,
|
|
28
|
+
approvalId: decision.approvalId,
|
|
29
|
+
goal: event.goal,
|
|
30
|
+
parameters: event.parameters ?? null,
|
|
31
|
+
policyId: decision.policyId,
|
|
32
|
+
reason: decision.reason,
|
|
33
|
+
risk: decision.risk,
|
|
34
|
+
runtimeName,
|
|
35
|
+
sessionId: event.sessionId ?? null,
|
|
36
|
+
tool: event.tool,
|
|
37
|
+
},
|
|
38
|
+
remediation: getRuntimeRemediation(decision),
|
|
39
|
+
severity: getRuntimeSeverity(decision),
|
|
40
|
+
summary,
|
|
41
|
+
title,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export async function reportRuntimeDecisionFinding(client, event, decision, options = {}) {
|
|
45
|
+
const finding = buildRuntimeDecisionFinding(event, decision, options);
|
|
46
|
+
if (!finding || !event.projectId) {
|
|
47
|
+
return { reported: false };
|
|
48
|
+
}
|
|
49
|
+
await client.reportFindings({
|
|
50
|
+
environment: event.environment,
|
|
51
|
+
findings: [finding],
|
|
52
|
+
projectId: event.projectId,
|
|
53
|
+
source: 'RUNTIME',
|
|
54
|
+
workspaceId: event.workspaceId,
|
|
55
|
+
});
|
|
56
|
+
return { finding, reported: true };
|
|
57
|
+
}
|
|
58
|
+
export function createRuntimeFindingHooks(client, options = {}) {
|
|
59
|
+
return {
|
|
60
|
+
async onDecision(decision, event) {
|
|
61
|
+
await reportRuntimeDecisionFinding(client, event, decision, options);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function shouldReportDecision(decision, options) {
|
|
66
|
+
if (decision.decision !== 'ALLOW') {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (!options.includeAllowDecisions) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const minimumRisk = options.minimumRisk ?? 'HIGH';
|
|
73
|
+
return riskOrder[decision.risk] >= riskOrder[minimumRisk];
|
|
74
|
+
}
|
|
75
|
+
function getRuntimeSeverity(decision) {
|
|
76
|
+
if (decision.decision === 'BLOCK') {
|
|
77
|
+
return 'CRITICAL';
|
|
78
|
+
}
|
|
79
|
+
if (decision.decision === 'REQUIRES_APPROVAL') {
|
|
80
|
+
return 'HIGH';
|
|
81
|
+
}
|
|
82
|
+
return decision.risk === 'HIGH' ? 'HIGH' : 'MEDIUM';
|
|
83
|
+
}
|
|
84
|
+
function getRuntimeFindingTitle(decision) {
|
|
85
|
+
if (decision.decision === 'BLOCK') {
|
|
86
|
+
return 'Blocked runtime action detected';
|
|
87
|
+
}
|
|
88
|
+
if (decision.decision === 'REQUIRES_APPROVAL') {
|
|
89
|
+
return 'Runtime action requires approval';
|
|
90
|
+
}
|
|
91
|
+
return 'High-risk runtime action allowed';
|
|
92
|
+
}
|
|
93
|
+
function getRuntimeFindingSummary(event, decision, runtimeName) {
|
|
94
|
+
const actionLabel = `${event.tool}.${event.action}`;
|
|
95
|
+
if (decision.decision === 'BLOCK') {
|
|
96
|
+
return `${runtimeName} attempted ${actionLabel} and Valence blocked it: ${decision.reason}`;
|
|
97
|
+
}
|
|
98
|
+
if (decision.decision === 'REQUIRES_APPROVAL') {
|
|
99
|
+
return `${runtimeName} attempted ${actionLabel} and Valence required approval: ${decision.reason}`;
|
|
100
|
+
}
|
|
101
|
+
return `${runtimeName} executed high-risk action ${actionLabel}. Review whether it should stay allowed: ${decision.reason}`;
|
|
102
|
+
}
|
|
103
|
+
function getRuntimeRemediation(decision) {
|
|
104
|
+
if (decision.decision === 'BLOCK') {
|
|
105
|
+
return 'Review the blocked workflow, narrow the trigger conditions, or update the custom check only if this behavior is expected.';
|
|
106
|
+
}
|
|
107
|
+
if (decision.decision === 'REQUIRES_APPROVAL') {
|
|
108
|
+
return 'Route this action through an explicit approval path or tighten the triggering conditions so only approved cases reach runtime.';
|
|
109
|
+
}
|
|
110
|
+
return 'Review whether this action should become a custom check, approval gate, or stricter runtime control before broader rollout.';
|
|
111
|
+
}
|
|
112
|
+
function fingerprint(input) {
|
|
113
|
+
return createHash('sha256').update(input).digest('hex');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=runtime-findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-findings.js","sourceRoot":"","sources":["../src/runtime-findings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAazC,MAAM,SAAS,GAAgC;IAC3C,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,UAAU,2BAA2B,CACvC,KAAgB,EAChB,QAA0B,EAC1B,UAAwC,EAAE;IAE1C,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS,IAAI,iBAAiB,CAAC;IAChF,MAAM,KAAK,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,wBAAwB,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEvE,OAAO;QACH,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,kBAAkB;QAChD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,WAAW,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE;QACxE,WAAW,EAAE,WAAW,CACpB;YACI,KAAK,CAAC,SAAS,IAAI,iBAAiB;YACpC,KAAK,CAAC,WAAW;YACjB,WAAW;YACX,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,MAAM;YACZ,QAAQ,CAAC,QAAQ;YACjB,QAAQ,CAAC,MAAM;SAClB,CAAC,IAAI,CAAC,GAAG,CAAC,CACd;QACD,QAAQ,EAAE;YACN,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,WAAW;YACX,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;YAClC,IAAI,EAAE,KAAK,CAAC,IAAI;SACnB;QACD,WAAW,EAAE,qBAAqB,CAAC,QAAQ,CAAC;QAC5C,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,CAAC;QACtC,OAAO;QACP,KAAK;KACR,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAC9C,MAAqB,EACrB,KAAgB,EAChB,QAA0B,EAC1B,UAAwC,EAAE;IAE1C,MAAM,OAAO,GAAG,2BAA2B,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtE,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,QAAQ,EAAE,KAAc,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,MAAM,CAAC,cAAc,CAAC;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,KAAK,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAa,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,yBAAyB,CACrC,MAAqB,EACrB,UAAwC,EAAE;IAE1C,OAAO;QACH,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK;YAC5B,MAAM,4BAA4B,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzE,CAAC;KACJ,CAAC;AACN,CAAC;AAED,SAAS,oBAAoB,CACzB,QAA0B,EAC1B,OAAqC;IAErC,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC;IAClD,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,WAAW,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,kBAAkB,CAAC,QAA0B;IAClD,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;AACxD,CAAC;AAED,SAAS,sBAAsB,CAAC,QAA0B;IACtD,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,iCAAiC,CAAC;IAC7C,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QAC5C,OAAO,kCAAkC,CAAC;IAC9C,CAAC;IAED,OAAO,kCAAkC,CAAC;AAC9C,CAAC;AAED,SAAS,wBAAwB,CAC7B,KAAgB,EAChB,QAA0B,EAC1B,WAAmB;IAEnB,MAAM,WAAW,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IAEpD,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,GAAG,WAAW,cAAc,WAAW,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC;IAChG,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QAC5C,OAAO,GAAG,WAAW,cAAc,WAAW,mCAAmC,QAAQ,CAAC,MAAM,EAAE,CAAC;IACvG,CAAC;IAED,OAAO,GAAG,WAAW,8BAA8B,WAAW,4CAA4C,QAAQ,CAAC,MAAM,EAAE,CAAC;AAChI,CAAC;AAED,SAAS,qBAAqB,CAAC,QAA0B;IACrD,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO,2HAA2H,CAAC;IACvI,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QAC5C,OAAO,gIAAgI,CAAC;IAC5I,CAAC;IAED,OAAO,6HAA6H,CAAC;AACzI,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type ValenceDecision = 'ALLOW' | 'BLOCK' | 'REQUIRES_APPROVAL';
|
|
|
2
2
|
export type ValenceRisk = 'LOW' | 'MEDIUM' | 'HIGH';
|
|
3
3
|
export type ValenceEnvironment = 'production' | 'staging' | 'sandbox';
|
|
4
4
|
export type ToolParameters = Record<string, unknown>;
|
|
5
|
+
export type FindingSource = 'LOCAL_SCAN' | 'CI_SCAN' | 'RUNTIME';
|
|
6
|
+
export type FindingSeverity = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
5
7
|
export type ToolEvent = {
|
|
6
8
|
agentId?: string;
|
|
7
9
|
agentName: string;
|
|
@@ -24,6 +26,26 @@ export type DecisionResponse = {
|
|
|
24
26
|
approvalId: string | null;
|
|
25
27
|
latencyMs: number;
|
|
26
28
|
};
|
|
29
|
+
export type ValenceFinding = {
|
|
30
|
+
category: string;
|
|
31
|
+
checkId?: string;
|
|
32
|
+
fingerprint: string;
|
|
33
|
+
locationLine?: number;
|
|
34
|
+
locationPath?: string;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
remediation: string;
|
|
37
|
+
severity: FindingSeverity;
|
|
38
|
+
summary: string;
|
|
39
|
+
title: string;
|
|
40
|
+
};
|
|
41
|
+
export type FindingBatch = {
|
|
42
|
+
environment?: ValenceEnvironment;
|
|
43
|
+
findings: ValenceFinding[];
|
|
44
|
+
metadata?: Record<string, unknown>;
|
|
45
|
+
projectId: string;
|
|
46
|
+
source: FindingSource;
|
|
47
|
+
workspaceId?: string;
|
|
48
|
+
};
|
|
27
49
|
export type ToolExecutionContext = Omit<ToolEvent, 'tool' | 'action' | 'parameters' | 'timestamp'>;
|
|
28
50
|
export type ToolDefinition = {
|
|
29
51
|
tool: string;
|
|
@@ -46,6 +68,25 @@ export type ValenceClientOptions = {
|
|
|
46
68
|
timeoutMs?: number;
|
|
47
69
|
headers?: Record<string, string>;
|
|
48
70
|
decidePath?: string;
|
|
71
|
+
findingsPath?: string;
|
|
49
72
|
simulatePath?: string;
|
|
50
73
|
};
|
|
74
|
+
export type ValenceLocalScanOptions = {
|
|
75
|
+
metadata?: Record<string, unknown>;
|
|
76
|
+
cwd?: string;
|
|
77
|
+
environment: ValenceEnvironment;
|
|
78
|
+
projectId: string;
|
|
79
|
+
workspaceId?: string;
|
|
80
|
+
};
|
|
81
|
+
export type ValenceLocalScanResult = {
|
|
82
|
+
findings: ValenceFinding[];
|
|
83
|
+
uploaded: boolean;
|
|
84
|
+
};
|
|
85
|
+
export type ValenceRuntimeFindingOptions = {
|
|
86
|
+
category?: string;
|
|
87
|
+
checkId?: string;
|
|
88
|
+
includeAllowDecisions?: boolean;
|
|
89
|
+
minimumRisk?: ValenceRisk;
|
|
90
|
+
serviceName?: string;
|
|
91
|
+
};
|
|
51
92
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,mBAAmB,CAAC;AACtE,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AACpD,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;AACtE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valence-ai/sdk",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "SDK for connecting applications to Valence AI for security issues, runtime signals, and optional runtime review flows.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/praveensahu-dev/Valence-AI.git",
|
|
@@ -41,11 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"keywords": [
|
|
43
43
|
"ai",
|
|
44
|
-
"agent",
|
|
45
44
|
"sdk",
|
|
46
45
|
"security",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
46
|
+
"appsec",
|
|
47
|
+
"issues",
|
|
48
|
+
"runtime",
|
|
49
|
+
"scanner",
|
|
50
|
+
"guardrails"
|
|
50
51
|
]
|
|
51
52
|
}
|