Skip to content

fix(server): fail closed on public agent routes in ungranted shared runtimes - #4325

Merged
kwakayama merged 3 commits into
mainfrom
issue/854-exec-discovery-shared-host
Aug 30, 2026
Merged

fix(server): fail closed on public agent routes in ungranted shared runtimes#4325
kwakayama merged 3 commits into
mainfrom
issue/854-exec-discovery-shared-host

Conversation

@kwakayama

Copy link
Copy Markdown
Contributor

In a shared multi-project runtime without a host execution grant, GET /api/agents and GET /api/agents/:id called ensureProjectDiscovery(ctx) with no locality guard, so the VeryfrontError thrown by src/server/handlers/request/api/project-discovery.ts:151 ("Remote executable discovery requires an isolated project runtime and cannot run in the shared host", INITIALIZATION_ERROR, 500) escaped the handler and surfaced in Sentry as an unhandled 500. Both PublicAgentsListHandler and PublicAgentMetadataHandler now check requiresIsolatedProjectRuntime(ctx) before discovery and return a structured RFC 9457 problem response (503, application/problem+json, type https://veryfront.com/docs/code/guides/errors#project-execution-unavailable) built through the response builder with CORS/security headers and no-store caching, exactly mirroring the sibling surfaces (ssr.handler, snippet.handler, app-router-handler). Shared runtimes the host granted execution (allowHostProjectCodeExecution: true) and explicit local projects still reach discovery and are served as before.

Fixes veryfront/veryfront-issue-inbox#854

Red

deno task test:file src/server/handlers/request/public-agents-list.handler.test.ts src/server/handlers/request/public-agent-metadata.handler.test.ts

Before the fix:

shared runtime without a host execution grant ...
  fails closed with project-execution-unavailable instead of leaking the discovery error ... FAILED (1ms)
  serves a shared runtime the host granted execution ... ok

ERRORS
server/handlers/request/public-agents-list.handler ... fails closed with project-execution-unavailable instead of leaking the discovery error
error: VeryfrontError: Remote executable discovery requires an isolated project runtime and cannot run in the shared host
    at Object.create (src/errors/types.ts:111:14)
    at Object.ensureProjectDiscovery (src/server/handlers/request/api/project-discovery.ts:151:32)
    at src/server/handlers/request/public-agents-list.handler.ts:44:23
    at PublicAgentsListHandler.withProxyContext (src/security/http/base-handler.ts:211:24)
    at PublicAgentsListHandler.handle (src/server/handlers/request/public-agents-list.handler.ts:39:17)

server/handlers/request/public-agent-metadata.handler ... fails closed with project-execution-unavailable instead of leaking the discovery error
error: VeryfrontError: Remote executable discovery requires an isolated project runtime and cannot run in the shared host
    at Object.create (src/errors/types.ts:111:14)
    at Object.ensureProjectDiscovery (src/server/handlers/request/api/project-discovery.ts:151:32)
    at src/server/handlers/request/public-agent-metadata.handler.ts:53:23

FAILED | 0 passed (10 steps) | 2 failed (4 steps) (202ms)

Green

After the fix, same command:

server/handlers/request/public-agents-list.handler ...
  returns every browser-safe agent, sorted by name ... ok
  skips ids that no longer resolve to an agent ... ok
  returns an empty list when the project exposes no agents ... ok
  ignores non-GET requests ... ok
  shared runtime without a host execution grant ...
    fails closed with project-execution-unavailable instead of leaking the discovery error ... ok
    serves a shared runtime the host granted execution ... ok
server/handlers/request/public-agent-metadata.handler ...
  returns browser-safe source-defined agent metadata ... ok
  returns 404 when the source-defined agent does not exist ... ok
  returns 400 when the agent id cannot be decoded ... ok
  ignores non-GET requests ... ok
  shared runtime without a host execution grant ...
    fails closed with project-execution-unavailable instead of leaking the discovery error ... ok
    serves a shared runtime the host granted execution ... ok

ok | 2 passed (14 steps) | 0 failed (232ms)

Affected suite: deno task test:file src/server/handlers/request/ -> ok | 69 passed (612 steps) | 0 failed (10s). deno check, deno fmt --check, and deno lint are clean on both changed handlers.

Revert check

Recorded HEAD 18bc7f4. git revert --no-commit 18bc7f453 (only the two handler .ts files reverted; tests kept), then the red test command:

REVERTED -> FAILED | 0 passed (10 steps) | 2 failed (4 steps)

Both "fails closed with project-execution-unavailable instead of leaking the discovery error" steps fail with VeryfrontError: Remote executable discovery requires an isolated project runtime and cannot run in the shared host at src/server/handlers/request/api/project-discovery.ts:151, escaping via withProxyContext (base-handler.ts:211), which is the exact Sentry leak. git reset --hard 18bc7f453 -> ok | 2 passed (14 steps) | 0 failed. Broader sweep at restored HEAD: deno task test:file src/server/handlers/request/ -> ok | 69 passed (612 steps) | 0 failed.

Acceptance criteria

  • GET /api/agents and GET /api/agents/:id in a shared multi-project runtime without a host execution grant return a structured RFC 9457 problem response instead of letting the raw VeryfrontError escape the handler
  • The denial response is 503 with content-type application/problem+json and problem type https://veryfront.com/docs/code/guides/errors#project-execution-unavailable, matching the convention of sibling surfaces (ssr.handler, snippet.handler, app-router-handler, api-handler-wrapper)
  • A shared runtime whose host granted execution (allowHostProjectCodeExecution: true, or explicit local project) is still served: the guard is requiresIsolatedProjectRuntime(ctx), not a blanket denial, and the granted-counterpart tests assert 200 plus that discovery ran
  • Existing handler behavior (200 list/metadata, 404 unknown agent, 400 bad id, non-GET passthrough) is preserved by the pre-existing tests in the same files

Kentaro Wakayama added 2 commits August 30, 2026 22:03
…untimes (issue-inbox#854)

GET /api/agents and GET /api/agents/:id called ensureProjectDiscovery
without a locality guard, so in a shared multi-project runtime without a
host execution grant the INITIALIZATION_ERROR thrown by the discovery
guard escaped the handler as a raw 500. Guard both handlers with
requiresIsolatedProjectRuntime and answer with the structured
project-execution-unavailable 503 problem response, matching the SSR,
snippet, and app-router surfaces. Granted shared runtimes still reach
discovery and are served.
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 4 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e99dc90-4e06-4d6f-aba2-965eaec37773

📥 Commits

Reviewing files that changed from the base of the PR and between eaaf178 and 92e3177.

📒 Files selected for processing (9)
  • src/server/handlers/execution-surface-policy.test.ts
  • src/server/handlers/request/public-agent-metadata.handler.test.ts
  • src/server/handlers/request/public-agent-metadata.handler.ts
  • src/server/handlers/request/public-agents-list.handler.test.ts
  • src/server/handlers/request/public-agents-list.handler.ts
  • src/server/handlers/request/snippet.handler.ts
  • src/server/handlers/utils/index.ts
  • src/server/handlers/utils/project-execution-unavailable.test.ts
  • src/server/handlers/utils/project-execution-unavailable.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

📦 Client bundle boundary

Entrypoint Modules Source size Server leaks
src/index.client.ts 288 2232 KiB ✅ 0

A server module in a client graph aborts hydration in the browser. New leaks fail CI; known leaks are tracked in scripts/lint/client-bundle-baseline.json to burn down.

Comment thread src/server/handlers/request/public-agents-list.handler.ts Outdated
@kwakayama
kwakayama marked this pull request as ready for review August 30, 2026 21:33

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kwakayama has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review 🔄 Running since 2026-08-30T21:57:34.278130Z 92e3177 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18bc7f453d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/server/handlers/request/public-agent-metadata.handler.ts
Comment thread src/server/handlers/request/public-agent-metadata.handler.ts
…e the runtime gate (issue-inbox#854)

Three review follow-ups on the public agent discovery routes.

- Add public-agent-metadata.handler.ts and public-agents-list.handler.ts
  to CAPABILITY_GATED_SURFACES. Both call requiresIsolatedProjectRuntime()
  and both already have paired fail-closed and granted-path tests, so the
  execution-surface inventory test was the only thing missing.

- Validate the agent id before the runtime gate in the metadata handler.
  A malformed id such as GET /api/agents/% needs neither discovery nor
  project-code execution, so it keeps the 400 "Invalid agent id" contract
  on an ungranted shared runtime instead of becoming a retryable 503.
  Covered by a new test in the shared-runtime describe block.

- Extract buildProjectExecutionUnavailableResponse() into
  server/handlers/utils and use it from both public agent handlers and
  from snippet.handler.ts, whose block was behaviourally identical
  (CORS + security + no-store, body on every method). The ssr, markdown
  preview, app-router, api-handler-wrapper and module copies differ
  (no CORS, nonce, HEAD null body, executionTopology metadata) and are
  left as they are. The helper does not call the predicate itself so the
  inventory test keeps seeing each surface's own gate.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kwakayama has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@github-actions

Copy link
Copy Markdown

@codex review

@gitar-bot

gitar-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because your trial's included automatic processing has been used for this period. Upgrade now, or comment "Gitar review" to run a review anytime.
Learn more

Code Review ✅ Approved 1 resolved / 1 findings

Adds fail-closed validation to public agent routes in ungranted shared runtimes, preventing a raw VeryfrontError from escaping the handler. GET /api/agents and GET /api/agents/:id now return a structured RFC 9457 problem response (503, application/problem+json) before discovery when the runtime lacks execution grants, matching the pattern used by sibling surfaces. Shared runtimes with granted host execution and explicit local projects continue to be served. Duplicated denial logic was extracted into a reusable utility function; all existing handler behavior and acceptance criteria are met.

✅ 1 resolved
Quality: Duplicated shared-runtime denial block across handlers

📄 src/server/handlers/request/public-agents-list.handler.ts:44-58 📄 src/server/handlers/request/public-agent-metadata.handler.ts:47-61
The identical ~16-line project-execution-unavailable denial block (problem creation + response builder with CORS/security/no-store/headers) is now copy-pasted into both public agent handlers, and the PR summary notes the same block already exists in ssr/snippet/app-router surfaces. While the underlying predicate is shared, the response-building logic is not, so status/type/header conventions can silently drift between surfaces. Consider extracting a small helper (e.g. buildProjectExecutionUnavailableResponse(this, req, ctx)) so all surfaces stay in lockstep. Minor and partly pre-existing.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 92e317726b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.29630% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../handlers/request/public-agent-metadata.handler.ts 94.73% 0 Missing and 1 partial ⚠️
...er/handlers/utils/project-execution-unavailable.ts 95.23% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@sonarqubecloud

Copy link
Copy Markdown

@kwakayama
kwakayama added this pull request to the merge queue Aug 30, 2026
Merged via the queue into main with commit a75d7fd Aug 30, 2026
65 checks passed
@kwakayama
kwakayama deleted the issue/854-exec-discovery-shared-host branch August 30, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants