@neurosec/sentry 1.0.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/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/bin/cli.js +18 -0
  4. package/bin/sentryd.js +19 -0
  5. package/dist/api.d.ts +21 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +161 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/audit.d.ts +18 -0
  10. package/dist/audit.d.ts.map +1 -0
  11. package/dist/audit.js +114 -0
  12. package/dist/audit.js.map +1 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +255 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/config.d.ts +54 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +160 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/discovery.d.ts +5 -0
  22. package/dist/discovery.d.ts.map +1 -0
  23. package/dist/discovery.js +279 -0
  24. package/dist/discovery.js.map +1 -0
  25. package/dist/enforcement/enforcement-engine.d.ts +37 -0
  26. package/dist/enforcement/enforcement-engine.d.ts.map +1 -0
  27. package/dist/enforcement/enforcement-engine.js +325 -0
  28. package/dist/enforcement/enforcement-engine.js.map +1 -0
  29. package/dist/enforcement/file-monitor.d.ts +4 -0
  30. package/dist/enforcement/file-monitor.d.ts.map +1 -0
  31. package/dist/enforcement/file-monitor.js +114 -0
  32. package/dist/enforcement/file-monitor.js.map +1 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +248 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/logger.d.ts +2 -0
  38. package/dist/logger.d.ts.map +1 -0
  39. package/dist/logger.js +17 -0
  40. package/dist/logger.js.map +1 -0
  41. package/dist/sandbox/index.d.ts +14 -0
  42. package/dist/sandbox/index.d.ts.map +1 -0
  43. package/dist/sandbox/index.js +91 -0
  44. package/dist/sandbox/index.js.map +1 -0
  45. package/dist/sandbox/linux-sandbox.d.ts +21 -0
  46. package/dist/sandbox/linux-sandbox.d.ts.map +1 -0
  47. package/dist/sandbox/linux-sandbox.js +186 -0
  48. package/dist/sandbox/linux-sandbox.js.map +1 -0
  49. package/dist/sandbox/macos-sandbox.d.ts +17 -0
  50. package/dist/sandbox/macos-sandbox.d.ts.map +1 -0
  51. package/dist/sandbox/macos-sandbox.js +145 -0
  52. package/dist/sandbox/macos-sandbox.js.map +1 -0
  53. package/dist/setup.d.ts +14 -0
  54. package/dist/setup.d.ts.map +1 -0
  55. package/dist/setup.js +220 -0
  56. package/dist/setup.js.map +1 -0
  57. package/dist/skill-authz/skill-evaluator.d.ts +20 -0
  58. package/dist/skill-authz/skill-evaluator.d.ts.map +1 -0
  59. package/dist/skill-authz/skill-evaluator.js +159 -0
  60. package/dist/skill-authz/skill-evaluator.js.map +1 -0
  61. package/dist/skill-authz/skill-scanner.d.ts +18 -0
  62. package/dist/skill-authz/skill-scanner.d.ts.map +1 -0
  63. package/dist/skill-authz/skill-scanner.js +169 -0
  64. package/dist/skill-authz/skill-scanner.js.map +1 -0
  65. package/dist/telemetry.d.ts +18 -0
  66. package/dist/telemetry.d.ts.map +1 -0
  67. package/dist/telemetry.js +106 -0
  68. package/dist/telemetry.js.map +1 -0
  69. package/dist/types.d.ts +127 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +209 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +69 -0
  74. package/scripts/install-sentry-macos.sh +238 -0
  75. package/scripts/install-sentry.sh +253 -0
  76. package/scripts/postinstall.js +191 -0
  77. package/scripts/prepack.js +33 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NeuroSec
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # NeuroShield Sentry
2
+
3
+ **Host-level agent protection daemon.** Detects AI agent processes running on your infrastructure, sandboxes them with kernel-level isolation, and enforces policies on filesystem access, network egress, syscalls, and skill/tool execution.
4
+
5
+ ```
6
+ npm install -g @neurosec/sentry
7
+ neuroshield-sentry setup
8
+ sudo neuroshield-sentry install
9
+ ```
10
+
11
+ ## How It Works
12
+
13
+ The Sentry daemon runs on each host and connects to your **NeuroSec** security platform:
14
+
15
+ 1. **Discovery** — scans `/proc/*` for processes matching agent framework signatures (LangChain, CrewAI, Claude Code, MCP, AutoGen, etc.)
16
+ 2. **Sandbox** — applies cgroups v2 (CPU/memory limits), seccomp (syscall allowlist), and Landlock (filesystem path restrictions) to each agent process
17
+ 3. **Enforcement** — evaluates every file access, network connection, and syscall against policy. Monitor mode = log-only. Enforce mode = block violations. Quarantine mode = kill on repeat offenses
18
+ 4. **Skill Authorization** — detects tool definitions from MCP manifests, env vars, and process args. High-risk skills (shell exec, file write, database queries) require approval or are blocked
19
+ 5. **Audit** — all decisions are logged as JSON Lines with auto-rotation and SIEM-ready format
20
+
21
+ ## Quick Start
22
+
23
+ ```bash
24
+ # Install globally
25
+ npm install -g @neurosec/sentry
26
+
27
+ # Interactive setup (prompts for NeuroSec URL, org ID, token)
28
+ neuroshield-sentry setup
29
+
30
+ # Or non-interactive for automation
31
+ neuroshield-sentry setup \
32
+ --org=org_abc123 \
33
+ --token=nst_yourtoken \
34
+ --mode=enforce \
35
+ --url=https://api.neurosec.ai
36
+
37
+ # Install as system service (systemd on Linux, launchd on macOS)
38
+ sudo neuroshield-sentry install
39
+
40
+ # Check status
41
+ neuroshield-sentry status
42
+
43
+ # View real-time enforcement decisions
44
+ neuroshield-sentry logs -f
45
+
46
+ # Start the daemon manually
47
+ sudo neuroshield-sentryd
48
+ ```
49
+
50
+ ## CLI Reference
51
+
52
+ | Command | Description |
53
+ |---------|-------------|
54
+ | `setup` | Generate sentry.yaml configuration |
55
+ | `install` | Install system service (systemd/launchd) |
56
+ | `status` | Show daemon status and active processes |
57
+ | `logs` | Tail the audit log (`-f` to follow, `-n 100` for lines) |
58
+ | `version` | Print version |
59
+ | `help` | Show usage |
60
+
61
+ ## Local API
62
+
63
+ When running, the daemon exposes a local HTTP API on `127.0.0.1:9191`:
64
+
65
+ ```
66
+ GET /api/v1/status — Daemon status
67
+ GET /api/v1/processes — Tagged agent processes
68
+ GET /api/v1/processes/:pid — Single process detail
69
+ GET /api/v1/decisions — Recent enforcement decisions
70
+ GET /api/v1/policy — Active policy
71
+ POST /api/v1/policy/reload — Force policy sync
72
+ GET /api/v1/approvals — Pending skill approvals
73
+ POST /api/v1/approve/:id — Approve a skill invocation
74
+ POST /api/v1/deny/:id — Deny a skill invocation
75
+ ```
76
+
77
+ ## Requirements
78
+
79
+ - **Linux** (kernel 5.4+ for cgroups v2, seccomp, Landlock) or **macOS** (Ventura+)
80
+ - **Node.js** >= 20
81
+ - **Systemd** (Linux) or **launchd** (macOS) for service installation
82
+ - Root/sudo access for sandbox (cgroups, seccomp) and `/proc` scanning
83
+
84
+ ## Configuration
85
+
86
+ Config is at `/etc/neuroshield/sentry.yaml`. Key settings:
87
+
88
+ ```yaml
89
+ neurosec:
90
+ endpoint: "https://api.neurosec.ai"
91
+ org_id: "your-org-id"
92
+ token_path: /etc/neuroshield/sentry.token
93
+
94
+ enforcement:
95
+ mode: "monitor" # monitor | enforce | quarantine
96
+ ```
97
+
98
+ All settings are also configurable via environment variables (`NEUROSEC_ORG_ID`, `SENTRY_ENFORCEMENT_MODE`, etc.)
99
+
100
+ ## Platform Backends
101
+
102
+ | Feature | Linux | macOS |
103
+ |---------|-------|-------|
104
+ | Cgroups CPU/memory limits | ✓ cgroups v2 | — |
105
+ | Seccomp syscall filtering | ✓ BPF | — |
106
+ | Landlock FS restrictions | ✓ kernel 5.13+ | — |
107
+ | Seatbelt sandbox profile | — | ✓ sandbox-exec |
108
+ | Endpoint Security monitor | — | ✓ ES framework |
109
+ | Process discovery (/proc) | ✓ | limited |
110
+ | Network monitoring | ✓ nftables/iptables | ✓ pf |
111
+
112
+ ## Kubernetes
113
+
114
+ Deploy as a DaemonSet for per-node enforcement:
115
+
116
+ ```bash
117
+ kubectl apply -f https://raw.githubusercontent.com/neurosec-ai/neurosec/main/packages/sentry/k8s/daemonset.yaml
118
+ ```
package/bin/cli.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ // NeuroShield Sentry — CLI management tool
3
+ // Installed globally via `npm install -g @neurosec/sentry`
4
+
5
+ const path = require('path');
6
+
7
+ let cli;
8
+ try {
9
+ cli = require(path.resolve(__dirname, '..', 'dist', 'cli.js'));
10
+ } catch (e1) {
11
+ try {
12
+ cli = require(path.resolve(__dirname, '..', 'src', 'cli.ts'));
13
+ } catch (e2) {
14
+ console.error('Failed to load CLI. Build it first: npm run build');
15
+ console.error(' or install globally: npm install -g @neurosec/sentry');
16
+ process.exit(1);
17
+ }
18
+ }
package/bin/sentryd.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ // NeuroShield Sentry Daemon — binary entry point
3
+ // Installed globally via `npm install -g @neurosec/sentry`
4
+
5
+ const path = require('path');
6
+
7
+ // Try the dist build first (production), then source as fallback (dev)
8
+ let main;
9
+ try {
10
+ main = require(path.resolve(__dirname, '..', 'dist', 'index.js'));
11
+ } catch (e1) {
12
+ try {
13
+ main = require(path.resolve(__dirname, '..', 'src', 'index.ts'));
14
+ } catch (e2) {
15
+ console.error('Failed to load sentry daemon. Build it first: npm run build');
16
+ console.error(' or install globally: npm install -g @neurosec/sentry');
17
+ process.exit(1);
18
+ }
19
+ }
package/dist/api.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { SentryConfig } from './config';
2
+ import { TaggedProcess, SentryStatus } from './types';
3
+ import { EnforcementEngine } from './enforcement/enforcement-engine';
4
+ import { SkillEvaluator } from './skill-authz/skill-evaluator';
5
+ export declare class SentryApiServer {
6
+ private config;
7
+ private getTaggedProcesses;
8
+ private getEngine;
9
+ private getSkillEvaluator;
10
+ private getPolicyVersion;
11
+ private getLastSyncAt;
12
+ private server;
13
+ private startTime;
14
+ constructor(config: SentryConfig, getTaggedProcesses: () => TaggedProcess[], getEngine: () => EnforcementEngine, getSkillEvaluator: () => SkillEvaluator, getPolicyVersion: () => string, getLastSyncAt: () => string | null);
15
+ start(): Promise<void>;
16
+ stop(): Promise<void>;
17
+ getStatus(): SentryStatus;
18
+ private handleRequest;
19
+ private json;
20
+ }
21
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,aAAa,EAAuB,YAAY,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D,qBAAa,eAAe;IAKxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,aAAa;IATvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,SAAS,CAAc;gBAGrB,MAAM,EAAE,YAAY,EACpB,kBAAkB,EAAE,MAAM,aAAa,EAAE,EACzC,SAAS,EAAE,MAAM,iBAAiB,EAClC,iBAAiB,EAAE,MAAM,cAAc,EACvC,gBAAgB,EAAE,MAAM,MAAM,EAC9B,aAAa,EAAE,MAAM,MAAM,GAAG,IAAI;IAGtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,SAAS,IAAI,YAAY;YAmBX,aAAa;YAuGb,IAAI;CAInB"}
package/dist/api.js ADDED
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SentryApiServer = void 0;
7
+ const http_1 = __importDefault(require("http"));
8
+ const logger_1 = require("./logger");
9
+ class SentryApiServer {
10
+ constructor(config, getTaggedProcesses, getEngine, getSkillEvaluator, getPolicyVersion, getLastSyncAt) {
11
+ this.config = config;
12
+ this.getTaggedProcesses = getTaggedProcesses;
13
+ this.getEngine = getEngine;
14
+ this.getSkillEvaluator = getSkillEvaluator;
15
+ this.getPolicyVersion = getPolicyVersion;
16
+ this.getLastSyncAt = getLastSyncAt;
17
+ this.server = null;
18
+ this.startTime = Date.now();
19
+ }
20
+ async start() {
21
+ if (this.server)
22
+ return;
23
+ this.server = http_1.default.createServer((req, res) => {
24
+ this.handleRequest(req, res).catch(err => {
25
+ logger_1.logger.error('API handler error', { err: err.message });
26
+ if (!res.headersSent) {
27
+ res.writeHead(500, { 'Content-Type': 'application/json' });
28
+ }
29
+ res.end(JSON.stringify({ error: 'Internal server error' }));
30
+ });
31
+ });
32
+ await new Promise((resolve, reject) => {
33
+ this.server.once('error', reject);
34
+ this.server.listen(this.config.sentry.apiPort, '127.0.0.1', () => resolve());
35
+ });
36
+ logger_1.logger.info('Sentry API server listening', { port: this.config.sentry.apiPort });
37
+ }
38
+ async stop() {
39
+ if (!this.server)
40
+ return;
41
+ await new Promise((resolve, reject) => {
42
+ this.server?.close(err => (err ? reject(err) : resolve()));
43
+ });
44
+ this.server = null;
45
+ }
46
+ getStatus() {
47
+ const engine = this.getEngine();
48
+ const stats = engine.getStats();
49
+ const processes = this.getTaggedProcesses();
50
+ return {
51
+ version: this.config.sentry.version,
52
+ uptime: Math.floor((Date.now() - this.startTime) / 1000),
53
+ mode: this.config.enforcement.mode,
54
+ policyVersion: this.getPolicyVersion(),
55
+ taggedProcesses: processes.length,
56
+ sandboxedProcesses: processes.filter(p => p.sandboxed).length,
57
+ decisionsTotal: stats.total,
58
+ decisionsDenied: stats.denied,
59
+ lastSyncAt: this.getLastSyncAt(),
60
+ platform: process.platform === 'linux' ? 'linux' : process.platform === 'darwin' ? 'darwin' : 'unknown',
61
+ };
62
+ }
63
+ async handleRequest(req, res) {
64
+ res.setHeader('Content-Type', 'application/json');
65
+ const parsed = new URL(req.url ?? '/', 'http://127.0.0.1');
66
+ const pathname = parsed.pathname;
67
+ const method = req.method ?? 'GET';
68
+ // CORS for local dev
69
+ res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
70
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
71
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
72
+ if (method === 'OPTIONS') {
73
+ res.writeHead(204);
74
+ res.end();
75
+ return;
76
+ }
77
+ try {
78
+ switch (true) {
79
+ case method === 'GET' && pathname === '/api/v1/status':
80
+ await this.json(res, 200, this.getStatus());
81
+ break;
82
+ case method === 'GET' && pathname === '/api/v1/processes':
83
+ await this.json(res, 200, this.getTaggedProcesses());
84
+ break;
85
+ case method === 'GET' && /^\/api\/v1\/processes\/(\d+)$/.test(pathname): {
86
+ const pid = parseInt(pathname.match(/^\/api\/v1\/processes\/(\d+)$/)[1], 10);
87
+ const processes = this.getTaggedProcesses();
88
+ const proc = processes.find(p => p.pid === pid);
89
+ if (proc) {
90
+ await this.json(res, 200, proc);
91
+ }
92
+ else {
93
+ await this.json(res, 404, { error: 'Process not found' });
94
+ }
95
+ break;
96
+ }
97
+ case method === 'GET' && pathname === '/api/v1/decisions':
98
+ await this.json(res, 200, this.getEngine().getRecentDecisions());
99
+ break;
100
+ case method === 'GET' && pathname === '/api/v1/policy':
101
+ await this.json(res, 200, {
102
+ version: this.getPolicyVersion(),
103
+ mode: this.config.enforcement.mode,
104
+ sandboxEnabled: this.config.enforcement.sandboxEnabled,
105
+ skillAuthzEnabled: this.config.skillAuthz.enabled,
106
+ allowedEgress: this.config.network.allowHosts,
107
+ blockedEgress: this.config.network.blockHosts,
108
+ });
109
+ break;
110
+ case method === 'POST' && pathname === '/api/v1/policy/reload':
111
+ await this.json(res, 200, { message: 'Policy reload requested' });
112
+ break;
113
+ case method === 'POST' && /^\/api\/v1\/sandbox\/(\d+)\/(disable|restrict)$/.test(pathname): {
114
+ const match = pathname.match(/^\/api\/v1\/sandbox\/(\d+)\/(disable|restrict)$/);
115
+ const pid = parseInt(match[1], 10);
116
+ const action = match[2];
117
+ logger_1.logger.info('Sandbox action requested', { pid, action });
118
+ await this.json(res, 200, { message: `Sandbox ${action} for pid ${pid}` });
119
+ break;
120
+ }
121
+ case method === 'GET' && pathname === '/api/v1/approvals':
122
+ await this.json(res, 200, this.getSkillEvaluator().getPendingApprovals());
123
+ break;
124
+ case method === 'POST' && /^\/api\/v1\/approve\/(.+)$/.test(pathname): {
125
+ const invocationId = pathname.match(/^\/api\/v1\/approve\/(.+)$/)[1];
126
+ const success = this.getSkillEvaluator().approve(invocationId);
127
+ if (success) {
128
+ await this.json(res, 200, { message: 'Skill invocation approved', invocationId });
129
+ }
130
+ else {
131
+ await this.json(res, 404, { error: 'Approval request not found or expired', invocationId });
132
+ }
133
+ break;
134
+ }
135
+ case method === 'POST' && /^\/api\/v1\/deny\/(.+)$/.test(pathname): {
136
+ const invocationId = pathname.match(/^\/api\/v1\/deny\/(.+)$/)[1];
137
+ const success = this.getSkillEvaluator().deny(invocationId);
138
+ if (success) {
139
+ await this.json(res, 200, { message: 'Skill invocation denied', invocationId });
140
+ }
141
+ else {
142
+ await this.json(res, 404, { error: 'Denial request not found or expired', invocationId });
143
+ }
144
+ break;
145
+ }
146
+ default:
147
+ await this.json(res, 404, { error: 'Not found', path: pathname });
148
+ }
149
+ }
150
+ catch (err) {
151
+ logger_1.logger.error('API error', { path: pathname, err: err.message });
152
+ await this.json(res, 500, { error: 'Internal error' });
153
+ }
154
+ }
155
+ async json(res, status, data) {
156
+ res.writeHead(status, { 'Content-Type': 'application/json' });
157
+ res.end(JSON.stringify(data));
158
+ }
159
+ }
160
+ exports.SentryApiServer = SentryApiServer;
161
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { AuditEntry } from './types';
2
+ import { SentryConfig } from './config';
3
+ export declare class AuditLogger {
4
+ private config;
5
+ private stream;
6
+ private writeQueue;
7
+ private flushTimer;
8
+ private currentSizeBytes;
9
+ private logDir;
10
+ constructor(config: SentryConfig);
11
+ init(): Promise<void>;
12
+ log(entry: AuditEntry): Promise<void>;
13
+ private flush;
14
+ private rotate;
15
+ private cleanupOldRotations;
16
+ shutdown(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,qBAAa,WAAW;IAOV,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,MAAM,CAAS;gBAEH,MAAM,EAAE,YAAY;IAIlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBrB,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAQ7B,KAAK;YAoBL,MAAM;YAqBN,mBAAmB;IA4B3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAahC"}
package/dist/audit.js ADDED
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AuditLogger = void 0;
7
+ const promises_1 = __importDefault(require("fs/promises"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = require("fs");
10
+ const logger_1 = require("./logger");
11
+ class AuditLogger {
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.stream = null;
15
+ this.writeQueue = [];
16
+ this.flushTimer = null;
17
+ this.currentSizeBytes = 0;
18
+ this.logDir = path_1.default.dirname(config.audit.logPath);
19
+ }
20
+ async init() {
21
+ await promises_1.default.mkdir(this.logDir, { recursive: true });
22
+ try {
23
+ const stat = await promises_1.default.stat(this.config.audit.logPath).catch(() => null);
24
+ if (stat) {
25
+ this.currentSizeBytes = stat.size;
26
+ }
27
+ }
28
+ catch {
29
+ this.currentSizeBytes = 0;
30
+ }
31
+ this.stream = (0, fs_1.createWriteStream)(this.config.audit.logPath, { flags: 'a' });
32
+ this.flushTimer = setInterval(() => this.flush(), 5000);
33
+ logger_1.logger.info('Audit logger initialized', { path: this.config.audit.logPath });
34
+ }
35
+ async log(entry) {
36
+ this.writeQueue.push(entry);
37
+ if (this.writeQueue.length >= 100) {
38
+ await this.flush();
39
+ }
40
+ }
41
+ async flush() {
42
+ if (this.writeQueue.length === 0)
43
+ return;
44
+ const batch = this.writeQueue.splice(0, this.writeQueue.length);
45
+ const lines = batch.map(entry => JSON.stringify(entry)).join('\n') + '\n';
46
+ if (this.stream) {
47
+ const canWrite = this.stream.write(lines);
48
+ this.currentSizeBytes += Buffer.byteLength(lines);
49
+ if (this.currentSizeBytes >= this.config.audit.maxSizeMb * 1024 * 1024) {
50
+ await this.rotate();
51
+ }
52
+ if (!canWrite) {
53
+ await new Promise(resolve => this.stream.once('drain', resolve));
54
+ }
55
+ }
56
+ }
57
+ async rotate() {
58
+ if (this.stream) {
59
+ this.stream.end();
60
+ this.stream = null;
61
+ }
62
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
63
+ const rotatedPath = `${this.config.audit.logPath}.${timestamp}`;
64
+ try {
65
+ await promises_1.default.rename(this.config.audit.logPath, rotatedPath);
66
+ }
67
+ catch {
68
+ // Already rotated or doesn't exist
69
+ }
70
+ this.currentSizeBytes = 0;
71
+ this.stream = (0, fs_1.createWriteStream)(this.config.audit.logPath, { flags: 'a' });
72
+ await this.cleanupOldRotations();
73
+ }
74
+ async cleanupOldRotations() {
75
+ try {
76
+ const dir = path_1.default.dirname(this.config.audit.logPath);
77
+ const baseName = path_1.default.basename(this.config.audit.logPath);
78
+ const files = await promises_1.default.readdir(dir);
79
+ const now = Date.now();
80
+ const maxAge = this.config.audit.retentionDays * 24 * 60 * 60 * 1000;
81
+ for (const file of files) {
82
+ if (file.startsWith(baseName + '.')) {
83
+ const filePath = path_1.default.join(dir, file);
84
+ try {
85
+ const stat = await promises_1.default.stat(filePath);
86
+ if (now - stat.mtimeMs > maxAge) {
87
+ await promises_1.default.unlink(filePath);
88
+ logger_1.logger.debug('Removed old audit rotation', { file: filePath });
89
+ }
90
+ }
91
+ catch {
92
+ // skip
93
+ }
94
+ }
95
+ }
96
+ }
97
+ catch {
98
+ // cleanup is best-effort
99
+ }
100
+ }
101
+ async shutdown() {
102
+ if (this.flushTimer) {
103
+ clearInterval(this.flushTimer);
104
+ this.flushTimer = null;
105
+ }
106
+ await this.flush();
107
+ if (this.stream) {
108
+ this.stream.end();
109
+ this.stream = null;
110
+ }
111
+ }
112
+ }
113
+ exports.AuditLogger = AuditLogger;
114
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAC7B,gDAAwB;AACxB,2BAAoD;AAGpD,qCAAkC;AAElC,MAAa,WAAW;IAOtB,YAAoB,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;QANhC,WAAM,GAAuB,IAAI,CAAC;QAClC,eAAU,GAAiB,EAAE,CAAC;QAC9B,eAAU,GAA0C,IAAI,CAAC;QACzD,qBAAgB,GAAG,CAAC,CAAC;QAI3B,IAAI,CAAC,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,kBAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACxE,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC;YACpC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAA,sBAAiB,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;QACxD,eAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAiB;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE5B,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAClC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEzC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAE1E,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,gBAAgB,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;gBACvE,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,CAAC;YAED,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,MAAM;QAClB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,WAAW,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC;QAEhE,IAAI,CAAC;YACH,MAAM,kBAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAA,sBAAiB,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAE3E,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpD,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAEpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;YAErE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;oBACpC,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBACtC,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;wBACrC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC;4BAChC,MAAM,kBAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;4BAC1B,eAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;wBACjE,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO;oBACT,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AAtHD,kCAsHC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}