@panguard-ai/security-hardening 0.1.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.
Files changed (77) hide show
  1. package/dist/audit/audit-logger.d.ts +44 -0
  2. package/dist/audit/audit-logger.d.ts.map +1 -0
  3. package/dist/audit/audit-logger.js +94 -0
  4. package/dist/audit/audit-logger.js.map +1 -0
  5. package/dist/audit/index.d.ts +9 -0
  6. package/dist/audit/index.d.ts.map +1 -0
  7. package/dist/audit/index.js +9 -0
  8. package/dist/audit/index.js.map +1 -0
  9. package/dist/audit/syslog-adapter.d.ts +48 -0
  10. package/dist/audit/syslog-adapter.d.ts.map +1 -0
  11. package/dist/audit/syslog-adapter.js +97 -0
  12. package/dist/audit/syslog-adapter.js.map +1 -0
  13. package/dist/credentials/credential-store.d.ts +51 -0
  14. package/dist/credentials/credential-store.d.ts.map +1 -0
  15. package/dist/credentials/credential-store.js +183 -0
  16. package/dist/credentials/credential-store.js.map +1 -0
  17. package/dist/credentials/index.d.ts +9 -0
  18. package/dist/credentials/index.d.ts.map +1 -0
  19. package/dist/credentials/index.js +9 -0
  20. package/dist/credentials/index.js.map +1 -0
  21. package/dist/credentials/migration.d.ts +37 -0
  22. package/dist/credentials/migration.d.ts.map +1 -0
  23. package/dist/credentials/migration.js +122 -0
  24. package/dist/credentials/migration.js.map +1 -0
  25. package/dist/index.d.ts +28 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +32 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/permissions/index.d.ts +9 -0
  30. package/dist/permissions/index.d.ts.map +1 -0
  31. package/dist/permissions/index.js +8 -0
  32. package/dist/permissions/index.js.map +1 -0
  33. package/dist/permissions/security-policy.d.ts +74 -0
  34. package/dist/permissions/security-policy.d.ts.map +1 -0
  35. package/dist/permissions/security-policy.js +109 -0
  36. package/dist/permissions/security-policy.js.map +1 -0
  37. package/dist/sandbox/command-whitelist.d.ts +43 -0
  38. package/dist/sandbox/command-whitelist.d.ts.map +1 -0
  39. package/dist/sandbox/command-whitelist.js +84 -0
  40. package/dist/sandbox/command-whitelist.js.map +1 -0
  41. package/dist/sandbox/filesystem-guard.d.ts +30 -0
  42. package/dist/sandbox/filesystem-guard.d.ts.map +1 -0
  43. package/dist/sandbox/filesystem-guard.js +67 -0
  44. package/dist/sandbox/filesystem-guard.js.map +1 -0
  45. package/dist/sandbox/index.d.ts +9 -0
  46. package/dist/sandbox/index.d.ts.map +1 -0
  47. package/dist/sandbox/index.js +9 -0
  48. package/dist/sandbox/index.js.map +1 -0
  49. package/dist/scanner/index.d.ts +8 -0
  50. package/dist/scanner/index.d.ts.map +1 -0
  51. package/dist/scanner/index.js +8 -0
  52. package/dist/scanner/index.js.map +1 -0
  53. package/dist/scanner/vulnerability-scanner.d.ts +22 -0
  54. package/dist/scanner/vulnerability-scanner.d.ts.map +1 -0
  55. package/dist/scanner/vulnerability-scanner.js +138 -0
  56. package/dist/scanner/vulnerability-scanner.js.map +1 -0
  57. package/dist/types.d.ts +143 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +8 -0
  60. package/dist/types.js.map +1 -0
  61. package/dist/websocket/connection-validator.d.ts +35 -0
  62. package/dist/websocket/connection-validator.d.ts.map +1 -0
  63. package/dist/websocket/connection-validator.js +93 -0
  64. package/dist/websocket/connection-validator.js.map +1 -0
  65. package/dist/websocket/csrf-token.d.ts +65 -0
  66. package/dist/websocket/csrf-token.d.ts.map +1 -0
  67. package/dist/websocket/csrf-token.js +123 -0
  68. package/dist/websocket/csrf-token.js.map +1 -0
  69. package/dist/websocket/index.d.ts +13 -0
  70. package/dist/websocket/index.d.ts.map +1 -0
  71. package/dist/websocket/index.js +13 -0
  72. package/dist/websocket/index.js.map +1 -0
  73. package/dist/websocket/origin-validator.d.ts +28 -0
  74. package/dist/websocket/origin-validator.d.ts.map +1 -0
  75. package/dist/websocket/origin-validator.js +60 -0
  76. package/dist/websocket/origin-validator.js.map +1 -0
  77. package/package.json +62 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Migrate plaintext credentials to secure storage
3
+ * 將明文憑證遷移到安全儲存
4
+ *
5
+ * @module @panguard-ai/security-hardening/credentials/migration
6
+ */
7
+ import { existsSync, readdirSync, readFileSync, renameSync } from 'fs';
8
+ import { join } from 'path';
9
+ import { homedir } from 'os';
10
+ import { createLogger } from '@panguard-ai/core';
11
+ const logger = createLogger('credentials:migration');
12
+ /** Default Panguard credentials directory / 預設 Panguard 憑證目錄 */
13
+ const DEFAULT_CREDENTIALS_DIR = join(homedir(), '.panguard', 'credentials');
14
+ /**
15
+ * Known credential file patterns
16
+ * 已知的憑證檔案模式
17
+ */
18
+ const CREDENTIAL_PATTERNS = [
19
+ { pattern: /^telegram[._-]?token$/i, service: 'telegram', account: 'bot' },
20
+ { pattern: /^slack[._-]?token$/i, service: 'slack', account: 'default' },
21
+ { pattern: /^discord[._-]?token$/i, service: 'discord', account: 'bot' },
22
+ { pattern: /^openai[._-]?(key|token)$/i, service: 'openai', account: 'default' },
23
+ { pattern: /^claude[._-]?(key|token)$/i, service: 'claude', account: 'default' },
24
+ { pattern: /^line[._-]?token$/i, service: 'line', account: 'default' },
25
+ { pattern: /^whatsapp[._-]?token$/i, service: 'whatsapp', account: 'default' },
26
+ { pattern: /^signal[._-]?token$/i, service: 'signal', account: 'default' },
27
+ ];
28
+ /**
29
+ * Scan for plaintext credential files
30
+ * 掃描明文憑證檔案
31
+ *
32
+ * @param credentialsDir - Directory to scan / 要掃描的目錄
33
+ * @returns Array of found plaintext credentials / 找到的明文憑證陣列
34
+ */
35
+ export function scanPlaintextCredentials(credentialsDir = DEFAULT_CREDENTIALS_DIR) {
36
+ if (!existsSync(credentialsDir)) {
37
+ logger.info('Credentials directory not found, no plaintext credentials', { credentialsDir });
38
+ return [];
39
+ }
40
+ const credentials = [];
41
+ let files;
42
+ try {
43
+ files = readdirSync(credentialsDir);
44
+ }
45
+ catch (error) {
46
+ logger.error('Failed to read credentials directory', { credentialsDir, error: String(error) });
47
+ return [];
48
+ }
49
+ for (const file of files) {
50
+ // Skip backup files and hidden files
51
+ if (file.startsWith('.') || file.endsWith('.backup') || file.endsWith('.enc')) {
52
+ continue;
53
+ }
54
+ const filePath = join(credentialsDir, file);
55
+ // Match against known patterns
56
+ for (const { pattern, service, account } of CREDENTIAL_PATTERNS) {
57
+ if (pattern.test(file)) {
58
+ try {
59
+ const value = readFileSync(filePath, 'utf-8').trim();
60
+ if (value.length > 0) {
61
+ credentials.push({ service, account, value, filePath });
62
+ logger.warn('Plaintext credential found', { service, account, filePath });
63
+ }
64
+ }
65
+ catch (error) {
66
+ logger.error('Failed to read credential file', { filePath, error: String(error) });
67
+ }
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ return credentials;
73
+ }
74
+ /**
75
+ * Migrate plaintext credentials to secure storage
76
+ * 將明文憑證遷移到安全儲存
77
+ *
78
+ * @param store - Target credential store / 目標憑證儲存
79
+ * @param credentialsDir - Source directory / 來源目錄
80
+ * @param dryRun - If true, only report without migrating / 僅報告而不遷移
81
+ * @returns Migration report / 遷移報告
82
+ */
83
+ export async function migrateCredentials(store, credentialsDir = DEFAULT_CREDENTIALS_DIR, dryRun = false) {
84
+ const credentials = scanPlaintextCredentials(credentialsDir);
85
+ const report = {
86
+ scanned: credentials.length,
87
+ migrated: 0,
88
+ failed: 0,
89
+ errors: [],
90
+ };
91
+ if (credentials.length === 0) {
92
+ logger.info('No plaintext credentials found to migrate');
93
+ return report;
94
+ }
95
+ logger.info(`Found ${credentials.length} plaintext credential(s)`, { dryRun });
96
+ for (const { service, account, value, filePath } of credentials) {
97
+ if (dryRun) {
98
+ logger.info('[DRY RUN] Would migrate credential', { service, account });
99
+ report.migrated++;
100
+ continue;
101
+ }
102
+ try {
103
+ await store.set(service, account, value);
104
+ renameSync(filePath, `${filePath}.backup`);
105
+ logger.info('Credential migrated successfully', { service, account });
106
+ report.migrated++;
107
+ }
108
+ catch (error) {
109
+ const msg = `Failed to migrate ${service}:${account}: ${String(error)}`;
110
+ logger.error(msg);
111
+ report.errors.push(msg);
112
+ report.failed++;
113
+ }
114
+ }
115
+ logger.info('Migration complete', {
116
+ scanned: report.scanned,
117
+ migrated: report.migrated,
118
+ failed: report.failed,
119
+ });
120
+ return report;
121
+ }
122
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/credentials/migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Panguard AI Hardening Library
3
+ * Panguard 安全強化函式庫
4
+ *
5
+ * Provides security fixes and hardening for Panguard AI Agent framework.
6
+ * Addresses CVE-2026-25253, credential storage, skill sandboxing,
7
+ * permission minimization, and audit logging.
8
+ * 為 Panguard AI Agent 框架提供安全修復和強化。
9
+ * 處理 CVE-2026-25253、憑證儲存、技能沙盒、權限最小化和稽核日誌。
10
+ *
11
+ * @module @panguard-ai/security-hardening
12
+ */
13
+ export type { SecurityPolicy, CsrfToken, OriginConfig, AuditAction, AuditEvent, CredentialStore, VulnerabilityFinding, SecurityAuditReport, MigrationReport, } from './types.js';
14
+ export { validateOrigin, createOriginValidator } from './websocket/index.js';
15
+ export { CsrfTokenManager } from './websocket/index.js';
16
+ export { validateGatewayUrl, sanitizeWebSocketUrl } from './websocket/index.js';
17
+ export { InMemoryCredentialStore, EncryptedFileCredentialStore } from './credentials/index.js';
18
+ export { scanPlaintextCredentials, migrateCredentials } from './credentials/index.js';
19
+ export { isPathAllowed, createFilesystemGuard } from './sandbox/index.js';
20
+ export { isCommandAllowed, createCommandValidator, DEFAULT_ALLOWED_COMMANDS, } from './sandbox/index.js';
21
+ export { loadSecurityPolicy, isOperationAllowed, DEFAULT_SECURITY_POLICY, } from './permissions/index.js';
22
+ export type { OperationType } from './permissions/index.js';
23
+ export { logAuditEvent, logWebSocketConnect, logCredentialAccess, logFileAccess, logCommandExecution, logPolicyCheck, } from './audit/index.js';
24
+ export { SyslogAdapter, formatSyslogMessage } from './audit/index.js';
25
+ export { runSecurityAudit } from './scanner/index.js';
26
+ /** Security hardening library version / 安全強化函式庫版本 */
27
+ export declare const HARDENING_VERSION = "0.1.0";
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,YAAY,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGhF,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGtF,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Panguard AI Hardening Library
3
+ * Panguard 安全強化函式庫
4
+ *
5
+ * Provides security fixes and hardening for Panguard AI Agent framework.
6
+ * Addresses CVE-2026-25253, credential storage, skill sandboxing,
7
+ * permission minimization, and audit logging.
8
+ * 為 Panguard AI Agent 框架提供安全修復和強化。
9
+ * 處理 CVE-2026-25253、憑證儲存、技能沙盒、權限最小化和稽核日誌。
10
+ *
11
+ * @module @panguard-ai/security-hardening
12
+ */
13
+ // WebSocket Security (CVE-2026-25253)
14
+ export { validateOrigin, createOriginValidator } from './websocket/index.js';
15
+ export { CsrfTokenManager } from './websocket/index.js';
16
+ export { validateGatewayUrl, sanitizeWebSocketUrl } from './websocket/index.js';
17
+ // Credential Security
18
+ export { InMemoryCredentialStore, EncryptedFileCredentialStore } from './credentials/index.js';
19
+ export { scanPlaintextCredentials, migrateCredentials } from './credentials/index.js';
20
+ // Skill Sandbox
21
+ export { isPathAllowed, createFilesystemGuard } from './sandbox/index.js';
22
+ export { isCommandAllowed, createCommandValidator, DEFAULT_ALLOWED_COMMANDS, } from './sandbox/index.js';
23
+ // Permissions
24
+ export { loadSecurityPolicy, isOperationAllowed, DEFAULT_SECURITY_POLICY, } from './permissions/index.js';
25
+ // Audit Logging
26
+ export { logAuditEvent, logWebSocketConnect, logCredentialAccess, logFileAccess, logCommandExecution, logPolicyCheck, } from './audit/index.js';
27
+ export { SyslogAdapter, formatSyslogMessage } from './audit/index.js';
28
+ // Security Scanner
29
+ export { runSecurityAudit } from './scanner/index.js';
30
+ /** Security hardening library version / 安全強化函式庫版本 */
31
+ export const HARDENING_VERSION = '0.1.0';
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,sCAAsC;AACtC,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEhF,sBAAsB;AACtB,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,gBAAgB;AAChB,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAE5B,cAAc;AACd,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAGhC,gBAAgB;AAChB,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEtE,mBAAmB;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,qDAAqD;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Permission and security policy module
3
+ * 權限與安全政策模組
4
+ *
5
+ * @module @panguard-ai/security-hardening/permissions
6
+ */
7
+ export { loadSecurityPolicy, isOperationAllowed, DEFAULT_SECURITY_POLICY, SecurityPolicySchema, } from './security-policy.js';
8
+ export type { OperationType } from './security-policy.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Permission and security policy module
3
+ * 權限與安全政策模組
4
+ *
5
+ * @module @panguard-ai/security-hardening/permissions
6
+ */
7
+ export { loadSecurityPolicy, isOperationAllowed, DEFAULT_SECURITY_POLICY, SecurityPolicySchema, } from './security-policy.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Security policy configuration and enforcement
3
+ * 安全政策配置與執行
4
+ *
5
+ * @module @panguard-ai/security-hardening/permissions/security-policy
6
+ */
7
+ import { z } from 'zod';
8
+ import type { SecurityPolicy } from '../types.js';
9
+ /**
10
+ * Zod schema for security policy validation
11
+ * 安全政策驗證的 Zod schema
12
+ */
13
+ export declare const SecurityPolicySchema: z.ZodObject<{
14
+ allowShellAccess: z.ZodDefault<z.ZodBoolean>;
15
+ allowedDirectories: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
16
+ allowedCommands: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
17
+ requireCsrfToken: z.ZodDefault<z.ZodBoolean>;
18
+ allowedOrigins: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
19
+ enableAuditLog: z.ZodDefault<z.ZodBoolean>;
20
+ syslogServer: z.ZodOptional<z.ZodString>;
21
+ syslogPort: z.ZodOptional<z.ZodNumber>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ allowShellAccess: boolean;
24
+ allowedDirectories: string[];
25
+ allowedCommands: string[];
26
+ requireCsrfToken: boolean;
27
+ allowedOrigins: string[];
28
+ enableAuditLog: boolean;
29
+ syslogServer?: string | undefined;
30
+ syslogPort?: number | undefined;
31
+ }, {
32
+ allowShellAccess?: boolean | undefined;
33
+ allowedDirectories?: string[] | undefined;
34
+ allowedCommands?: string[] | undefined;
35
+ requireCsrfToken?: boolean | undefined;
36
+ allowedOrigins?: string[] | undefined;
37
+ enableAuditLog?: boolean | undefined;
38
+ syslogServer?: string | undefined;
39
+ syslogPort?: number | undefined;
40
+ }>;
41
+ /**
42
+ * Default security policy (restricted mode)
43
+ * 預設安全政策(受限模式)
44
+ *
45
+ * Shell access disabled, CSRF required, audit logging enabled.
46
+ * Shell 存取停用、CSRF 必要、稽核日誌啟用。
47
+ */
48
+ export declare const DEFAULT_SECURITY_POLICY: SecurityPolicy;
49
+ /**
50
+ * Operation types that can be checked against policy
51
+ * 可以根據政策檢查的操作類型
52
+ */
53
+ export type OperationType = 'shell' | 'file_read' | 'file_write' | 'command' | 'network';
54
+ /**
55
+ * Load and validate a security policy from configuration
56
+ * 從配置載入並驗證安全政策
57
+ *
58
+ * Falls back to default restricted policy on validation failure.
59
+ * 驗證失敗時回退到預設的受限政策。
60
+ *
61
+ * @param config - Raw configuration object / 原始配置物件
62
+ * @returns Validated security policy / 驗證後的安全政策
63
+ */
64
+ export declare function loadSecurityPolicy(config: unknown): SecurityPolicy;
65
+ /**
66
+ * Check if an operation is allowed by the current policy
67
+ * 檢查操作是否被目前的政策允許
68
+ *
69
+ * @param operation - Operation type / 操作類型
70
+ * @param policy - Security policy / 安全政策
71
+ * @returns true if operation is allowed / 操作被允許則回傳 true
72
+ */
73
+ export declare function isOperationAllowed(operation: OperationType, policy: SecurityPolicy): boolean;
74
+ //# sourceMappingURL=security-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-policy.d.ts","sourceRoot":"","sources":["../../src/permissions/security-policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS/B,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAOrC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CA0BlE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CA0B5F"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Security policy configuration and enforcement
3
+ * 安全政策配置與執行
4
+ *
5
+ * @module @panguard-ai/security-hardening/permissions/security-policy
6
+ */
7
+ import { z } from 'zod';
8
+ import { createLogger, validateInput } from '@panguard-ai/core';
9
+ const logger = createLogger('permissions:security-policy');
10
+ /**
11
+ * Zod schema for security policy validation
12
+ * 安全政策驗證的 Zod schema
13
+ */
14
+ export const SecurityPolicySchema = z.object({
15
+ allowShellAccess: z.boolean().default(false),
16
+ allowedDirectories: z.array(z.string()).default([]),
17
+ allowedCommands: z.array(z.string()).default([]),
18
+ requireCsrfToken: z.boolean().default(true),
19
+ allowedOrigins: z.array(z.string()).default(['http://localhost:18789', 'http://127.0.0.1:18789']),
20
+ enableAuditLog: z.boolean().default(true),
21
+ syslogServer: z.string().optional(),
22
+ syslogPort: z.number().int().min(1).max(65535).optional(),
23
+ });
24
+ /**
25
+ * Default security policy (restricted mode)
26
+ * 預設安全政策(受限模式)
27
+ *
28
+ * Shell access disabled, CSRF required, audit logging enabled.
29
+ * Shell 存取停用、CSRF 必要、稽核日誌啟用。
30
+ */
31
+ export const DEFAULT_SECURITY_POLICY = {
32
+ allowShellAccess: false,
33
+ allowedDirectories: [],
34
+ allowedCommands: [],
35
+ requireCsrfToken: true,
36
+ allowedOrigins: ['http://localhost:18789', 'http://127.0.0.1:18789'],
37
+ enableAuditLog: true,
38
+ };
39
+ /**
40
+ * Load and validate a security policy from configuration
41
+ * 從配置載入並驗證安全政策
42
+ *
43
+ * Falls back to default restricted policy on validation failure.
44
+ * 驗證失敗時回退到預設的受限政策。
45
+ *
46
+ * @param config - Raw configuration object / 原始配置物件
47
+ * @returns Validated security policy / 驗證後的安全政策
48
+ */
49
+ export function loadSecurityPolicy(config) {
50
+ try {
51
+ const parsed = validateInput(SecurityPolicySchema, config);
52
+ // Zod .default() guarantees all required fields after parsing
53
+ const policy = {
54
+ allowShellAccess: parsed.allowShellAccess ?? false,
55
+ allowedDirectories: parsed.allowedDirectories ?? [],
56
+ allowedCommands: parsed.allowedCommands ?? [],
57
+ requireCsrfToken: parsed.requireCsrfToken ?? true,
58
+ allowedOrigins: parsed.allowedOrigins ?? ['http://localhost:18789', 'http://127.0.0.1:18789'],
59
+ enableAuditLog: parsed.enableAuditLog ?? true,
60
+ syslogServer: parsed.syslogServer,
61
+ syslogPort: parsed.syslogPort,
62
+ };
63
+ logger.info('Security policy loaded', {
64
+ allowShellAccess: policy.allowShellAccess,
65
+ requireCsrfToken: policy.requireCsrfToken,
66
+ enableAuditLog: policy.enableAuditLog,
67
+ });
68
+ return policy;
69
+ }
70
+ catch (error) {
71
+ logger.error('Failed to load security policy, using restricted defaults', {
72
+ error: String(error),
73
+ });
74
+ return DEFAULT_SECURITY_POLICY;
75
+ }
76
+ }
77
+ /**
78
+ * Check if an operation is allowed by the current policy
79
+ * 檢查操作是否被目前的政策允許
80
+ *
81
+ * @param operation - Operation type / 操作類型
82
+ * @param policy - Security policy / 安全政策
83
+ * @returns true if operation is allowed / 操作被允許則回傳 true
84
+ */
85
+ export function isOperationAllowed(operation, policy) {
86
+ let allowed;
87
+ switch (operation) {
88
+ case 'shell':
89
+ allowed = policy.allowShellAccess;
90
+ break;
91
+ case 'file_read':
92
+ case 'file_write':
93
+ allowed = policy.allowedDirectories.length > 0;
94
+ break;
95
+ case 'command':
96
+ allowed = policy.allowedCommands.length > 0 || policy.allowShellAccess;
97
+ break;
98
+ case 'network':
99
+ allowed = true; // Network is allowed by default, controlled separately
100
+ break;
101
+ default:
102
+ allowed = false;
103
+ }
104
+ if (!allowed) {
105
+ logger.warn('Operation blocked by security policy', { operation });
106
+ }
107
+ return allowed;
108
+ }
109
+ //# sourceMappingURL=security-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-policy.js","sourceRoot":"","sources":["../../src/permissions/security-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Command whitelist for safe execution
3
+ * 安全執行的命令白名單
4
+ *
5
+ * Prevents Skills from executing arbitrary commands.
6
+ * 防止 Skills 執行任意命令。
7
+ *
8
+ * @module @panguard-ai/security-hardening/sandbox/command-whitelist
9
+ */
10
+ /**
11
+ * Default allowed commands (safe, read-only utilities)
12
+ * 預設允許的命令(安全、唯讀工具)
13
+ */
14
+ export declare const DEFAULT_ALLOWED_COMMANDS: readonly string[];
15
+ /**
16
+ * Extract base command name from a command string
17
+ * 從命令字串中提取基礎命令名稱
18
+ *
19
+ * @param command - Full command string / 完整命令字串
20
+ * @returns Base command name / 基礎命令名稱
21
+ */
22
+ export declare function extractBaseCommand(command: string): string;
23
+ /**
24
+ * Check if a command is in the whitelist
25
+ * 檢查命令是否在白名單中
26
+ *
27
+ * @param command - Command to check / 要檢查的命令
28
+ * @param whitelist - Allowed commands / 允許的命令
29
+ * @returns true if command is allowed / 命令被允許則回傳 true
30
+ */
31
+ export declare function isCommandAllowed(command: string, whitelist?: readonly string[]): boolean;
32
+ /**
33
+ * Create a command validator function
34
+ * 建立命令驗證器函式
35
+ *
36
+ * Returns a function that throws if a command is not whitelisted.
37
+ * 回傳一個在命令未列入白名單時拋出錯誤的函式。
38
+ *
39
+ * @param whitelist - Allowed commands / 允許的命令
40
+ * @returns Validator function / 驗證器函式
41
+ */
42
+ export declare function createCommandValidator(whitelist?: readonly string[]): (command: string) => void;
43
+ //# sourceMappingURL=command-whitelist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-whitelist.d.ts","sourceRoot":"","sources":["../../src/sandbox/command-whitelist.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAe5C,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,SAAS,MAAM,EAA6B,GACtD,OAAO,CAWT;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,GAAE,SAAS,MAAM,EAA6B,aAC3E,MAAM,KAAG,IAAI,CAQ/B"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Command whitelist for safe execution
3
+ * 安全執行的命令白名單
4
+ *
5
+ * Prevents Skills from executing arbitrary commands.
6
+ * 防止 Skills 執行任意命令。
7
+ *
8
+ * @module @panguard-ai/security-hardening/sandbox/command-whitelist
9
+ */
10
+ import { createLogger } from '@panguard-ai/core';
11
+ const logger = createLogger('sandbox:command-whitelist');
12
+ /**
13
+ * Default allowed commands (safe, read-only utilities)
14
+ * 預設允許的命令(安全、唯讀工具)
15
+ */
16
+ export const DEFAULT_ALLOWED_COMMANDS = [
17
+ 'ls',
18
+ 'cat',
19
+ 'grep',
20
+ 'find',
21
+ 'head',
22
+ 'tail',
23
+ 'wc',
24
+ 'echo',
25
+ 'pwd',
26
+ 'date',
27
+ 'whoami',
28
+ 'uname',
29
+ 'node',
30
+ 'git',
31
+ ];
32
+ /**
33
+ * Extract base command name from a command string
34
+ * 從命令字串中提取基礎命令名稱
35
+ *
36
+ * @param command - Full command string / 完整命令字串
37
+ * @returns Base command name / 基礎命令名稱
38
+ */
39
+ export function extractBaseCommand(command) {
40
+ const trimmed = command.trim();
41
+ // Get first token (before any spaces/args)
42
+ const firstToken = trimmed.split(/\s+/)[0] ?? trimmed;
43
+ // Get basename (after last /)
44
+ const basename = firstToken.split('/').pop() ?? firstToken;
45
+ return basename;
46
+ }
47
+ /**
48
+ * Check if a command is in the whitelist
49
+ * 檢查命令是否在白名單中
50
+ *
51
+ * @param command - Command to check / 要檢查的命令
52
+ * @param whitelist - Allowed commands / 允許的命令
53
+ * @returns true if command is allowed / 命令被允許則回傳 true
54
+ */
55
+ export function isCommandAllowed(command, whitelist = DEFAULT_ALLOWED_COMMANDS) {
56
+ const base = extractBaseCommand(command);
57
+ const allowed = whitelist.includes(base);
58
+ if (!allowed) {
59
+ logger.warn('Command blocked: not in whitelist', { command, baseCommand: base });
60
+ }
61
+ else {
62
+ logger.info('Command allowed', { command, baseCommand: base });
63
+ }
64
+ return allowed;
65
+ }
66
+ /**
67
+ * Create a command validator function
68
+ * 建立命令驗證器函式
69
+ *
70
+ * Returns a function that throws if a command is not whitelisted.
71
+ * 回傳一個在命令未列入白名單時拋出錯誤的函式。
72
+ *
73
+ * @param whitelist - Allowed commands / 允許的命令
74
+ * @returns Validator function / 驗證器函式
75
+ */
76
+ export function createCommandValidator(whitelist = DEFAULT_ALLOWED_COMMANDS) {
77
+ return (command) => {
78
+ if (!isCommandAllowed(command, whitelist)) {
79
+ throw new Error(`Command execution denied: '${extractBaseCommand(command)}' is not whitelisted / ` +
80
+ `命令執行拒絕:'${extractBaseCommand(command)}' 未列入白名單`);
81
+ }
82
+ };
83
+ }
84
+ //# sourceMappingURL=command-whitelist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-whitelist.js","sourceRoot":"","sources":["../../src/sandbox/command-whitelist.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,MAAM,GAAG,YAAY,CAAC,2BAA2B,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAsB;IACzD,IAAI;IACJ,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,MAAM;IACN,KAAK;IACL,MAAM;IACN,QAAQ;IACR,OAAO;IACP,MAAM;IACN,KAAK;CACG,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,2CAA2C;IAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACtD,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,UAAU,CAAC;IAC3D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,YAA+B,wBAAwB;IAEvD,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEzC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACnF,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAAC,YAA+B,wBAAwB;IAC5F,OAAO,CAAC,OAAe,EAAQ,EAAE;QAC/B,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,8BAA8B,kBAAkB,CAAC,OAAO,CAAC,yBAAyB;gBAChF,WAAW,kBAAkB,CAAC,OAAO,CAAC,UAAU,CACnD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Filesystem access control for Skills
3
+ * Skills 的檔案系統存取控制
4
+ *
5
+ * Restricts file access to whitelisted directories only.
6
+ * 限制檔案存取僅限白名單目錄。
7
+ *
8
+ * @module @panguard-ai/security-hardening/sandbox/filesystem-guard
9
+ */
10
+ /**
11
+ * Check if a file path is within allowed directories
12
+ * 檢查檔案路徑是否在允許的目錄內
13
+ *
14
+ * @param filePath - File path to check / 要檢查的檔案路徑
15
+ * @param allowedDirs - Allowed directories / 允許的目錄
16
+ * @returns true if path is allowed / 路徑被允許則回傳 true
17
+ */
18
+ export declare function isPathAllowed(filePath: string, allowedDirs: string[]): boolean;
19
+ /**
20
+ * Create a filesystem guard function
21
+ * 建立檔案系統守衛函式
22
+ *
23
+ * Returns a function that throws if a path is not allowed.
24
+ * 回傳一個在路徑不被允許時拋出錯誤的函式。
25
+ *
26
+ * @param allowedDirs - Allowed directories / 允許的目錄
27
+ * @returns Guard function / 守衛函式
28
+ */
29
+ export declare function createFilesystemGuard(allowedDirs: string[]): (filePath: string) => void;
30
+ //# sourceMappingURL=filesystem-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-guard.d.ts","sourceRoot":"","sources":["../../src/sandbox/filesystem-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CA6B9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,cACvC,MAAM,KAAG,IAAI,CAQhC"}