@grwnd/pi-governance 1.4.1 → 1.5.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/index.d.cts CHANGED
@@ -58,6 +58,37 @@ declare const GovernanceConfigSchema: _sinclair_typebox.TObject<{
58
58
  connection: _sinclair_typebox.TString;
59
59
  }>]>>;
60
60
  }>>;
61
+ dlp: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
62
+ enabled: _sinclair_typebox.TBoolean;
63
+ mode: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
64
+ on_input: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
65
+ on_output: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
66
+ masking: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
67
+ strategy: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"partial">, _sinclair_typebox.TLiteral<"full">, _sinclair_typebox.TLiteral<"hash">]>;
68
+ show_chars: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
69
+ placeholder: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
70
+ }>>;
71
+ severity_threshold: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"low">, _sinclair_typebox.TLiteral<"medium">, _sinclair_typebox.TLiteral<"high">, _sinclair_typebox.TLiteral<"critical">]>>;
72
+ built_in: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
73
+ secrets: _sinclair_typebox.TBoolean;
74
+ pii: _sinclair_typebox.TBoolean;
75
+ }>>;
76
+ custom_patterns: _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TObject<{
77
+ name: _sinclair_typebox.TString;
78
+ pattern: _sinclair_typebox.TString;
79
+ severity: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"low">, _sinclair_typebox.TLiteral<"medium">, _sinclair_typebox.TLiteral<"high">, _sinclair_typebox.TLiteral<"critical">]>;
80
+ action: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
81
+ }>>>;
82
+ allowlist: _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TObject<{
83
+ pattern: _sinclair_typebox.TString;
84
+ }>>>;
85
+ role_overrides: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TObject<{
86
+ enabled: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
87
+ mode: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
88
+ on_input: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
89
+ on_output: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
90
+ }>>>;
91
+ }>>;
61
92
  org_units: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TObject<{
62
93
  hitl: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
63
94
  default_mode: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"autonomous">, _sinclair_typebox.TLiteral<"supervised">, _sinclair_typebox.TLiteral<"dry_run">]>>;
@@ -237,6 +268,78 @@ declare class BashClassifier {
237
268
  declare const SAFE_PATTERNS: RegExp[];
238
269
  declare const DANGEROUS_PATTERNS: RegExp[];
239
270
 
271
+ type DlpSeverity = 'low' | 'medium' | 'high' | 'critical';
272
+ type DlpCategory = 'secret' | 'pii' | 'custom';
273
+ interface DlpPatternDef {
274
+ name: string;
275
+ pattern: RegExp;
276
+ severity: DlpSeverity;
277
+ category: DlpCategory;
278
+ }
279
+ declare const SECRET_PATTERNS: DlpPatternDef[];
280
+ declare const PII_PATTERNS: DlpPatternDef[];
281
+
282
+ type DlpAction = 'audit' | 'mask' | 'block';
283
+ interface DlpMatch {
284
+ patternName: string;
285
+ category: DlpCategory;
286
+ severity: DlpSeverity;
287
+ start: number;
288
+ end: number;
289
+ matched: string;
290
+ }
291
+ interface DlpScanResult {
292
+ hasMatches: boolean;
293
+ matches: DlpMatch[];
294
+ }
295
+ interface DlpCustomPattern {
296
+ name: string;
297
+ pattern: string;
298
+ severity: DlpSeverity;
299
+ action?: DlpAction;
300
+ }
301
+ interface DlpAllowlistEntry {
302
+ pattern: string;
303
+ }
304
+ interface DlpScannerConfig {
305
+ enabled: boolean;
306
+ mode: DlpAction;
307
+ on_input?: DlpAction;
308
+ on_output?: DlpAction;
309
+ severity_threshold: DlpSeverity;
310
+ built_in: {
311
+ secrets: boolean;
312
+ pii: boolean;
313
+ };
314
+ custom_patterns: DlpCustomPattern[];
315
+ allowlist: DlpAllowlistEntry[];
316
+ pattern_overrides: Map<string, DlpAction>;
317
+ }
318
+ declare class DlpScanner {
319
+ private patterns;
320
+ private allowlistRegexps;
321
+ private severityThreshold;
322
+ private config;
323
+ constructor(config: DlpScannerConfig);
324
+ scan(text: string): DlpScanResult;
325
+ getAction(direction: 'input' | 'output'): DlpAction;
326
+ getPatternAction(match: DlpMatch, direction: 'input' | 'output'): DlpAction;
327
+ private isAllowlisted;
328
+ }
329
+ declare function compareSeverity(a: DlpSeverity, b: DlpSeverity): number;
330
+
331
+ interface MaskingConfig {
332
+ strategy: 'partial' | 'full' | 'hash';
333
+ show_chars: number;
334
+ placeholder: string;
335
+ }
336
+ declare class DlpMasker {
337
+ private config;
338
+ constructor(config?: Partial<MaskingConfig>);
339
+ maskValue(value: string): string;
340
+ maskText(text: string, matches: DlpMatch[]): string;
341
+ }
342
+
240
343
  /**
241
344
  * Tracks tool invocation count as a proxy for token budget.
242
345
  * The budget value represents max invocations per session; -1 means unlimited.
@@ -299,7 +402,7 @@ interface AuditSink {
299
402
  flush(): Promise<void>;
300
403
  }
301
404
 
302
- type AuditEventType = 'session_start' | 'session_end' | 'tool_allowed' | 'tool_denied' | 'tool_dry_run' | 'tool_result' | 'bash_denied' | 'path_denied' | 'approval_requested' | 'approval_granted' | 'approval_denied' | 'budget_exceeded' | 'config_reloaded';
405
+ type AuditEventType = 'session_start' | 'session_end' | 'tool_allowed' | 'tool_denied' | 'tool_dry_run' | 'tool_result' | 'bash_denied' | 'path_denied' | 'approval_requested' | 'approval_granted' | 'approval_denied' | 'budget_exceeded' | 'config_reloaded' | 'dlp_blocked' | 'dlp_detected' | 'dlp_masked';
303
406
  interface AuditRecord {
304
407
  id: string;
305
408
  timestamp: string;
@@ -407,4 +510,4 @@ declare class WebhookApprover implements ApprovalFlow {
407
510
  }): Promise<ApprovalResult>;
408
511
  }
409
512
 
410
- export { type ApprovalFlow, type ApprovalResult, type AuditEventType, AuditLogger, type AuditRecord, type AuditSink, type BashClassification, BashClassifier, type BashOverrides, BudgetTracker, CliApprover, ConfigValidationError, ConfigWatcher, type ConfirmUI, DANGEROUS_PATTERNS, EnvIdentityProvider, type ExecutionMode, type FactStore, type GovernanceConfig, type GovernanceToolCall, type HitlConfig, IdentityChain, type IdentityProvider, JsonlAuditSink, LocalIdentityProvider, OsoMemoryFactStore, type PathOperation, type PolicyDecision, type PolicyEngine, type Relation, type ResolvedIdentity, type RoleBinding, SAFE_PATTERNS, TemplateSelector, type TemplateSelectorConfig, WebhookApprover, WebhookAuditSink, YamlFactStore, YamlPolicyEngine, type YamlRole, type YamlRules, createApprovalFlow, createIdentityChain, createPolicyEngine, loadConfig, render as renderTemplate };
513
+ export { type ApprovalFlow, type ApprovalResult, type AuditEventType, AuditLogger, type AuditRecord, type AuditSink, type BashClassification, BashClassifier, type BashOverrides, BudgetTracker, CliApprover, ConfigValidationError, ConfigWatcher, type ConfirmUI, DANGEROUS_PATTERNS, PII_PATTERNS as DLP_PII_PATTERNS, SECRET_PATTERNS as DLP_SECRET_PATTERNS, type DlpAction, type DlpAllowlistEntry, type DlpCategory, type DlpCustomPattern, DlpMasker, type DlpMatch, type DlpPatternDef, type DlpScanResult, DlpScanner, type DlpScannerConfig, type DlpSeverity, EnvIdentityProvider, type ExecutionMode, type FactStore, type GovernanceConfig, type GovernanceToolCall, type HitlConfig, IdentityChain, type IdentityProvider, JsonlAuditSink, LocalIdentityProvider, type MaskingConfig, OsoMemoryFactStore, type PathOperation, type PolicyDecision, type PolicyEngine, type Relation, type ResolvedIdentity, type RoleBinding, SAFE_PATTERNS, TemplateSelector, type TemplateSelectorConfig, WebhookApprover, WebhookAuditSink, YamlFactStore, YamlPolicyEngine, type YamlRole, type YamlRules, compareSeverity, createApprovalFlow, createIdentityChain, createPolicyEngine, loadConfig, render as renderTemplate };
package/dist/index.d.ts CHANGED
@@ -58,6 +58,37 @@ declare const GovernanceConfigSchema: _sinclair_typebox.TObject<{
58
58
  connection: _sinclair_typebox.TString;
59
59
  }>]>>;
60
60
  }>>;
61
+ dlp: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
62
+ enabled: _sinclair_typebox.TBoolean;
63
+ mode: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
64
+ on_input: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
65
+ on_output: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
66
+ masking: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
67
+ strategy: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"partial">, _sinclair_typebox.TLiteral<"full">, _sinclair_typebox.TLiteral<"hash">]>;
68
+ show_chars: _sinclair_typebox.TOptional<_sinclair_typebox.TNumber>;
69
+ placeholder: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
70
+ }>>;
71
+ severity_threshold: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"low">, _sinclair_typebox.TLiteral<"medium">, _sinclair_typebox.TLiteral<"high">, _sinclair_typebox.TLiteral<"critical">]>>;
72
+ built_in: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
73
+ secrets: _sinclair_typebox.TBoolean;
74
+ pii: _sinclair_typebox.TBoolean;
75
+ }>>;
76
+ custom_patterns: _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TObject<{
77
+ name: _sinclair_typebox.TString;
78
+ pattern: _sinclair_typebox.TString;
79
+ severity: _sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"low">, _sinclair_typebox.TLiteral<"medium">, _sinclair_typebox.TLiteral<"high">, _sinclair_typebox.TLiteral<"critical">]>;
80
+ action: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
81
+ }>>>;
82
+ allowlist: _sinclair_typebox.TOptional<_sinclair_typebox.TArray<_sinclair_typebox.TObject<{
83
+ pattern: _sinclair_typebox.TString;
84
+ }>>>;
85
+ role_overrides: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TObject<{
86
+ enabled: _sinclair_typebox.TOptional<_sinclair_typebox.TBoolean>;
87
+ mode: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
88
+ on_input: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
89
+ on_output: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"audit">, _sinclair_typebox.TLiteral<"mask">, _sinclair_typebox.TLiteral<"block">]>>;
90
+ }>>>;
91
+ }>>;
61
92
  org_units: _sinclair_typebox.TOptional<_sinclair_typebox.TRecord<_sinclair_typebox.TString, _sinclair_typebox.TObject<{
62
93
  hitl: _sinclair_typebox.TOptional<_sinclair_typebox.TObject<{
63
94
  default_mode: _sinclair_typebox.TOptional<_sinclair_typebox.TUnion<[_sinclair_typebox.TLiteral<"autonomous">, _sinclair_typebox.TLiteral<"supervised">, _sinclair_typebox.TLiteral<"dry_run">]>>;
@@ -237,6 +268,78 @@ declare class BashClassifier {
237
268
  declare const SAFE_PATTERNS: RegExp[];
238
269
  declare const DANGEROUS_PATTERNS: RegExp[];
239
270
 
271
+ type DlpSeverity = 'low' | 'medium' | 'high' | 'critical';
272
+ type DlpCategory = 'secret' | 'pii' | 'custom';
273
+ interface DlpPatternDef {
274
+ name: string;
275
+ pattern: RegExp;
276
+ severity: DlpSeverity;
277
+ category: DlpCategory;
278
+ }
279
+ declare const SECRET_PATTERNS: DlpPatternDef[];
280
+ declare const PII_PATTERNS: DlpPatternDef[];
281
+
282
+ type DlpAction = 'audit' | 'mask' | 'block';
283
+ interface DlpMatch {
284
+ patternName: string;
285
+ category: DlpCategory;
286
+ severity: DlpSeverity;
287
+ start: number;
288
+ end: number;
289
+ matched: string;
290
+ }
291
+ interface DlpScanResult {
292
+ hasMatches: boolean;
293
+ matches: DlpMatch[];
294
+ }
295
+ interface DlpCustomPattern {
296
+ name: string;
297
+ pattern: string;
298
+ severity: DlpSeverity;
299
+ action?: DlpAction;
300
+ }
301
+ interface DlpAllowlistEntry {
302
+ pattern: string;
303
+ }
304
+ interface DlpScannerConfig {
305
+ enabled: boolean;
306
+ mode: DlpAction;
307
+ on_input?: DlpAction;
308
+ on_output?: DlpAction;
309
+ severity_threshold: DlpSeverity;
310
+ built_in: {
311
+ secrets: boolean;
312
+ pii: boolean;
313
+ };
314
+ custom_patterns: DlpCustomPattern[];
315
+ allowlist: DlpAllowlistEntry[];
316
+ pattern_overrides: Map<string, DlpAction>;
317
+ }
318
+ declare class DlpScanner {
319
+ private patterns;
320
+ private allowlistRegexps;
321
+ private severityThreshold;
322
+ private config;
323
+ constructor(config: DlpScannerConfig);
324
+ scan(text: string): DlpScanResult;
325
+ getAction(direction: 'input' | 'output'): DlpAction;
326
+ getPatternAction(match: DlpMatch, direction: 'input' | 'output'): DlpAction;
327
+ private isAllowlisted;
328
+ }
329
+ declare function compareSeverity(a: DlpSeverity, b: DlpSeverity): number;
330
+
331
+ interface MaskingConfig {
332
+ strategy: 'partial' | 'full' | 'hash';
333
+ show_chars: number;
334
+ placeholder: string;
335
+ }
336
+ declare class DlpMasker {
337
+ private config;
338
+ constructor(config?: Partial<MaskingConfig>);
339
+ maskValue(value: string): string;
340
+ maskText(text: string, matches: DlpMatch[]): string;
341
+ }
342
+
240
343
  /**
241
344
  * Tracks tool invocation count as a proxy for token budget.
242
345
  * The budget value represents max invocations per session; -1 means unlimited.
@@ -299,7 +402,7 @@ interface AuditSink {
299
402
  flush(): Promise<void>;
300
403
  }
301
404
 
302
- type AuditEventType = 'session_start' | 'session_end' | 'tool_allowed' | 'tool_denied' | 'tool_dry_run' | 'tool_result' | 'bash_denied' | 'path_denied' | 'approval_requested' | 'approval_granted' | 'approval_denied' | 'budget_exceeded' | 'config_reloaded';
405
+ type AuditEventType = 'session_start' | 'session_end' | 'tool_allowed' | 'tool_denied' | 'tool_dry_run' | 'tool_result' | 'bash_denied' | 'path_denied' | 'approval_requested' | 'approval_granted' | 'approval_denied' | 'budget_exceeded' | 'config_reloaded' | 'dlp_blocked' | 'dlp_detected' | 'dlp_masked';
303
406
  interface AuditRecord {
304
407
  id: string;
305
408
  timestamp: string;
@@ -407,4 +510,4 @@ declare class WebhookApprover implements ApprovalFlow {
407
510
  }): Promise<ApprovalResult>;
408
511
  }
409
512
 
410
- export { type ApprovalFlow, type ApprovalResult, type AuditEventType, AuditLogger, type AuditRecord, type AuditSink, type BashClassification, BashClassifier, type BashOverrides, BudgetTracker, CliApprover, ConfigValidationError, ConfigWatcher, type ConfirmUI, DANGEROUS_PATTERNS, EnvIdentityProvider, type ExecutionMode, type FactStore, type GovernanceConfig, type GovernanceToolCall, type HitlConfig, IdentityChain, type IdentityProvider, JsonlAuditSink, LocalIdentityProvider, OsoMemoryFactStore, type PathOperation, type PolicyDecision, type PolicyEngine, type Relation, type ResolvedIdentity, type RoleBinding, SAFE_PATTERNS, TemplateSelector, type TemplateSelectorConfig, WebhookApprover, WebhookAuditSink, YamlFactStore, YamlPolicyEngine, type YamlRole, type YamlRules, createApprovalFlow, createIdentityChain, createPolicyEngine, loadConfig, render as renderTemplate };
513
+ export { type ApprovalFlow, type ApprovalResult, type AuditEventType, AuditLogger, type AuditRecord, type AuditSink, type BashClassification, BashClassifier, type BashOverrides, BudgetTracker, CliApprover, ConfigValidationError, ConfigWatcher, type ConfirmUI, DANGEROUS_PATTERNS, PII_PATTERNS as DLP_PII_PATTERNS, SECRET_PATTERNS as DLP_SECRET_PATTERNS, type DlpAction, type DlpAllowlistEntry, type DlpCategory, type DlpCustomPattern, DlpMasker, type DlpMatch, type DlpPatternDef, type DlpScanResult, DlpScanner, type DlpScannerConfig, type DlpSeverity, EnvIdentityProvider, type ExecutionMode, type FactStore, type GovernanceConfig, type GovernanceToolCall, type HitlConfig, IdentityChain, type IdentityProvider, JsonlAuditSink, LocalIdentityProvider, type MaskingConfig, OsoMemoryFactStore, type PathOperation, type PolicyDecision, type PolicyEngine, type Relation, type ResolvedIdentity, type RoleBinding, SAFE_PATTERNS, TemplateSelector, type TemplateSelectorConfig, WebhookApprover, WebhookAuditSink, YamlFactStore, YamlPolicyEngine, type YamlRole, type YamlRules, compareSeverity, createApprovalFlow, createIdentityChain, createPolicyEngine, loadConfig, render as renderTemplate };
package/dist/index.js CHANGED
@@ -3831,12 +3831,78 @@ var OrgUnitOverride = Type.Object({
3831
3831
  })
3832
3832
  )
3833
3833
  });
3834
+ var DlpMaskingConfig = Type.Object({
3835
+ strategy: Type.Union([Type.Literal("partial"), Type.Literal("full"), Type.Literal("hash")], {
3836
+ default: "partial"
3837
+ }),
3838
+ show_chars: Type.Optional(Type.Number({ default: 4, minimum: 0 })),
3839
+ placeholder: Type.Optional(Type.String({ default: "***" }))
3840
+ });
3841
+ var DlpCustomPatternConfig = Type.Object({
3842
+ name: Type.String(),
3843
+ pattern: Type.String(),
3844
+ severity: Type.Union([
3845
+ Type.Literal("low"),
3846
+ Type.Literal("medium"),
3847
+ Type.Literal("high"),
3848
+ Type.Literal("critical")
3849
+ ]),
3850
+ action: Type.Optional(
3851
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")])
3852
+ )
3853
+ });
3854
+ var DlpAllowlistEntryConfig = Type.Object({
3855
+ pattern: Type.String()
3856
+ });
3857
+ var DlpRoleOverrideConfig = Type.Object({
3858
+ enabled: Type.Optional(Type.Boolean()),
3859
+ mode: Type.Optional(
3860
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")])
3861
+ ),
3862
+ on_input: Type.Optional(
3863
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")])
3864
+ ),
3865
+ on_output: Type.Optional(
3866
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")])
3867
+ )
3868
+ });
3869
+ var DlpConfig = Type.Object({
3870
+ enabled: Type.Boolean({ default: false }),
3871
+ mode: Type.Optional(
3872
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")], {
3873
+ default: "audit"
3874
+ })
3875
+ ),
3876
+ on_input: Type.Optional(
3877
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")])
3878
+ ),
3879
+ on_output: Type.Optional(
3880
+ Type.Union([Type.Literal("audit"), Type.Literal("mask"), Type.Literal("block")])
3881
+ ),
3882
+ masking: Type.Optional(DlpMaskingConfig),
3883
+ severity_threshold: Type.Optional(
3884
+ Type.Union(
3885
+ [Type.Literal("low"), Type.Literal("medium"), Type.Literal("high"), Type.Literal("critical")],
3886
+ { default: "low" }
3887
+ )
3888
+ ),
3889
+ built_in: Type.Optional(
3890
+ Type.Object({
3891
+ secrets: Type.Boolean({ default: true }),
3892
+ pii: Type.Boolean({ default: true })
3893
+ })
3894
+ ),
3895
+ custom_patterns: Type.Optional(Type.Array(DlpCustomPatternConfig)),
3896
+ allowlist: Type.Optional(Type.Array(DlpAllowlistEntryConfig)),
3897
+ role_overrides: Type.Optional(Type.Record(Type.String(), DlpRoleOverrideConfig))
3898
+ });
3834
3899
  var GovernanceConfigSchema = Type.Object({
3835
3900
  auth: Type.Optional(AuthConfig),
3836
3901
  policy: Type.Optional(PolicyConfig),
3837
3902
  templates: Type.Optional(TemplatesConfig),
3838
3903
  hitl: Type.Optional(HitlConfig),
3839
3904
  audit: Type.Optional(AuditConfig),
3905
+ dlp: Type.Optional(DlpConfig),
3840
3906
  org_units: Type.Optional(Type.Record(Type.String(), OrgUnitOverride))
3841
3907
  });
3842
3908
 
@@ -3867,6 +3933,9 @@ var DEFAULTS = {
3867
3933
  },
3868
3934
  audit: {
3869
3935
  sinks: [{ type: "jsonl", path: "~/.pi/agent/audit.jsonl" }]
3936
+ },
3937
+ dlp: {
3938
+ enabled: false
3870
3939
  }
3871
3940
  };
3872
3941
 
@@ -4338,6 +4407,300 @@ var BashClassifier = class {
4338
4407
  }
4339
4408
  };
4340
4409
 
4410
+ // src/lib/dlp/patterns.ts
4411
+ var SECRET_PATTERNS = [
4412
+ // AWS
4413
+ {
4414
+ name: "aws_access_key",
4415
+ pattern: /\b(AKIA[0-9A-Z]{16})\b/g,
4416
+ severity: "critical",
4417
+ category: "secret"
4418
+ },
4419
+ {
4420
+ name: "aws_secret_key",
4421
+ pattern: /\b([A-Za-z0-9/+=]{40})(?=\s|$|"|')/g,
4422
+ severity: "critical",
4423
+ category: "secret"
4424
+ },
4425
+ // GitHub
4426
+ {
4427
+ name: "github_pat",
4428
+ pattern: /\b(ghp_[A-Za-z0-9]{36,})\b/g,
4429
+ severity: "critical",
4430
+ category: "secret"
4431
+ },
4432
+ {
4433
+ name: "github_oauth",
4434
+ pattern: /\b(gho_[A-Za-z0-9]{36,})\b/g,
4435
+ severity: "high",
4436
+ category: "secret"
4437
+ },
4438
+ {
4439
+ name: "github_app_token",
4440
+ pattern: /\b(ghu_[A-Za-z0-9]{36,})\b/g,
4441
+ severity: "high",
4442
+ category: "secret"
4443
+ },
4444
+ // Anthropic
4445
+ {
4446
+ name: "anthropic_api_key",
4447
+ pattern: /\b(sk-ant-api03-[A-Za-z0-9_-]{90,})\b/g,
4448
+ severity: "critical",
4449
+ category: "secret"
4450
+ },
4451
+ // OpenAI
4452
+ {
4453
+ name: "openai_api_key",
4454
+ pattern: /\b(sk-[A-Za-z0-9]{20,}T3BlbkFJ[A-Za-z0-9]{20,})\b/g,
4455
+ severity: "critical",
4456
+ category: "secret"
4457
+ },
4458
+ // JWT
4459
+ {
4460
+ name: "jwt_token",
4461
+ pattern: /\b(eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,})\b/g,
4462
+ severity: "high",
4463
+ category: "secret"
4464
+ },
4465
+ // Private key headers
4466
+ {
4467
+ name: "private_key",
4468
+ pattern: /-----BEGIN\s+(RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,
4469
+ severity: "critical",
4470
+ category: "secret"
4471
+ },
4472
+ // Database connection strings
4473
+ {
4474
+ name: "database_url",
4475
+ pattern: /\b((?:postgres|mysql|mongodb|redis):\/\/[^\s'"]{10,})\b/g,
4476
+ severity: "high",
4477
+ category: "secret"
4478
+ },
4479
+ // Slack
4480
+ {
4481
+ name: "slack_token",
4482
+ pattern: /\b(xox[bpras]-[A-Za-z0-9-]{10,})\b/g,
4483
+ severity: "high",
4484
+ category: "secret"
4485
+ },
4486
+ // Stripe
4487
+ {
4488
+ name: "stripe_key",
4489
+ pattern: /\b([rs]k_(?:live|test)_[A-Za-z0-9]{20,})\b/g,
4490
+ severity: "critical",
4491
+ category: "secret"
4492
+ },
4493
+ // npm
4494
+ {
4495
+ name: "npm_token",
4496
+ pattern: /\b(npm_[A-Za-z0-9]{36,})\b/g,
4497
+ severity: "high",
4498
+ category: "secret"
4499
+ },
4500
+ // SendGrid
4501
+ {
4502
+ name: "sendgrid_key",
4503
+ pattern: /\b(SG\.[A-Za-z0-9_-]{22,}\.[A-Za-z0-9_-]{22,})\b/g,
4504
+ severity: "high",
4505
+ category: "secret"
4506
+ },
4507
+ // Generic API key patterns (env-var style assignments)
4508
+ {
4509
+ name: "generic_api_key",
4510
+ pattern: /\b(?:API_KEY|API_SECRET|ACCESS_TOKEN|AUTH_TOKEN|SECRET_KEY)\s*[=:]\s*['"]?([A-Za-z0-9_-]{16,})['"]?/gi,
4511
+ severity: "medium",
4512
+ category: "secret"
4513
+ },
4514
+ // High-entropy string near keyword context
4515
+ {
4516
+ name: "generic_secret_assignment",
4517
+ pattern: /\b(?:password|passwd|secret|token|credential)\s*[=:]\s*['"]([^'"]{8,})['"]?/gi,
4518
+ severity: "medium",
4519
+ category: "secret"
4520
+ }
4521
+ ];
4522
+ var PII_PATTERNS = [
4523
+ // SSN (US)
4524
+ {
4525
+ name: "ssn",
4526
+ pattern: /\b(\d{3}-\d{2}-\d{4})\b/g,
4527
+ severity: "critical",
4528
+ category: "pii"
4529
+ },
4530
+ // Credit card numbers
4531
+ {
4532
+ name: "credit_card",
4533
+ pattern: /\b(4\d{3}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}|5[1-5]\d{2}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}|3[47]\d{2}[\s-]?\d{6}[\s-]?\d{5}|6(?:011|5\d{2})[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4})\b/g,
4534
+ severity: "critical",
4535
+ category: "pii"
4536
+ },
4537
+ // Email address
4538
+ {
4539
+ name: "email",
4540
+ pattern: /\b([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})\b/g,
4541
+ severity: "low",
4542
+ category: "pii"
4543
+ },
4544
+ // US phone number
4545
+ {
4546
+ name: "phone_us",
4547
+ pattern: /\b(\+?1?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4})\b/g,
4548
+ severity: "medium",
4549
+ category: "pii"
4550
+ },
4551
+ // IPv4 address
4552
+ {
4553
+ name: "ipv4",
4554
+ pattern: /\b((?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?))\b/g,
4555
+ severity: "low",
4556
+ category: "pii"
4557
+ }
4558
+ ];
4559
+
4560
+ // src/lib/dlp/scanner.ts
4561
+ var SEVERITY_ORDER = {
4562
+ low: 0,
4563
+ medium: 1,
4564
+ high: 2,
4565
+ critical: 3
4566
+ };
4567
+ var DlpScanner = class {
4568
+ patterns;
4569
+ allowlistRegexps;
4570
+ severityThreshold;
4571
+ config;
4572
+ constructor(config) {
4573
+ this.config = config;
4574
+ this.severityThreshold = SEVERITY_ORDER[config.severity_threshold];
4575
+ this.patterns = [];
4576
+ this.allowlistRegexps = [];
4577
+ if (config.built_in.secrets) {
4578
+ for (const def of SECRET_PATTERNS) {
4579
+ this.patterns.push({ def });
4580
+ }
4581
+ }
4582
+ if (config.built_in.pii) {
4583
+ for (const def of PII_PATTERNS) {
4584
+ this.patterns.push({ def });
4585
+ }
4586
+ }
4587
+ for (const cp of config.custom_patterns) {
4588
+ const def = {
4589
+ name: cp.name,
4590
+ pattern: new RegExp(cp.pattern, "g"),
4591
+ severity: cp.severity,
4592
+ category: "custom"
4593
+ };
4594
+ this.patterns.push({ def, action: cp.action });
4595
+ }
4596
+ for (const compiled of this.patterns) {
4597
+ const override = config.pattern_overrides.get(compiled.def.name);
4598
+ if (override) {
4599
+ compiled.action = override;
4600
+ }
4601
+ }
4602
+ for (const entry of config.allowlist) {
4603
+ this.allowlistRegexps.push(new RegExp(entry.pattern));
4604
+ }
4605
+ }
4606
+ scan(text) {
4607
+ if (!this.config.enabled || text.length === 0) {
4608
+ return { hasMatches: false, matches: [] };
4609
+ }
4610
+ const matches = [];
4611
+ for (const compiled of this.patterns) {
4612
+ if (SEVERITY_ORDER[compiled.def.severity] < this.severityThreshold) {
4613
+ continue;
4614
+ }
4615
+ const regex = new RegExp(compiled.def.pattern.source, compiled.def.pattern.flags);
4616
+ let match;
4617
+ while ((match = regex.exec(text)) !== null) {
4618
+ const matched = match[1] ?? match[0];
4619
+ const start = match[1] ? match.index + match[0].indexOf(match[1]) : match.index;
4620
+ const end = start + matched.length;
4621
+ if (this.isAllowlisted(matched)) {
4622
+ continue;
4623
+ }
4624
+ matches.push({
4625
+ patternName: compiled.def.name,
4626
+ category: compiled.def.category,
4627
+ severity: compiled.def.severity,
4628
+ start,
4629
+ end,
4630
+ matched
4631
+ });
4632
+ }
4633
+ }
4634
+ return { hasMatches: matches.length > 0, matches };
4635
+ }
4636
+ getAction(direction) {
4637
+ if (direction === "input" && this.config.on_input) {
4638
+ return this.config.on_input;
4639
+ }
4640
+ if (direction === "output" && this.config.on_output) {
4641
+ return this.config.on_output;
4642
+ }
4643
+ return this.config.mode;
4644
+ }
4645
+ getPatternAction(match, direction) {
4646
+ const compiled = this.patterns.find((p) => p.def.name === match.patternName);
4647
+ if (compiled?.action) {
4648
+ return compiled.action;
4649
+ }
4650
+ return this.getAction(direction);
4651
+ }
4652
+ isAllowlisted(value) {
4653
+ for (const re of this.allowlistRegexps) {
4654
+ if (re.test(value)) return true;
4655
+ }
4656
+ return false;
4657
+ }
4658
+ };
4659
+ function compareSeverity(a, b) {
4660
+ return SEVERITY_ORDER[a] - SEVERITY_ORDER[b];
4661
+ }
4662
+
4663
+ // src/lib/dlp/masker.ts
4664
+ import { createHash } from "crypto";
4665
+ var DEFAULT_CONFIG = {
4666
+ strategy: "partial",
4667
+ show_chars: 4,
4668
+ placeholder: "***"
4669
+ };
4670
+ var DlpMasker = class {
4671
+ config;
4672
+ constructor(config) {
4673
+ this.config = { ...DEFAULT_CONFIG, ...config };
4674
+ }
4675
+ maskValue(value) {
4676
+ switch (this.config.strategy) {
4677
+ case "full":
4678
+ return this.config.placeholder;
4679
+ case "hash": {
4680
+ const hash = createHash("sha256").update(value).digest("hex").slice(0, 8);
4681
+ return `[REDACTED:${hash}]`;
4682
+ }
4683
+ case "partial":
4684
+ default: {
4685
+ if (value.length <= this.config.show_chars) {
4686
+ return this.config.placeholder;
4687
+ }
4688
+ return this.config.placeholder + value.slice(-this.config.show_chars);
4689
+ }
4690
+ }
4691
+ }
4692
+ maskText(text, matches) {
4693
+ if (matches.length === 0) return text;
4694
+ const sorted = [...matches].sort((a, b) => b.start - a.start);
4695
+ let result = text;
4696
+ for (const match of sorted) {
4697
+ const masked = this.maskValue(match.matched);
4698
+ result = result.slice(0, match.start) + masked + result.slice(match.end);
4699
+ }
4700
+ return result;
4701
+ }
4702
+ };
4703
+
4341
4704
  // src/lib/budget/tracker.ts
4342
4705
  var BudgetTracker = class {
4343
4706
  _used = 0;
@@ -4682,6 +5045,10 @@ export {
4682
5045
  ConfigValidationError,
4683
5046
  ConfigWatcher,
4684
5047
  DANGEROUS_PATTERNS,
5048
+ PII_PATTERNS as DLP_PII_PATTERNS,
5049
+ SECRET_PATTERNS as DLP_SECRET_PATTERNS,
5050
+ DlpMasker,
5051
+ DlpScanner,
4685
5052
  EnvIdentityProvider,
4686
5053
  IdentityChain,
4687
5054
  JsonlAuditSink,
@@ -4693,6 +5060,7 @@ export {
4693
5060
  WebhookAuditSink,
4694
5061
  YamlFactStore,
4695
5062
  YamlPolicyEngine,
5063
+ compareSeverity,
4696
5064
  createApprovalFlow,
4697
5065
  createIdentityChain,
4698
5066
  createPolicyEngine,