@vellumai/vellum-gateway 0.5.12 → 0.5.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/vellum-gateway",
3
- "version": "0.5.12",
3
+ "version": "0.5.13",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -47,7 +47,7 @@
47
47
  "key": "app-builder-multifile",
48
48
  "label": "App Builder Multi-file",
49
49
  "description": "Enable multi-file TSX app creation with esbuild compilation instead of single-HTML apps",
50
- "defaultEnabled": false
50
+ "defaultEnabled": true
51
51
  },
52
52
  {
53
53
  "id": "mobile-pairing",
@@ -4,8 +4,11 @@ import { validateEdgeToken } from "../../auth/token-exchange.js";
4
4
  import { resolveScopeProfile } from "../../auth/scopes.js";
5
5
  import type { Scope } from "../../auth/types.js";
6
6
  import type { AuthRateLimiter } from "../../auth-rate-limiter.js";
7
+ import { getLogger } from "../../logger.js";
7
8
  import { isLoopbackPeer } from "../routes/browser-relay-websocket.js";
8
9
 
10
+ const log = getLogger("auth");
11
+
9
12
  type GetClientIp = () => string;
10
13
 
11
14
  /**
@@ -34,11 +37,19 @@ export function createAuthMiddleware(
34
37
  const token = extractBearerToken(req);
35
38
  if (!token) {
36
39
  authRateLimiter.recordFailure(getClientIp());
40
+ log.warn(
41
+ { path: new URL(req.url).pathname },
42
+ "Edge auth rejected: missing or malformed Authorization header",
43
+ );
37
44
  return Response.json({ error: "Unauthorized" }, { status: 401 });
38
45
  }
39
46
  const result = validateEdgeToken(token);
40
47
  if (!result.ok) {
41
48
  authRateLimiter.recordFailure(getClientIp());
49
+ log.warn(
50
+ { path: new URL(req.url).pathname, reason: result.reason },
51
+ "Edge auth rejected: token validation failed",
52
+ );
42
53
  return Response.json({ error: "Unauthorized" }, { status: 401 });
43
54
  }
44
55
  return null;
@@ -60,11 +71,19 @@ export function createAuthMiddleware(
60
71
  const token = extractBearerToken(req);
61
72
  if (!token) {
62
73
  authRateLimiter.recordFailure(getClientIp());
74
+ log.warn(
75
+ { path: new URL(req.url).pathname, scope },
76
+ "Scoped edge auth rejected: missing or malformed Authorization header",
77
+ );
63
78
  return Response.json({ error: "Unauthorized" }, { status: 401 });
64
79
  }
65
80
  const result = validateEdgeToken(token);
66
81
  if (!result.ok) {
67
82
  authRateLimiter.recordFailure(getClientIp());
83
+ log.warn(
84
+ { path: new URL(req.url).pathname, scope, reason: result.reason },
85
+ "Scoped edge auth rejected: token validation failed",
86
+ );
68
87
  return Response.json({ error: "Unauthorized" }, { status: 401 });
69
88
  }
70
89
  const scopes = resolveScopeProfile(result.claims.scope_profile);
@@ -1,4 +1,7 @@
1
1
  import { verifyToken } from "../../auth/token-service.js";
2
+ import { getLogger } from "../../logger.js";
3
+
4
+ const log = getLogger("deliver-auth");
2
5
 
3
6
  /**
4
7
  * Creates a fail-closed auth check for delivery routes.
@@ -21,12 +24,20 @@ export function checkDeliverAuth(
21
24
 
22
25
  const authHeader = req.headers.get("authorization");
23
26
  if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) {
27
+ log.warn(
28
+ { path: new URL(req.url).pathname },
29
+ "Deliver auth rejected: missing or malformed Authorization header",
30
+ );
24
31
  return Response.json({ error: "Unauthorized" }, { status: 401 });
25
32
  }
26
33
 
27
34
  const token = authHeader.slice(7);
28
35
  const result = verifyToken(token, "vellum-daemon");
29
36
  if (!result.ok) {
37
+ log.warn(
38
+ { path: new URL(req.url).pathname, reason: result.reason },
39
+ "Deliver auth rejected: token validation failed",
40
+ );
30
41
  return Response.json({ error: "Unauthorized" }, { status: 401 });
31
42
  }
32
43
 
@@ -44,12 +44,19 @@ export function createRuntimeProxyHandler(config: GatewayConfig) {
44
44
  if (config.runtimeProxyRequireAuth && req.method !== "OPTIONS") {
45
45
  const authHeader = req.headers.get("authorization");
46
46
  if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) {
47
+ log.warn(
48
+ { method: req.method, path: url.pathname },
49
+ "Runtime proxy auth rejected: missing or malformed Authorization header",
50
+ );
47
51
  return Response.json({ error: "Unauthorized" }, { status: 401 });
48
52
  }
49
53
  const edgeJwt = authHeader.slice(7);
50
54
  const result = validateEdgeToken(edgeJwt);
51
55
  if (!result.ok) {
52
- log.debug({ reason: result.reason }, "Edge token validation failed");
56
+ log.warn(
57
+ { method: req.method, path: url.pathname, reason: result.reason },
58
+ "Runtime proxy auth rejected: edge token validation failed",
59
+ );
53
60
  return Response.json({ error: "Unauthorized" }, { status: 401 });
54
61
  }
55
62
  exchangeToken = mintExchangeToken(
package/src/index.ts CHANGED
@@ -629,12 +629,20 @@ async function main() {
629
629
  const authHeader = req.headers.get("authorization");
630
630
  if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) {
631
631
  authRateLimiter.recordFailure(getClientIp());
632
+ log.warn(
633
+ { path: new URL(req.url).pathname },
634
+ "Guardian refresh auth rejected: missing or malformed Authorization header",
635
+ );
632
636
  return Response.json({ error: "Unauthorized" }, { status: 401 });
633
637
  }
634
638
  const token = authHeader.slice(7);
635
639
  const result = validateEdgeToken(token, { allowExpired: true });
636
640
  if (!result.ok) {
637
641
  authRateLimiter.recordFailure(getClientIp());
642
+ log.warn(
643
+ { path: new URL(req.url).pathname, reason: result.reason },
644
+ "Guardian refresh auth rejected: token validation failed",
645
+ );
638
646
  return Response.json({ error: "Unauthorized" }, { status: 401 });
639
647
  }
640
648
  return channelVerificationSessionProxy.handleGuardianRefresh(req);