@voyant-travel/hono 0.126.3 → 0.127.1

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.
@@ -21,6 +21,7 @@ export interface RequireActorOptions {
21
21
  resources?: readonly {
22
22
  path: string;
23
23
  resource: string;
24
+ authorization?: "coarse" | "route";
24
25
  }[];
25
26
  accessCatalog?: AccessCatalog;
26
27
  }
@@ -79,11 +79,14 @@ export function isStaffRbacEnforced(env) {
79
79
  function isRequireActorOptions(value) {
80
80
  return typeof value === "object" && value !== null && !Array.isArray(value);
81
81
  }
82
- function apiKeyResourceForRequest(pathname, options) {
82
+ function authorizationForRequest(pathname, options) {
83
83
  const override = [...(options.resources ?? [])]
84
84
  .sort((left, right) => right.path.length - left.path.length)
85
85
  .find(({ path }) => pathname === path || pathname.startsWith(`${path}/`));
86
- return override?.resource ?? apiKeyResourceFromPath(pathname);
86
+ return {
87
+ resource: override?.resource ?? apiKeyResourceFromPath(pathname),
88
+ authorization: override?.authorization ?? "coarse",
89
+ };
87
90
  }
88
91
  export function requireActor(...args) {
89
92
  const options = isRequireActorOptions(args[0]) ? args[0] : {};
@@ -99,14 +102,14 @@ export function requireActor(...args) {
99
102
  const pathname = normalizePathname(new URL(c.req.url).pathname, {
100
103
  basePath: options.basePath,
101
104
  });
102
- const resource = apiKeyResourceForRequest(pathname, options);
105
+ const { resource, authorization } = authorizationForRequest(pathname, options);
103
106
  // Coarse-guard-exempt surfaces. `_meta` (capability discovery) and `mcp`
104
107
  // (the agent tool server) are dispatch surfaces where authorization is
105
108
  // enforced at a finer grain than method+path: the MCP server filters and
106
109
  // gates each tool by its own `requiredScopes` (voyant#2792, D2). So any
107
110
  // authenticated key reaches them; a key with no relevant scopes simply
108
111
  // sees an empty tool list. Neither is a real module name.
109
- if (isCoarseGuardExempt(resource))
112
+ if (authorization === "route" || isCoarseGuardExempt(resource))
110
113
  return next();
111
114
  const actions = apiKeyPermissionActionsForMethod(c.req.method, pathname);
112
115
  if (resource &&
@@ -137,8 +140,8 @@ export function requireActor(...args) {
137
140
  const pathname = normalizePathname(new URL(c.req.url).pathname, {
138
141
  basePath: options.basePath,
139
142
  });
140
- const resource = apiKeyResourceForRequest(pathname, options);
141
- if (resource && !isCoarseGuardExempt(resource)) {
143
+ const { resource, authorization } = authorizationForRequest(pathname, options);
144
+ if (resource && authorization !== "route" && !isCoarseGuardExempt(resource)) {
142
145
  const actions = apiKeyPermissionActionsForMethod(c.req.method, pathname);
143
146
  if (!hasAnyApiKeyPermission(scopes, resource, actions, options.accessCatalog)) {
144
147
  return c.json({ error: "Forbidden: missing required permission" }, 403);
package/dist/types.d.ts CHANGED
@@ -218,6 +218,7 @@ export interface VoyantAppConfig<TBindings extends VoyantBindings = VoyantBindin
218
218
  accessResources?: readonly {
219
219
  path: string;
220
220
  resource: string;
221
+ authorization?: "coarse" | "route";
221
222
  }[];
222
223
  /** Effective selected-plus-legacy catalog used for wildcard policy. */
223
224
  accessCatalog?: AccessCatalog;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyant-travel/hono",
3
- "version": "0.126.3",
3
+ "version": "0.127.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -130,18 +130,18 @@
130
130
  "drizzle-orm": "^0.45.2",
131
131
  "hono": "^4.12.27",
132
132
  "zod": "^4.4.3",
133
- "@voyant-travel/core": "^0.122.1",
134
- "@voyant-travel/db": "^0.114.4",
135
- "@voyant-travel/types": "^0.109.1",
133
+ "@voyant-travel/core": "^0.124.0",
134
+ "@voyant-travel/db": "^0.114.7",
135
+ "@voyant-travel/types": "^0.109.2",
136
136
  "@voyant-travel/utils": "^0.107.1",
137
- "@voyant-travel/workflows": "^0.120.2"
137
+ "@voyant-travel/workflows": "^0.121.0"
138
138
  },
139
139
  "devDependencies": {
140
140
  "@cloudflare/workers-types": "^4.20260702.1",
141
141
  "typescript": "^6.0.3",
142
142
  "vitest": "^4.1.9",
143
143
  "@voyant-travel/voyant-typescript-config": "^0.1.0",
144
- "@voyant-travel/workflows-orchestrator": "^0.120.2"
144
+ "@voyant-travel/workflows-orchestrator": "^0.121.0"
145
145
  },
146
146
  "files": [
147
147
  "dist"