airlock-bot 0.2.35 → 0.2.37
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 +31 -1
- package/dist/audit/api.d.ts +2 -0
- package/dist/audit/api.d.ts.map +1 -1
- package/dist/audit/api.js +3 -13
- package/dist/audit/api.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +41 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/config/profiles.d.ts +3 -6
- package/dist/config/profiles.d.ts.map +1 -1
- package/dist/config/profiles.js +52 -19
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/schema.d.ts +368 -8
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +35 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/configure-web/cli.d.ts +41 -2
- package/dist/configure-web/cli.d.ts.map +1 -1
- package/dist/configure-web/cli.js +1283 -55
- package/dist/configure-web/cli.js.map +1 -1
- package/dist/gateway.d.ts +7 -1
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +81 -26
- package/dist/gateway.js.map +1 -1
- package/dist/hitl/api.d.ts +2 -0
- package/dist/hitl/api.d.ts.map +1 -1
- package/dist/hitl/api.js +3 -13
- package/dist/hitl/api.js.map +1 -1
- package/dist/hitl/approval-dashboard.d.ts +19 -0
- package/dist/hitl/approval-dashboard.d.ts.map +1 -0
- package/dist/hitl/approval-dashboard.js +148 -0
- package/dist/hitl/approval-dashboard.js.map +1 -0
- package/dist/hitl/provider-factory.js +1 -1
- package/dist/hitl/provider-factory.js.map +1 -1
- package/dist/hitl/providers/dashboard.d.ts +4 -5
- package/dist/hitl/providers/dashboard.d.ts.map +1 -1
- package/dist/hitl/providers/dashboard.js +29 -469
- package/dist/hitl/providers/dashboard.js.map +1 -1
- package/dist/hook/api.d.ts +2 -0
- package/dist/hook/api.d.ts.map +1 -1
- package/dist/hook/api.js +3 -13
- package/dist/hook/api.js.map +1 -1
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/middleware/chain-builder.d.ts +1 -1
- package/dist/middleware/chain-builder.d.ts.map +1 -1
- package/dist/middleware/chain-builder.js +4 -2
- package/dist/middleware/chain-builder.js.map +1 -1
- package/dist/middleware/core/arg-policy.d.ts +12 -0
- package/dist/middleware/core/arg-policy.d.ts.map +1 -0
- package/dist/middleware/core/arg-policy.js +91 -0
- package/dist/middleware/core/arg-policy.js.map +1 -0
- package/dist/security/request.d.ts +14 -0
- package/dist/security/request.d.ts.map +1 -0
- package/dist/security/request.js +47 -0
- package/dist/security/request.js.map +1 -0
- package/dist/tools/api.d.ts +2 -0
- package/dist/tools/api.d.ts.map +1 -1
- package/dist/tools/api.js +3 -13
- package/dist/tools/api.js.map +1 -1
- package/dist/transport/http-server.d.ts +2 -0
- package/dist/transport/http-server.d.ts.map +1 -1
- package/dist/transport/http-server.js +9 -22
- package/dist/transport/http-server.js.map +1 -1
- package/dist/transport/sse-server.d.ts +2 -0
- package/dist/transport/sse-server.d.ts.map +1 -1
- package/dist/transport/sse-server.js +9 -26
- package/dist/transport/sse-server.js.map +1 -1
- package/examples/docker-compose.yaml +63 -0
- package/examples/docker-gateway.yaml +61 -0
- package/examples/gateway.yaml +7 -0
- package/examples/profiles.yaml +4 -2
- package/package.json +1 -1
- package/schema.json +79 -0
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { timingSafeEqual } from 'crypto';
|
|
2
1
|
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
3
2
|
import { createAgentServer, connectAgentServer } from './agent-server.js';
|
|
4
3
|
import { childLogger } from '../util/logger.js';
|
|
4
|
+
import { checkBearerAuth, checkOrigin, checkRequestSecurity } from '../security/request.js';
|
|
5
5
|
const log = childLogger('sse-server');
|
|
6
6
|
/** Interval between SSE keep-alive pings (ms). Keeps connections alive through NAT/firewalls. */
|
|
7
7
|
const PING_INTERVAL_MS = 30_000;
|
|
8
|
-
function constantTimeEqual(a, b) {
|
|
9
|
-
const bufA = Buffer.from(a);
|
|
10
|
-
const bufB = Buffer.from(b);
|
|
11
|
-
if (bufA.length !== bufB.length)
|
|
12
|
-
return false;
|
|
13
|
-
return timingSafeEqual(bufA, bufB);
|
|
14
|
-
}
|
|
15
8
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
16
9
|
export async function sseServerPlugin(app, opts) {
|
|
17
10
|
const { secret } = opts;
|
|
@@ -23,24 +16,17 @@ export async function sseServerPlugin(app, opts) {
|
|
|
23
16
|
done(null);
|
|
24
17
|
});
|
|
25
18
|
function checkAgentAuth(request, reply, deps) {
|
|
19
|
+
if (!checkOrigin(request, reply, opts.allowedOrigins))
|
|
20
|
+
return false;
|
|
26
21
|
const token = deps.agentConfig.token;
|
|
27
22
|
if (token) {
|
|
28
|
-
|
|
29
|
-
if (!constantTimeEqual(auth, `Bearer ${token}`)) {
|
|
30
|
-
reply.status(401).send({ error: 'Unauthorized' });
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
return true;
|
|
23
|
+
return checkBearerAuth(request, reply, { secret: token, authRequired: true });
|
|
34
24
|
}
|
|
35
25
|
// No per-agent token — fall back to global api_secret
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return true;
|
|
26
|
+
return checkBearerAuth(request, reply, {
|
|
27
|
+
secret,
|
|
28
|
+
authRequired: opts.authRequired,
|
|
29
|
+
});
|
|
44
30
|
}
|
|
45
31
|
// Auth for non-agent endpoints (management API)
|
|
46
32
|
app.addHook('preHandler', async (request, reply) => {
|
|
@@ -48,11 +34,8 @@ export async function sseServerPlugin(app, opts) {
|
|
|
48
34
|
// Agent endpoints handle their own auth
|
|
49
35
|
if (url.startsWith('/agents/'))
|
|
50
36
|
return;
|
|
51
|
-
if (!
|
|
37
|
+
if (!checkRequestSecurity(request, reply, opts)) {
|
|
52
38
|
return;
|
|
53
|
-
const auth = request.headers.authorization ?? '';
|
|
54
|
-
if (!constantTimeEqual(auth, `Bearer ${secret}`)) {
|
|
55
|
-
return reply.status(401).send({ error: 'Unauthorized' });
|
|
56
39
|
}
|
|
57
40
|
});
|
|
58
41
|
app.get('/agents/:profileId/sse', async (request, reply) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse-server.js","sourceRoot":"","sources":["../../src/transport/sse-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sse-server.js","sourceRoot":"","sources":["../../src/transport/sse-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
services:
|
|
2
|
+
airlock-gateway:
|
|
3
|
+
build:
|
|
4
|
+
context: ..
|
|
5
|
+
dockerfile: Dockerfile
|
|
6
|
+
image: airlock-bot:local
|
|
7
|
+
command: gateway --config /config/airlock.yaml
|
|
8
|
+
restart: unless-stopped
|
|
9
|
+
env_file:
|
|
10
|
+
- .env
|
|
11
|
+
environment:
|
|
12
|
+
AIRLOCK_CONFIG: /config/airlock.yaml
|
|
13
|
+
AIRLOCK_HEALTH_PORT: '4111'
|
|
14
|
+
volumes:
|
|
15
|
+
# Runtime gateway can hot-reload this file but cannot modify policy.
|
|
16
|
+
- ./airlock-config:/config:ro
|
|
17
|
+
- airlock-data:/data
|
|
18
|
+
# Keep npx-installed MCP servers cached across restarts.
|
|
19
|
+
- airlock-npm-cache:/home/airlock/.npm
|
|
20
|
+
ports:
|
|
21
|
+
# Bind to loopback by default. Put your TLS/auth proxy on the same host,
|
|
22
|
+
# or change these bindings only for a trusted private network.
|
|
23
|
+
- 127.0.0.1:4111:4111
|
|
24
|
+
read_only: true
|
|
25
|
+
tmpfs:
|
|
26
|
+
- /tmp:rw,nosuid,nodev,size=256m
|
|
27
|
+
cap_drop:
|
|
28
|
+
- ALL
|
|
29
|
+
security_opt:
|
|
30
|
+
- no-new-privileges:true
|
|
31
|
+
# Add reverse-proxy labels or service discovery metadata here if your
|
|
32
|
+
# platform uses container labels.
|
|
33
|
+
|
|
34
|
+
airlock-dashboard:
|
|
35
|
+
image: airlock-bot:local
|
|
36
|
+
command: dashboard --config /config/airlock.yaml --host 0.0.0.0 --port 4112 --gateway-url http://airlock-gateway:4111
|
|
37
|
+
restart: unless-stopped
|
|
38
|
+
env_file:
|
|
39
|
+
- .env
|
|
40
|
+
environment:
|
|
41
|
+
AIRLOCK_CONFIG: /config/airlock.yaml
|
|
42
|
+
AIRLOCK_GATEWAY_SECRET: ${AIRLOCK_API_SECRET}
|
|
43
|
+
AIRLOCK_HEALTH_PORT: '4112'
|
|
44
|
+
volumes:
|
|
45
|
+
# Dashboard owns config mutation and writes /config/airlock.bak.
|
|
46
|
+
- ./airlock-config:/config
|
|
47
|
+
ports:
|
|
48
|
+
- 127.0.0.1:4112:4112
|
|
49
|
+
read_only: true
|
|
50
|
+
tmpfs:
|
|
51
|
+
- /tmp:rw,nosuid,nodev,size=128m
|
|
52
|
+
cap_drop:
|
|
53
|
+
- ALL
|
|
54
|
+
security_opt:
|
|
55
|
+
- no-new-privileges:true
|
|
56
|
+
depends_on:
|
|
57
|
+
- airlock-gateway
|
|
58
|
+
# Add dashboard-specific reverse-proxy labels here. Protect this route with
|
|
59
|
+
# human authentication.
|
|
60
|
+
|
|
61
|
+
volumes:
|
|
62
|
+
airlock-data:
|
|
63
|
+
airlock-npm-cache:
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# yaml-language-server: $schema=../schema.json
|
|
2
|
+
# Minimal Docker/VPS-oriented config. Copy this file next to
|
|
3
|
+
# examples/docker-compose.yaml, create an .env file with the referenced secrets,
|
|
4
|
+
# and edit providers/agents for your deployment.
|
|
5
|
+
|
|
6
|
+
server:
|
|
7
|
+
port: 4111
|
|
8
|
+
host: 0.0.0.0
|
|
9
|
+
api_secret: ${AIRLOCK_API_SECRET}
|
|
10
|
+
auth_required: true
|
|
11
|
+
require_agent_tokens: true
|
|
12
|
+
allowed_origins:
|
|
13
|
+
- https://airlock.example.com
|
|
14
|
+
expose_management_api: true
|
|
15
|
+
expose_tools_api: false
|
|
16
|
+
expose_hook_api: false
|
|
17
|
+
|
|
18
|
+
providers:
|
|
19
|
+
http: builtin
|
|
20
|
+
# Add stdio/SSE/HTTP MCP providers here. If a provider uses npx, the compose
|
|
21
|
+
# example persists /home/airlock/.npm so packages are cached across restarts.
|
|
22
|
+
|
|
23
|
+
agents:
|
|
24
|
+
example-agent:
|
|
25
|
+
token: ${EXAMPLE_AGENT_AIRLOCK_TOKEN}
|
|
26
|
+
allow:
|
|
27
|
+
- http/get
|
|
28
|
+
ask:
|
|
29
|
+
- http/post
|
|
30
|
+
http:
|
|
31
|
+
domain_allowlist:
|
|
32
|
+
- api.github.com
|
|
33
|
+
|
|
34
|
+
approvals:
|
|
35
|
+
provider:
|
|
36
|
+
type: dashboard
|
|
37
|
+
host: 0.0.0.0
|
|
38
|
+
port: 4112
|
|
39
|
+
timeout_ms: 300000
|
|
40
|
+
|
|
41
|
+
security:
|
|
42
|
+
blocked_hosts:
|
|
43
|
+
- localhost
|
|
44
|
+
- 127.0.0.1
|
|
45
|
+
- '::1'
|
|
46
|
+
- '*.local'
|
|
47
|
+
- '10.*'
|
|
48
|
+
- '172.16.*'
|
|
49
|
+
- '192.168.*'
|
|
50
|
+
- '169.254.*'
|
|
51
|
+
allowed_local: []
|
|
52
|
+
|
|
53
|
+
audit:
|
|
54
|
+
db_path: /data/airlock-audit.db
|
|
55
|
+
retention_days: 90
|
|
56
|
+
redact_fields:
|
|
57
|
+
- password
|
|
58
|
+
- token
|
|
59
|
+
- secret
|
|
60
|
+
- key
|
|
61
|
+
- authorization
|
package/examples/gateway.yaml
CHANGED
|
@@ -6,6 +6,13 @@ server:
|
|
|
6
6
|
port: 4111
|
|
7
7
|
host: 127.0.0.1
|
|
8
8
|
# api_secret: ${AIRLOCK_API_SECRET}
|
|
9
|
+
# auth_required: true
|
|
10
|
+
# require_agent_tokens: true
|
|
11
|
+
# allowed_origins:
|
|
12
|
+
# - https://airlock.example.com
|
|
13
|
+
# expose_management_api: false
|
|
14
|
+
# expose_tools_api: false
|
|
15
|
+
# expose_hook_api: false
|
|
9
16
|
|
|
10
17
|
# Tool providers — MCP servers and builtins
|
|
11
18
|
providers:
|
package/examples/profiles.yaml
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# yaml-language-server: $schema=../schema.json
|
|
2
2
|
# Composable profiles — define reusable permission sets, then mix them into agents.
|
|
3
3
|
#
|
|
4
|
-
# Profiles are union-merged:
|
|
5
|
-
# gets all allow/ask patterns from both profiles,
|
|
4
|
+
# Profiles are union-merged recursively: a profile or agent that extends
|
|
5
|
+
# [readonly, github-write] gets all allow/ask/deny patterns from both profiles,
|
|
6
|
+
# plus its own.
|
|
6
7
|
# Precedence still applies: deny > ask > allow > default-deny.
|
|
7
8
|
#
|
|
8
9
|
# Run: npx tsx src/index.ts --agent helena --config examples/profiles.yaml
|
|
@@ -35,6 +36,7 @@ profiles:
|
|
|
35
36
|
ask: []
|
|
36
37
|
|
|
37
38
|
github-write:
|
|
39
|
+
extends: [readonly]
|
|
38
40
|
allow:
|
|
39
41
|
- 'github/create_issue'
|
|
40
42
|
- 'github/create_pr'
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -152,6 +152,13 @@
|
|
|
152
152
|
"additionalProperties": {
|
|
153
153
|
"type": "object",
|
|
154
154
|
"properties": {
|
|
155
|
+
"extends": {
|
|
156
|
+
"type": "array",
|
|
157
|
+
"items": {
|
|
158
|
+
"type": "string"
|
|
159
|
+
},
|
|
160
|
+
"default": []
|
|
161
|
+
},
|
|
155
162
|
"allow": {
|
|
156
163
|
"type": "array",
|
|
157
164
|
"items": {
|
|
@@ -558,12 +565,49 @@
|
|
|
558
565
|
}
|
|
559
566
|
},
|
|
560
567
|
"additionalProperties": false
|
|
568
|
+
},
|
|
569
|
+
"args": {
|
|
570
|
+
"type": "object",
|
|
571
|
+
"additionalProperties": {
|
|
572
|
+
"type": "object",
|
|
573
|
+
"properties": {
|
|
574
|
+
"allow": {
|
|
575
|
+
"type": "array",
|
|
576
|
+
"items": {}
|
|
577
|
+
},
|
|
578
|
+
"equals": {},
|
|
579
|
+
"label": {
|
|
580
|
+
"type": "string"
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
"additionalProperties": false
|
|
584
|
+
}
|
|
561
585
|
}
|
|
562
586
|
},
|
|
563
587
|
"additionalProperties": false
|
|
564
588
|
},
|
|
565
589
|
"default": {}
|
|
566
590
|
},
|
|
591
|
+
"arg_policy": {
|
|
592
|
+
"type": "object",
|
|
593
|
+
"additionalProperties": {
|
|
594
|
+
"type": "object",
|
|
595
|
+
"additionalProperties": {
|
|
596
|
+
"type": "object",
|
|
597
|
+
"properties": {
|
|
598
|
+
"allow": {
|
|
599
|
+
"type": "array",
|
|
600
|
+
"items": {}
|
|
601
|
+
},
|
|
602
|
+
"equals": {},
|
|
603
|
+
"label": {
|
|
604
|
+
"type": "string"
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
"additionalProperties": false
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
},
|
|
567
611
|
"exec": {
|
|
568
612
|
"type": "object",
|
|
569
613
|
"properties": {
|
|
@@ -1000,6 +1044,10 @@
|
|
|
1000
1044
|
"type": "string",
|
|
1001
1045
|
"const": "dashboard"
|
|
1002
1046
|
},
|
|
1047
|
+
"host": {
|
|
1048
|
+
"type": "string",
|
|
1049
|
+
"default": "127.0.0.1"
|
|
1050
|
+
},
|
|
1003
1051
|
"port": {
|
|
1004
1052
|
"type": "integer",
|
|
1005
1053
|
"minimum": 1,
|
|
@@ -1154,6 +1202,10 @@
|
|
|
1154
1202
|
"type": "string",
|
|
1155
1203
|
"const": "dashboard"
|
|
1156
1204
|
},
|
|
1205
|
+
"host": {
|
|
1206
|
+
"type": "string",
|
|
1207
|
+
"default": "127.0.0.1"
|
|
1208
|
+
},
|
|
1157
1209
|
"port": {
|
|
1158
1210
|
"type": "integer",
|
|
1159
1211
|
"minimum": 1,
|
|
@@ -1295,6 +1347,33 @@
|
|
|
1295
1347
|
},
|
|
1296
1348
|
"api_secret": {
|
|
1297
1349
|
"type": "string"
|
|
1350
|
+
},
|
|
1351
|
+
"auth_required": {
|
|
1352
|
+
"type": "boolean",
|
|
1353
|
+
"default": false
|
|
1354
|
+
},
|
|
1355
|
+
"require_agent_tokens": {
|
|
1356
|
+
"type": "boolean",
|
|
1357
|
+
"default": false
|
|
1358
|
+
},
|
|
1359
|
+
"allowed_origins": {
|
|
1360
|
+
"type": "array",
|
|
1361
|
+
"items": {
|
|
1362
|
+
"type": "string"
|
|
1363
|
+
},
|
|
1364
|
+
"default": []
|
|
1365
|
+
},
|
|
1366
|
+
"expose_management_api": {
|
|
1367
|
+
"type": "boolean",
|
|
1368
|
+
"default": true
|
|
1369
|
+
},
|
|
1370
|
+
"expose_tools_api": {
|
|
1371
|
+
"type": "boolean",
|
|
1372
|
+
"default": true
|
|
1373
|
+
},
|
|
1374
|
+
"expose_hook_api": {
|
|
1375
|
+
"type": "boolean",
|
|
1376
|
+
"default": true
|
|
1298
1377
|
}
|
|
1299
1378
|
},
|
|
1300
1379
|
"additionalProperties": false,
|