lucifer-gate 0.7.4 → 0.8.0-alpha.1.02835cd

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 CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  AI agent command firewall with Telegram-based human approval.
4
4
 
5
- Lucifer sits between your AI agent and the shell. It authenticates callers via API keys, matches commands against a policy file, and gates unknown commands through Telegram for human approval. Approved commands build up a permission library over time. Think "sudo via Telegram."
5
+ Lucifer sits between your AI agent and the shell. It authenticates callers via
6
+ API keys, matches commands against a policy file, and gates unknown commands
7
+ through Telegram for human approval. Approved commands build up a permission
8
+ library over time. Think "sudo via Telegram."
6
9
 
7
10
  ## Quick start (2 minutes, no Telegram needed)
8
11
 
@@ -22,185 +25,47 @@ curl -X POST http://localhost:3001/api/v1/execute \
22
25
 
23
26
  ## How it works
24
27
 
25
- 1. Caller sends `POST /api/v1/execute` with API key + command
26
- 2. Lucifer authenticates the key and checks IP allowlist
28
+ 1. Caller sends `POST /api/v1/execute` with API key + command.
29
+ 2. Lucifer authenticates the key and checks the IP allowlist.
27
30
  3. Command is matched against `config/command-rules.json`:
28
- - `always_approve` -> execute immediately
29
- - `always_deny` -> reject (403)
30
- - `manual_approve` -> check SQLite for cached approval, or send to Telegram
31
- 4. If Telegram approval needed, human sees the command with risk warnings and taps a button
32
- 5. Approved commands execute and results are returned to the caller
33
-
34
- ## Config files
35
-
36
- Generated by `--init`, hand-editable:
37
-
38
- **config/lucifer.json** - Server settings (port, timeouts, limits, log file path)
39
-
40
- **config/api-keys.json** - API key definitions (hashed, with optional IP allowlists)
41
-
42
- **config/command-rules.json** - Command policy:
43
- ```json
44
- {
45
- "rules": [
46
- { "prefix": "echo ", "action": "always_approve" },
47
- { "prefix": "git pull", "action": "manual_approve" },
48
- { "prefix": "rm ", "action": "always_deny" }
49
- ],
50
- "defaultAction": "always_deny"
51
- }
52
- ```
53
-
54
- Rules matched top-to-bottom, first match wins.
55
-
56
- ### Command aliases (optional)
57
-
58
- `config/lucifer.json` may include an `aliases` map that points a name at a
59
- script or executable on disk. When the incoming command matches an alias name
60
- exactly, Lucifer runs the referenced file directly (no shell) with the
61
- script's parent directory as the working directory. Callers supplying a `cwd`
62
- have it ignored for alias invocations. If the name does not match an alias,
63
- execution falls back to the normal shell path.
64
-
65
- ```json
66
- {
67
- "aliases": {
68
- "deploy": { "path": "/opt/ops/deploy.sh", "type": "bash" },
69
- "healthz": { "path": "/opt/ops/bin/healthz", "type": "elf" }
70
- }
71
- }
72
- ```
73
-
74
- Supported `type` values:
75
-
76
- - `bash` — launched via `bash -- <path>`. The `--` prevents a path that
77
- happens to start with `-` from being interpreted as a bash option.
78
- - `elf` — launched directly (must be executable and on a filesystem without
79
- `noexec`).
80
-
81
- Relative alias `path` values are resolved against the **config file's
82
- directory**, not the daemon's working directory. So `"./scripts/deploy.sh"`
83
- in `config/lucifer.json` always means `config/scripts/deploy.sh` regardless
84
- of where the server was started from. Absolute paths are used as-is.
85
-
86
- Command rules still apply to the alias name as sent by the caller (so you can
87
- e.g. put `{ "prefix": "deploy", "action": "manual_approve" }` in
88
- `command-rules.json`). Exact-string match only — an alias `deploy` does not
89
- match `deploy --dry-run`; that falls through to the shell path.
90
-
91
- ### Transparent HTTP proxy (optional)
92
-
93
- Lucifer can also run one or more transparent HTTP proxy listeners alongside
94
- the main gateway. Each listener forwards every request it receives to a
95
- configured upstream, preserving path, method, query string and body, and
96
- injecting a fixed set of outgoing headers.
97
-
98
- Drop `config/proxy-config.json`:
99
-
100
- ```json
101
- {
102
- "proxies": [
103
- {
104
- "port": 6060,
105
- "baseUrl": "https://api.openai.com",
106
- "headers": { "Authorization": "Bearer sk-..." }
107
- }
108
- ]
109
- }
110
- ```
111
-
112
- A request to `http://localhost:6060/v1/chat/completions` is forwarded to
113
- `https://api.openai.com/v1/chat/completions` with the configured
114
- `Authorization` header attached server-side. Configured headers **overwrite**
115
- any caller-supplied header of the same name, so callers never need (and
116
- cannot spoof) the upstream credential.
117
-
118
- File semantics:
119
-
120
- - File missing → feature disabled (no behavior change for existing installs).
121
- - File present with `proxies: []` → feature enabled, no listeners started.
122
- - Ports must be in 1–65535 and must not collide with the gateway port or
123
- with each other — validated at startup.
124
- - `baseUrl` must be a syntactically valid `http://` or `https://` URL.
125
- - Listeners bind to `127.0.0.1` by default. Set `"host": "0.0.0.0"` on a
126
- mapping to expose it beyond loopback; when doing so, the operator is
127
- responsible for fronting the listener with access control.
128
-
129
- See [docs/specs/transparent-proxy.md](docs/specs/transparent-proxy.md) for
130
- the full contract.
31
+ - `always_approve` execute immediately
32
+ - `always_deny` reject (`403`)
33
+ - `manual_approve` check SQLite for a cached approval, or send to Telegram
34
+ 4. If Telegram approval is needed, a human sees the command with risk warnings
35
+ and taps a button.
36
+ 5. Approved commands execute and results are returned to the caller.
37
+
38
+ See [docs/specs/command-execution.md](docs/specs/command-execution.md) for the
39
+ full API contract (request shape, success response, error codes) and
40
+ [docs/specs/approval-channels.md](docs/specs/approval-channels.md) for how
41
+ Telegram, the web admin UI, and auto-approve interact.
131
42
 
132
43
  ## Production setup (with Telegram)
133
44
 
134
- 1. Create a Telegram bot via [@BotFather](https://t.me/BotFather) and get the token
135
- 2. Send any message to your bot from the chat you want to use for approvals
136
- 3. Run the pairing command:
137
-
138
- ```bash
139
- LUCIFER_TELEGRAM_TOKEN=your_bot_token npx lucifer-gate pair --config ./config/lucifer.json
140
- ```
141
-
142
- The pairing wizard will:
143
- - Validate your bot token
144
- - List all chats that have messaged the bot (most recent first)
145
- - Let you pick which chat to use for approvals
146
- - Send a 6-digit verification code to that chat
147
- - Ask you to enter the code to prove you can read the chat
148
- - Save the chat ID to `config/lucifer.json`
149
-
150
- 4. Start the server (no `LUCIFER_TELEGRAM_CHAT_ID` env var needed — it's in the config):
151
-
152
- ```bash
153
- LUCIFER_TELEGRAM_TOKEN=your_bot_token npx lucifer-gate --config ./config/lucifer.json
154
- ```
155
-
156
- > **Manual alternative:** You can still set `LUCIFER_TELEGRAM_CHAT_ID` as an environment variable instead of using `pair`. The env var takes precedence over the config file value.
45
+ 1. Create a Telegram bot via [@BotFather](https://t.me/BotFather) and get the
46
+ token.
47
+ 2. Send any message to your bot from the chat you want to use for approvals.
48
+ 3. Pair the chat:
157
49
 
158
- When a `manual_approve` command arrives, you'll see an inline keyboard in Telegram:
50
+ ```bash
51
+ LUCIFER_TELEGRAM_TOKEN=your_bot_token npx lucifer-gate pair --config ./config/lucifer.json
52
+ ```
159
53
 
160
- ```
161
- Command Request from key-name (192.168.1.5)
162
- git push origin main
163
-
164
- [Exact 2h] [Exact 8h] [Exact forever]
165
- ["git push" 2h] ["git push" 8h]
166
- [Deny]
167
- ```
54
+ The wizard lists chats that have messaged the bot, sends a 6-digit
55
+ verification code, and writes the chosen chat ID into `lucifer.json`.
56
+ 4. Start the server:
168
57
 
169
- ## API
58
+ ```bash
59
+ LUCIFER_TELEGRAM_TOKEN=your_bot_token npx lucifer-gate --config ./config/lucifer.json
60
+ ```
170
61
 
171
- ### POST /api/v1/execute
62
+ See [docs/specs/operator-workflows.md](docs/specs/operator-workflows.md) for
63
+ the full pairing, `--init`, `log`, and `stats` contract.
172
64
 
173
- Execute a command. The endpoint is synchronous: it blocks until the command
174
- reaches a terminal state (approved + executed, denied, or approval timed out)
175
- and returns the full result in a single response.
176
-
177
- ```bash
178
- curl -X POST http://localhost:3001/api/v1/execute \
179
- -H "Content-Type: application/json" \
180
- -H "x-api-key: luc_yourkey" \
181
- -d '{"command":"git status"}'
182
- ```
183
-
184
- Success response:
185
- ```json
186
- { "requestId": "uuid", "status": "completed", "exitCode": 0, "stdout": "...", "stderr": "", "durationMs": 42 }
187
- ```
188
-
189
- Status values observable on success/failure paths: `completed`, `failed`,
190
- `denied`, `timed_out`.
191
-
192
- ### Error responses
193
-
194
- All errors return:
195
- ```json
196
- { "code": "ERROR_CODE", "message": "Human readable", "retryable": true }
197
- ```
198
-
199
- Codes: `MISSING_API_KEY`, `INVALID_API_KEY`, `IP_NOT_ALLOWED`, `RATE_LIMITED`,
200
- `COMMAND_DENIED`, `COMMAND_TOO_LONG`, `INVALID_CWD`, `DENIED`,
201
- `DUPLICATE_IN_FLIGHT` (an identical command from this API key is already
202
- awaiting approval — retry after it settles), `APPROVAL_TIMEOUT`,
203
- `APPROVAL_ERROR`.
65
+ When a `manual_approve` command arrives, an inline keyboard appears in
66
+ Telegram with buttons for exact / prefix approval and lifetimes of 2h, 8h,
67
+ or permanent, plus a Deny button. Approval shapes and storage semantics live
68
+ in [docs/specs/approval-channels.md](docs/specs/approval-channels.md).
204
69
 
205
70
  ## CLI
206
71
 
@@ -213,83 +78,33 @@ lucifer-gate log [--limit N] Query audit log
213
78
  lucifer-gate stats Show approval statistics
214
79
  ```
215
80
 
216
- ## Docker
81
+ ## Configuration, logging, Docker, env vars
217
82
 
218
- ```bash
219
- docker build -t lucifer-gate .
220
- docker run -p 3001:3001 \
221
- -e LUCIFER_TELEGRAM_TOKEN=your_token \
222
- -e LUCIFER_TELEGRAM_CHAT_ID=your_chat_id \
223
- -v ./config:/app/config \
224
- -v ./data:/app/data \
225
- lucifer-gate
226
- ```
83
+ All operator-side configuration — file locations, environment variables,
84
+ logging setup, and the Docker recipe — lives in
85
+ [docs/CONFIGURATION.md](docs/CONFIGURATION.md).
227
86
 
228
- ## Logging
87
+ Per-feature contracts live under [docs/specs/](docs/specs/):
229
88
 
230
- Lucifer logs to **both console and file** by default.
231
-
232
- **Console output** is human-readable (colorized, formatted) when `pino-pretty` is available, and falls back to structured JSON otherwise. `pino-pretty` is included when you clone the repo and run `npm install`, but is not bundled with the published npm package — so `npx lucifer-gate` uses JSON console output. This is expected and fully functional.
233
-
234
- **File output** is always structured JSON (one object per line), written to `data/lucifer.log` by default. Each line is a complete JSON object, making it easy to search, filter, and feed into log aggregators.
235
-
236
- File logging is enabled via `config/lucifer.json`:
237
-
238
- ```json
239
- {
240
- "logFile": "lucifer.log",
241
- ...
242
- }
243
- ```
244
-
245
- The `logFile` path is relative to `dataDir` (default: `data/lucifer.log`). Remove the key to disable file logging. The `--init` command generates the config with file logging enabled.
246
-
247
- **Log levels** (controlled via `LOG_LEVEL` env var):
248
- - `debug` — verbose output (default in development)
249
- - `info` — normal operations (default in production, when `NODE_ENV=production`)
250
- - `warn` — potential issues
251
- - `error` — failures only
252
-
253
- Example:
254
- ```bash
255
- LOG_LEVEL=info LUCIFER_TELEGRAM_TOKEN=your_token npx lucifer-gate --config ./config/lucifer.json
256
- ```
257
-
258
- ## Environment variables
259
-
260
- | Variable | Required | Description |
261
- |---|---|---|
262
- | `LUCIFER_TELEGRAM_TOKEN` | Yes (prod) | Telegram bot token from @BotFather |
263
- | `LUCIFER_TELEGRAM_CHAT_ID` | No | Telegram chat ID (use `pair` command instead, or set manually) |
264
- | `LUCIFER_ADMIN_SECRET` | No | Bearer token for admin endpoints |
265
- | `PORT` | No | Server port (default: 3001) |
266
- | `LOG_LEVEL` | No | Log level: `debug`, `info`, `warn`, `error` (default: `debug` / `info` in production) |
267
- | `NODE_ENV` | No | Set to `production` for production defaults (info log level, no pretty-printing) |
268
-
269
- ## Architecture
270
-
271
- ```
272
- server/src/domains/
273
- command-gateway/ Core domain
274
- types/ CommandRequest, Approval, types
275
- config/ Gateway configuration
276
- repository/ SQLite stores, JSON config readers
277
- service/ Auth, rules, risk analysis, execution, approvals
278
- api/ Execute routes + web approval UI routes
279
- platform-api/ Health endpoint + server runtime wiring
280
- request-proxy/ Optional transparent HTTP proxy listeners
281
- types/ ProxyMapping, ProxyConfig
282
- config/ proxy-config.json loader + port-collision validation
283
- service/ http-proxy-middleware-backed listeners
284
- ```
89
+ | Topic | Source of truth |
90
+ |---|---|
91
+ | Execute API & error codes | [specs/command-execution.md](docs/specs/command-execution.md) |
92
+ | Command aliases | [specs/command-execution.md#aliases](docs/specs/command-execution.md#aliases) |
93
+ | Approval channels (Telegram, web admin, auto-approve) | [specs/approval-channels.md](docs/specs/approval-channels.md) |
94
+ | Operator workflows (init, pair, start, audit) | [specs/operator-workflows.md](docs/specs/operator-workflows.md) |
95
+ | Transparent HTTP proxy | [specs/transparent-proxy.md](docs/specs/transparent-proxy.md) |
96
+ | Platform health | [specs/platform-health.md](docs/specs/platform-health.md) |
97
+ | User journeys | [specs/USER-JOURNEYS.md](docs/specs/USER-JOURNEYS.md) |
98
+ | Architecture map | [architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md) |
285
99
 
286
- Dependency flow: Types -> Config -> Repository -> Service -> Runtime -> UI/API
100
+ For agent-specific instructions (task lifecycle, review checklist, skills),
101
+ start at [AGENTS.md](AGENTS.md).
287
102
 
288
103
  ## Stack
289
104
 
290
105
  - Express 5 + TypeScript
291
- - SQLite (better-sqlite3) for approvals + audit
106
+ - SQLite (better-sqlite3) for approvals + audit log
292
107
  - Telegraf for Telegram bot
293
108
  - Optional server-delivered web approval UI with SSE updates
294
- - Pino for structured logging (pino-pretty for human-readable console output in dev)
109
+ - Pino for structured logging (pino-pretty for human-readable dev console)
295
110
  - Vitest for testing
@@ -48,6 +48,82 @@ function initApprovalChannel(deps, autoApprove, telegramApiRoot) {
48
48
  }
49
49
  return channels.length === 1 ? channels[0] : createMultiApprovalChannel(channels);
50
50
  }
51
+ /**
52
+ * Adapter from the command-gateway ApiKeyStore to the proxy-domain
53
+ * ProxyTokenValidator contract. Kept in this composition file so
54
+ * `request-proxy` never imports from `command-gateway`.
55
+ */
56
+ function createProxyTokenValidator(apiKeyStore) {
57
+ return {
58
+ validate(rawToken) {
59
+ const entry = apiKeyStore.findByKey(rawToken);
60
+ if (!entry)
61
+ return undefined;
62
+ return { keyId: entry.id, keyName: entry.name };
63
+ },
64
+ };
65
+ }
66
+ /**
67
+ * Adapter from the command-gateway ApprovalChannel to the proxy-domain
68
+ * ProxyApprovalRequester contract. Synthesises a human-readable descriptor
69
+ * as the "command" string and races against an approval timeout so the
70
+ * proxy request cannot block indefinitely waiting for a human.
71
+ */
72
+ function createProxyApprovalRequester(approvalChannel, approvalTimeoutSeconds) {
73
+ return {
74
+ async request(ctx) {
75
+ const descriptor = `HTTP proxy ${ctx.method} ${ctx.path} (port ${ctx.port}) by ${ctx.keyName}`;
76
+ let timer;
77
+ const timeoutPromise = new Promise((resolve) => {
78
+ timer = setTimeout(() => resolve('timeout'), approvalTimeoutSeconds * 1000);
79
+ });
80
+ try {
81
+ const approvalPromise = approvalChannel
82
+ .requestApproval(descriptor, ctx.keyName, ctx.ip, ctx.requestId, { level: 'safe', warnings: [] })
83
+ .then((r) => (r.decision === 'approved' ? 'approved' : 'denied'));
84
+ const outcome = await Promise.race([approvalPromise, timeoutPromise]);
85
+ if (outcome === 'timeout') {
86
+ approvalChannel.cancel?.(ctx.requestId);
87
+ }
88
+ return outcome;
89
+ }
90
+ catch (err) {
91
+ log.warn({ err, requestId: ctx.requestId }, 'Proxy approval channel threw');
92
+ return 'error';
93
+ }
94
+ finally {
95
+ if (timer)
96
+ clearTimeout(timer);
97
+ }
98
+ },
99
+ };
100
+ }
101
+ /**
102
+ * Adapter from proxy audit events to the command-gateway audit log, so
103
+ * proxy auth/approval activity shows up in `lucifer-gate log` alongside
104
+ * command activity.
105
+ */
106
+ function createProxyAuditSink(auditLog) {
107
+ return {
108
+ record(event) {
109
+ try {
110
+ auditLog.append({
111
+ ts: event.ts,
112
+ type: event.type,
113
+ requestId: event.requestId,
114
+ command: `HTTP proxy ${event.method} ${event.path} (port ${event.port})`,
115
+ apiKeyName: event.keyName,
116
+ ip: event.ip,
117
+ approvedBy: event.source,
118
+ error: event.reason,
119
+ });
120
+ }
121
+ catch (err) {
122
+ log.warn({ err }, 'Failed to write proxy audit event');
123
+ }
124
+ },
125
+ };
126
+ }
51
127
  export function createApp(options = {}) {
52
128
  const serverConfig = getServerConfig();
53
129
  const metadataRepository = createRuntimeMetadataRepository();
@@ -73,6 +149,7 @@ export function createApp(options = {}) {
73
149
  }
74
150
  let approvalChannel;
75
151
  let cleanupInterval;
152
+ const proxyDeps = {};
76
153
  // Only initialize gateway if config files exist
77
154
  if (fs.existsSync(apiKeysPath) && fs.existsSync(commandRulesPath)) {
78
155
  const db = getDatabase(gatewayConfig.dataDir);
@@ -91,6 +168,11 @@ export function createApp(options = {}) {
91
168
  approvalStore.removeExpired();
92
169
  pendingStore.cleanup(gatewayConfig.approvalTimeoutSeconds * 1000);
93
170
  }, 60_000);
171
+ // Wire the proxy bridges over gateway stores so request-proxy stays
172
+ // isolated from command-gateway code (Dependency Rules).
173
+ proxyDeps.tokenValidator = createProxyTokenValidator(apiKeyStore);
174
+ proxyDeps.approvalRequester = createProxyApprovalRequester(approvalChannel, gatewayConfig.approvalTimeoutSeconds);
175
+ proxyDeps.auditSink = createProxyAuditSink(auditLog);
94
176
  log.info('Command gateway initialized');
95
177
  }
96
178
  else {
@@ -105,7 +187,7 @@ export function createApp(options = {}) {
105
187
  const proxyConfig = loadProxyConfig(proxyConfigPath);
106
188
  if (proxyConfig && proxyConfig.proxies.length > 0) {
107
189
  validateProxyPorts(proxyConfig.proxies, gatewayConfig.port);
108
- proxyServers = createProxyServers(proxyConfig.proxies);
190
+ proxyServers = createProxyServers(proxyConfig.proxies, proxyDeps);
109
191
  log.info({ count: proxyConfig.proxies.length }, 'Transparent proxy mappings configured');
110
192
  }
111
193
  async function start() {
@@ -1 +1 @@
1
- {"version":3,"file":"create_app.js","sourceRoot":"","sources":["../../server/src/create_app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create_app.js","sourceRoot":"","sources":["../../server/src/create_app.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,9 @@ function isValidHeaders(value) {
20
20
  return false;
21
21
  return Object.values(value).every((v) => typeof v === 'string');
22
22
  }
23
+ function isValidAuthMode(value) {
24
+ return value === 'none' || value === 'api-key' || value === 'api-key-telegram';
25
+ }
23
26
  function isProxyMapping(value) {
24
27
  if (typeof value !== 'object' || value === null)
25
28
  return false;
@@ -32,6 +35,24 @@ function isProxyMapping(value) {
32
35
  return false;
33
36
  if (m.host !== undefined && (typeof m.host !== 'string' || m.host.length === 0))
34
37
  return false;
38
+ if (m.authMode !== undefined && !isValidAuthMode(m.authMode))
39
+ return false;
40
+ if (m.apiKeyHeader !== undefined && (typeof m.apiKeyHeader !== 'string' || m.apiKeyHeader.length === 0))
41
+ return false;
42
+ if (m.apiKeyPrefix !== undefined && typeof m.apiKeyPrefix !== 'string')
43
+ return false;
44
+ if (m.telegramApprovalTtlSeconds !== undefined &&
45
+ (typeof m.telegramApprovalTtlSeconds !== 'number'
46
+ || !Number.isInteger(m.telegramApprovalTtlSeconds)
47
+ || m.telegramApprovalTtlSeconds < 0)) {
48
+ return false;
49
+ }
50
+ // When auth is required, the caller header name is mandatory. Fail fast at
51
+ // load time rather than at the first request — the operator wants a
52
+ // descriptive startup error, not a 500 later.
53
+ if (m.authMode !== undefined && m.authMode !== 'none' && m.apiKeyHeader === undefined) {
54
+ return false;
55
+ }
35
56
  return true;
36
57
  }
37
58
  function isProxyConfig(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_config.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/config/proxy_config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy_config.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/config/proxy_config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * In-memory TTL cache for "approved" proxy decisions, keyed by the tuple
3
+ * `(api-key-id, port)`. A cache hit means the token-holder has an
4
+ * unexpired Telegram approval for this specific proxy listener, so the
5
+ * next request is forwarded without asking the approver again.
6
+ *
7
+ * Why in-memory (and not SQLite, like command approvals): proxy traffic is
8
+ * expected to be high-volume and the approval is scoped to a running agent
9
+ * session. Survival across restarts is a non-goal for v1 — an operator
10
+ * restart should re-prompt, which is the conservative default. Persisting
11
+ * proxy approvals can be added later without changing the cache API.
12
+ */
13
+ /**
14
+ * Construct a cache. `now` is injectable so tests can advance time
15
+ * without using real timers.
16
+ */
17
+ export function createProxyApprovalCache(now = Date.now) {
18
+ const entries = new Map();
19
+ function cacheKey(key) {
20
+ return `${key.keyId}::${key.port}`;
21
+ }
22
+ return {
23
+ has(key) {
24
+ const expiresAt = entries.get(cacheKey(key));
25
+ if (expiresAt === undefined)
26
+ return false;
27
+ if (expiresAt <= now()) {
28
+ entries.delete(cacheKey(key));
29
+ return false;
30
+ }
31
+ return true;
32
+ },
33
+ set(key, ttlSeconds) {
34
+ if (ttlSeconds <= 0) {
35
+ // A zero/negative TTL means "do not cache". Dropping the write is
36
+ // simpler than surfacing an error — callers disable caching by
37
+ // setting the config value to 0.
38
+ entries.delete(cacheKey(key));
39
+ return;
40
+ }
41
+ entries.set(cacheKey(key), now() + ttlSeconds * 1000);
42
+ },
43
+ clear() {
44
+ entries.clear();
45
+ },
46
+ };
47
+ }
48
+ //# sourceMappingURL=proxy_approval_cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy_approval_cache.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/service/proxy_approval_cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAoB,IAAI,CAAC,GAAG;IACnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,SAAS,QAAQ,CAAC,GAA0B;QAC1C,OAAO,GAAG,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;IACrC,CAAC;IAED,OAAO;QACL,GAAG,CAAC,GAA0B;YAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC7C,IAAI,SAAS,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YAC1C,IAAI,SAAS,IAAI,GAAG,EAAE,EAAE,CAAC;gBACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC9B,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,GAAG,CAAC,GAA0B,EAAE,UAAkB;YAChD,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;gBACpB,kEAAkE;gBAClE,+DAA+D;gBAC/D,iCAAiC;gBACjC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;QACxD,CAAC;QAED,KAAK;YACH,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,220 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { DEFAULT_PROXY_APPROVAL_TTL_SECONDS } from '../types/proxy_types.js';
3
+ import { createChildLogger } from '../../../lib/logger.js';
4
+ const log = createChildLogger('proxy-auth');
5
+ /**
6
+ * Authenticate and (optionally) request approval for a single proxy request.
7
+ *
8
+ * Pure logic — takes the incoming request and the per-mapping dependencies,
9
+ * returns a decision. The proxy server is responsible for writing the 401/403
10
+ * response and for deleting the caller's auth header from the forwarded
11
+ * request when the decision is `pass`.
12
+ */
13
+ export async function authorizeProxyRequest(req, deps) {
14
+ const { mapping, validator, approvalRequester, cache, audit, generateRequestId } = deps;
15
+ const requestId = generateRequestId ? generateRequestId() : randomUUID();
16
+ const authMode = mapping.authMode ?? 'none';
17
+ // Extract non-sensitive primitives once. Downstream logging/audit reads
18
+ // these locals, never the full mapping object — this keeps the taint-flow
19
+ // analyzer from painting `port`/`method`/`path` as derived from the
20
+ // header-configuration fields (`apiKeyHeader`, `apiKeyPrefix`), which are
21
+ // only header *names*, not credentials.
22
+ const port = mapping.port;
23
+ const method = req.method ?? 'GET';
24
+ const path = req.url ?? '/';
25
+ const ip = callerIp(req);
26
+ if (authMode === 'none') {
27
+ return { kind: 'pass', requestId };
28
+ }
29
+ const headerName = mapping.apiKeyHeader;
30
+ if (headerName === undefined) {
31
+ // Config loader should reject this, but fail closed if we ever see it.
32
+ recordAudit(audit, {
33
+ type: 'proxy_auth_denied', requestId, port, method, path, ip,
34
+ reason: 'apiKeyHeader not configured',
35
+ });
36
+ return {
37
+ kind: 'reject', requestId,
38
+ status: 500, code: 'misconfigured',
39
+ message: 'Proxy mapping is misconfigured (apiKeyHeader missing).',
40
+ };
41
+ }
42
+ if (!validator) {
43
+ recordAudit(audit, {
44
+ type: 'proxy_auth_denied', requestId, port, method, path, ip,
45
+ reason: 'no validator wired',
46
+ });
47
+ return {
48
+ kind: 'reject', requestId,
49
+ status: 500, code: 'misconfigured',
50
+ message: 'Proxy auth is configured but no token validator is available.',
51
+ };
52
+ }
53
+ const rawToken = extractToken(req, headerName, mapping.apiKeyPrefix);
54
+ if (rawToken === undefined) {
55
+ recordAudit(audit, {
56
+ type: 'proxy_auth_denied', requestId, port, method, path, ip,
57
+ reason: 'missing or malformed header',
58
+ });
59
+ return {
60
+ kind: 'reject', requestId,
61
+ status: 401, code: 'unauthorized',
62
+ message: 'Missing or malformed authentication header.',
63
+ };
64
+ }
65
+ const identity = validator.validate(rawToken);
66
+ if (!identity) {
67
+ recordAudit(audit, {
68
+ type: 'proxy_auth_denied', requestId, port, method, path, ip,
69
+ reason: 'invalid token',
70
+ });
71
+ return {
72
+ kind: 'reject', requestId,
73
+ status: 401, code: 'unauthorized',
74
+ message: 'Invalid authentication token.',
75
+ };
76
+ }
77
+ if (authMode === 'api-key') {
78
+ recordAudit(audit, {
79
+ type: 'proxy_auth_ok', requestId, port, method, path, ip, identity,
80
+ });
81
+ return { kind: 'pass', requestId, keyId: identity.keyId, keyName: identity.keyName };
82
+ }
83
+ // authMode === 'api-key-telegram'
84
+ if (!approvalRequester) {
85
+ recordAudit(audit, {
86
+ type: 'proxy_approval_error', requestId, port, method, path, ip, identity,
87
+ reason: 'no approval requester wired',
88
+ });
89
+ return {
90
+ kind: 'reject', requestId,
91
+ status: 500, code: 'misconfigured',
92
+ message: 'Telegram approval is configured but no approval channel is available.',
93
+ };
94
+ }
95
+ const cacheKey = { keyId: identity.keyId, port };
96
+ if (cache?.has(cacheKey)) {
97
+ recordAudit(audit, {
98
+ type: 'proxy_approval_approved', requestId, port, method, path, ip, identity, source: 'cache',
99
+ });
100
+ return { kind: 'pass', requestId, keyId: identity.keyId, keyName: identity.keyName };
101
+ }
102
+ const approvalCtx = {
103
+ port,
104
+ baseUrl: mapping.baseUrl,
105
+ method,
106
+ path,
107
+ keyId: identity.keyId,
108
+ keyName: identity.keyName,
109
+ ip,
110
+ requestId,
111
+ };
112
+ recordAudit(audit, {
113
+ type: 'proxy_approval_requested', requestId, port, method, path, ip, identity,
114
+ });
115
+ let outcome;
116
+ try {
117
+ outcome = await approvalRequester.request(approvalCtx);
118
+ }
119
+ catch (err) {
120
+ log.error({ err, requestId, port }, 'Approval requester threw');
121
+ recordAudit(audit, {
122
+ type: 'proxy_approval_error', requestId, port, method, path, ip, identity,
123
+ reason: err instanceof Error ? err.message : 'approval error',
124
+ });
125
+ return {
126
+ kind: 'reject', requestId,
127
+ status: 503, code: 'approval_error',
128
+ message: 'Approval channel failed.',
129
+ };
130
+ }
131
+ if (outcome === 'approved') {
132
+ const ttl = mapping.telegramApprovalTtlSeconds ?? DEFAULT_PROXY_APPROVAL_TTL_SECONDS;
133
+ cache?.set(cacheKey, ttl);
134
+ recordAudit(audit, {
135
+ type: 'proxy_approval_approved', requestId, port, method, path, ip, identity, source: 'telegram',
136
+ });
137
+ return { kind: 'pass', requestId, keyId: identity.keyId, keyName: identity.keyName };
138
+ }
139
+ if (outcome === 'timeout') {
140
+ recordAudit(audit, {
141
+ type: 'proxy_approval_timeout', requestId, port, method, path, ip, identity,
142
+ });
143
+ return {
144
+ kind: 'reject', requestId,
145
+ status: 408, code: 'approval_timeout',
146
+ message: 'Approval timed out.',
147
+ };
148
+ }
149
+ if (outcome === 'error') {
150
+ recordAudit(audit, {
151
+ type: 'proxy_approval_error', requestId, port, method, path, ip, identity,
152
+ reason: 'approval channel error',
153
+ });
154
+ return {
155
+ kind: 'reject', requestId,
156
+ status: 503, code: 'approval_error',
157
+ message: 'Approval channel failed.',
158
+ };
159
+ }
160
+ // outcome === 'denied'
161
+ recordAudit(audit, {
162
+ type: 'proxy_approval_denied', requestId, port, method, path, ip, identity,
163
+ });
164
+ return {
165
+ kind: 'reject', requestId,
166
+ status: 403, code: 'forbidden',
167
+ message: 'Approval denied.',
168
+ };
169
+ }
170
+ /**
171
+ * Extract the token value from the configured header (case-insensitive).
172
+ * Returns `undefined` when missing, empty, or when a required prefix is
173
+ * not present.
174
+ */
175
+ function extractToken(req, headerName, prefix) {
176
+ const lower = headerName.toLowerCase();
177
+ const raw = req.headers[lower];
178
+ const value = Array.isArray(raw) ? raw[0] : raw;
179
+ if (typeof value !== 'string' || value.length === 0)
180
+ return undefined;
181
+ if (prefix !== undefined && prefix.length > 0) {
182
+ if (!value.startsWith(prefix))
183
+ return undefined;
184
+ const stripped = value.slice(prefix.length);
185
+ return stripped.length > 0 ? stripped : undefined;
186
+ }
187
+ return value;
188
+ }
189
+ /**
190
+ * Best-effort remote address extraction. The proxy listeners bind to loopback
191
+ * by default, so in production this is primarily used for audit context
192
+ * rather than authorization.
193
+ */
194
+ function callerIp(req) {
195
+ return req.socket?.remoteAddress ?? 'unknown';
196
+ }
197
+ function recordAudit(sink, args) {
198
+ if (!sink)
199
+ return;
200
+ const event = {
201
+ type: args.type,
202
+ ts: new Date().toISOString(),
203
+ requestId: args.requestId,
204
+ port: args.port,
205
+ method: args.method,
206
+ path: args.path,
207
+ keyId: args.identity?.keyId,
208
+ keyName: args.identity?.keyName,
209
+ ip: args.ip,
210
+ reason: args.reason,
211
+ source: args.source,
212
+ };
213
+ try {
214
+ sink.record(event);
215
+ }
216
+ catch (err) {
217
+ log.warn({ err, requestId: args.requestId }, 'Proxy audit sink threw; continuing');
218
+ }
219
+ }
220
+ //# sourceMappingURL=proxy_auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy_auth.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/service/proxy_auth.ts"],"names":[],"mappings":"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"}
@@ -2,14 +2,29 @@ import http from 'node:http';
2
2
  import { createProxyMiddleware } from 'http-proxy-middleware';
3
3
  import { DEFAULT_PROXY_HOST } from '../types/proxy_types.js';
4
4
  import { createChildLogger } from '../../../lib/logger.js';
5
+ import { authorizeProxyRequest } from './proxy_auth.js';
6
+ import { createProxyApprovalCache } from './proxy_approval_cache.js';
5
7
  const log = createChildLogger('proxy');
6
- function buildProxyServer(mapping) {
8
+ function writeJsonError(res, status, code, message) {
9
+ if (res.headersSent)
10
+ return;
11
+ res.writeHead(status, { 'Content-Type': 'application/json' });
12
+ res.end(JSON.stringify({ error: code, message }));
13
+ }
14
+ function buildProxyServer(mapping, deps, cache) {
7
15
  const middleware = createProxyMiddleware({
8
16
  target: mapping.baseUrl,
9
17
  changeOrigin: true,
10
18
  logger: log,
11
19
  on: {
12
20
  proxyReq: (proxyReq) => {
21
+ // Defense-in-depth: also strip the caller's auth header from the
22
+ // outgoing request. The incoming req.headers has already been
23
+ // mutated (see handler below), but proxyReq.removeHeader is the
24
+ // authoritative write onto the outgoing socket.
25
+ if (mapping.authMode && mapping.authMode !== 'none' && mapping.apiKeyHeader) {
26
+ proxyReq.removeHeader(mapping.apiKeyHeader);
27
+ }
13
28
  if (!mapping.headers)
14
29
  return;
15
30
  for (const [name, value] of Object.entries(mapping.headers)) {
@@ -28,12 +43,34 @@ function buildProxyServer(mapping) {
28
43
  },
29
44
  });
30
45
  return http.createServer((req, res) => {
31
- middleware(req, res).catch((err) => {
32
- log.error({ err, port: mapping.port }, 'Proxy middleware threw');
33
- if (!res.headersSent) {
34
- res.writeHead(502, { 'Content-Type': 'application/json' });
35
- res.end(JSON.stringify({ error: 'bad_gateway', message: 'Proxy handler failed' }));
46
+ authorizeProxyRequest(req, {
47
+ mapping,
48
+ validator: deps.tokenValidator,
49
+ approvalRequester: deps.approvalRequester,
50
+ cache,
51
+ audit: deps.auditSink,
52
+ })
53
+ .then((decision) => {
54
+ if (decision.kind === 'reject') {
55
+ writeJsonError(res, decision.status, decision.code, decision.message);
56
+ return;
57
+ }
58
+ // Strip the caller's auth header from req.headers before the proxy
59
+ // middleware forwards it, so the lucifer-gate token does not leak
60
+ // upstream. The proxyReq handler also removes it on the outgoing
61
+ // socket (belt and braces).
62
+ if (mapping.authMode && mapping.authMode !== 'none' && mapping.apiKeyHeader) {
63
+ delete req.headers[mapping.apiKeyHeader.toLowerCase()];
36
64
  }
65
+ middleware(req, res).catch((err) => {
66
+ log.error({ err, port: mapping.port }, 'Proxy middleware threw');
67
+ writeJsonError(res, 502, 'bad_gateway', 'Proxy handler failed');
68
+ });
69
+ })
70
+ .catch((err) => {
71
+ // authorizeProxyRequest never rejects, but guard just in case.
72
+ log.error({ err, port: mapping.port }, 'Proxy auth threw unexpectedly');
73
+ writeJsonError(res, 500, 'internal_error', 'Proxy authorization failed');
37
74
  });
38
75
  });
39
76
  }
@@ -69,6 +106,26 @@ async function bestEffortClose(server) {
69
106
  log.warn({ err }, 'Error while closing proxy listener');
70
107
  }
71
108
  }
109
+ /**
110
+ * Validate that every mapping with a non-`none` authMode has the runtime
111
+ * deps it needs. Called at startup so operators get a descriptive error
112
+ * rather than a confusing 500 on the first request.
113
+ */
114
+ function validateMappingDeps(mappings, deps) {
115
+ for (const [index, m] of mappings.entries()) {
116
+ const mode = m.authMode ?? 'none';
117
+ if (mode === 'none')
118
+ continue;
119
+ if (!deps.tokenValidator) {
120
+ throw new Error(`Proxy mapping proxies[${index}] (port ${m.port}) has authMode='${mode}' but no token validator is wired. ` +
121
+ `Ensure api-keys.json is present so the gateway is initialized before the proxy.`);
122
+ }
123
+ if (mode === 'api-key-telegram' && !deps.approvalRequester) {
124
+ throw new Error(`Proxy mapping proxies[${index}] (port ${m.port}) has authMode='api-key-telegram' but no approval channel is wired. ` +
125
+ `Configure Telegram (LUCIFER_TELEGRAM_TOKEN + chat id) or the web approval UI.`);
126
+ }
127
+ }
128
+ }
72
129
  /**
73
130
  * Build proxy servers for a set of mappings. Listeners are NOT bound until
74
131
  * `start()` is called so that `createApp()` stays synchronous and config
@@ -78,11 +135,17 @@ async function bestEffortClose(server) {
78
135
  * started listeners are closed before the error is rethrown, so the caller
79
136
  * never observes a partially-started set.
80
137
  */
81
- export function createProxyServers(mappings) {
82
- const running = mappings.map((mapping) => ({
83
- mapping,
84
- server: buildProxyServer(mapping),
85
- }));
138
+ export function createProxyServers(mappings, deps = {}) {
139
+ validateMappingDeps(mappings, deps);
140
+ const cacheFactory = deps.approvalCacheFactory ?? (() => createProxyApprovalCache());
141
+ const running = mappings.map((mapping) => {
142
+ const cache = cacheFactory();
143
+ return {
144
+ mapping,
145
+ cache,
146
+ server: buildProxyServer(mapping, deps, cache),
147
+ };
148
+ });
86
149
  async function start() {
87
150
  const started = [];
88
151
  try {
@@ -90,7 +153,7 @@ export function createProxyServers(mappings) {
90
153
  const host = entry.mapping.host ?? DEFAULT_PROXY_HOST;
91
154
  await listenAsync(entry.server, entry.mapping.port, host);
92
155
  started.push(entry);
93
- log.info({ port: entry.mapping.port, host, baseUrl: entry.mapping.baseUrl }, 'Proxy listening');
156
+ log.info({ port: entry.mapping.port, host, baseUrl: entry.mapping.baseUrl, authMode: entry.mapping.authMode ?? 'none' }, 'Proxy listening');
94
157
  }
95
158
  }
96
159
  catch (err) {
@@ -103,7 +166,10 @@ export function createProxyServers(mappings) {
103
166
  async function stop() {
104
167
  // Best-effort close: a listener that never bound (e.g. because start()
105
168
  // failed partway) must not prevent cleanup of the rest.
106
- await Promise.all(running.map(({ server }) => bestEffortClose(server)));
169
+ await Promise.all(running.map(({ server, cache }) => {
170
+ cache.clear();
171
+ return bestEffortClose(server);
172
+ }));
107
173
  }
108
174
  return { start, stop };
109
175
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_server.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/service/proxy_server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy_server.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/service/proxy_server.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,4 @@
1
+ export const DEFAULT_PROXY_AUTH_MODE = 'none';
2
+ export const DEFAULT_PROXY_APPROVAL_TTL_SECONDS = 3600;
1
3
  export const DEFAULT_PROXY_HOST = '127.0.0.1';
2
4
  //# sourceMappingURL=proxy_types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy_types.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/types/proxy_types.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC"}
1
+ {"version":3,"file":"proxy_types.js","sourceRoot":"","sources":["../../../../../server/src/domains/request-proxy/types/proxy_types.ts"],"names":[],"mappings":"AA0BA,MAAM,CAAC,MAAM,uBAAuB,GAAkB,MAAM,CAAC;AAC7D,MAAM,CAAC,MAAM,kCAAkC,GAAG,IAAI,CAAC;AAavD,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC"}
@@ -17,7 +17,9 @@ export function createTestAppContext(label, options) {
17
17
  approvalTimeoutSeconds: 5,
18
18
  executionTimeoutSeconds: 10,
19
19
  maxConcurrentExecutions: 3,
20
- maxOutputBytes: 1024,
20
+ // Integration tests run real commands against the repo (e.g. `git status`),
21
+ // so this needs to accommodate a growing working tree. 1 KiB was brittle.
22
+ maxOutputBytes: 65536,
21
23
  rateLimitPerMinute: 100,
22
24
  onApprovalTimeout: 'deny',
23
25
  dataDir: '../data',
@@ -1 +1 @@
1
- {"version":3,"file":"integration-setup.js","sourceRoot":"","sources":["../../../server/src/test/integration-setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration-setup.js","sourceRoot":"","sources":["../../../server/src/test/integration-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,wDAAwD,CAAC;AAUpF,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,OAGC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,OAAO,KAAK,QAAQ,CAAC;IACrC,MAAM,QAAQ,GAAG,GAAG,KAAK,eAAe,CAAC;IACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE/C,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAEnD,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;QACvC,IAAI,EAAE,CAAC;QACP,sBAAsB,EAAE,CAAC;QACzB,uBAAuB,EAAE,EAAE;QAC3B,uBAAuB,EAAE,CAAC;QAC1B,4EAA4E;QAC5E,0EAA0E;QAC1E,cAAc,EAAE,KAAK;QACrB,kBAAkB,EAAE,GAAG;QACvB,iBAAiB,EAAE,MAAM;QACzB,OAAO,EAAE,SAAS;QAClB,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC,CAAC,CAAC;IAEJ,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;QAC7D,IAAI,EAAE,CAAC;gBACL,EAAE,EAAE,GAAG,KAAK,OAAO;gBACnB,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,QAAQ;gBACjB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;gBACd,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,MAAM,EAAE,IAAI;aACb,CAAC;KACH,CAAC,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG;QACZ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE;QAC7C,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE;QAC5C,GAAG,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC;KAC/B,CAAC;IAEF,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;QAClE,KAAK;QACL,aAAa,EAAE,aAAa;KAC7B,CAAC,CAAC,CAAC;IAEJ,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5D,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO;QACP,OAAO;KACR,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucifer-gate",
3
- "version": "0.7.4",
3
+ "version": "0.8.0-alpha.1.02835cd",
4
4
  "description": "AI agent command firewall with Telegram-based human approval",
5
5
  "type": "module",
6
6
  "bin": {