feat(agent-bff): serve the static OpenAPI document behind the agent gate - #1810
Open
Tonours wants to merge 1 commit into
Open
feat(agent-bff): serve the static OpenAPI document behind the agent gate#1810Tonours wants to merge 1 commit into
Tonours wants to merge 1 commit into
Conversation
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
from
August 6, 2026 17:19
ba29239 to
dc83756
Compare
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
3 times, most recently
from
August 6, 2026 17:48
595c4b6 to
ece634c
Compare
4 tasks
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
from
August 6, 2026 20:48
ece634c to
b11c332
Compare
|
Coverage Impact This PR will not change total coverage. Modified Files with Diff Coverage (5)
馃 Increase coverage with AI coding...馃殾 See full report on Qlty Cloud 禄 馃洘 Help
|
Tonours
force-pushed
the
chore/dedupe-zod-single-v4-resolution
branch
from
August 7, 2026 07:39
3e81c4b to
04d3ba9
Compare
Tonours
force-pushed
the
feature/prd-886-openapi-static-document
branch
from
August 7, 2026 07:42
d51081e to
9652148
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #1809 (
chore/dedupe-zod-single-v4-resolution). The base is that branch, notmain: #1809 must be reviewed and merged first, and the diff below is only this branch's commit. #1809 is a hard prerequisite, not a convenience:@asteasolutions/zod-to-openapitakes zod as a peer dependency, so without the dedupe yarn can bind it to a different zod copy than the one agent-bff builds its schemas from.Serves
GET /agent/openapi.json: an OpenAPI 3.1 document describing the six generic BFF routes, generated from Zod, built once at boot.fixes PRD-886
The mount point is the auth gate
The route sits at
/agent/openapi.json, inside theagentScopedchain, right after the auth middlewares. That is deliberate. The BFF has no deny-by-default gate: auth applies only to paths under/agent, and/healthis the one hardcoded public exact-match ahead of the chain. Mounting at the root would have made the document public and required a bespoke gate; mounting under/agentinherits the existing one, so an unauthenticated request gets a 401 before path matching even happens.Placed before the timezone middleware and before
buildAgentRouteMiddlewares, so it still answers whenAGENT_URLis unset and the data routes fall back to the stub. It never calls the agent.Written against the code, not the spec
The PRD-648 spike is dead (its base predates the whole package), so this is from scratch on
main. Its patterns survive:extendZodWithOpenApiload-once, registry plusOpenApiGeneratorV31, aserializeOpenApishared with the future CLI. Its content did not: six of its claims were wrong against today's code:/agent/v1, not/v1data-routes-middleware.ts:41capabilities-validator.ts:19-38operator-normalizer.ts:10-28sort[].directionagent-query.ts:126page.offsetlimitagent-query.ts:135parentIdagent-query.ts:176-188recordIdsaction-routes-middleware.ts:42The document declares every status each route can actually return, including the ones a proxy hits most: 502 on transport failure, 413 on the 16kb body cap, 429 on agent rate-limiting. 501 is declared only on execute, the one route that produces it, and points at a separate schema because that body carries no
messagefield.Scope and safety
Additive. No existing route, handler, or schema changed. The only edit outside
src/openapi/is one line in thecli-core.tsmiddleware chain.The document is static: it describes generic routes with path placeholders and holds no tenant data. The only environment-derived value is the package version, served to authenticated callers only. Per-collection unfolding, which does expose real names, is PRD-684.
How to test
yarn workspace @forestadmin/agent-bff test yarn workspace @forestadmin/agent-bff lintAgainst a running agent:
Ran on this branch: 767 tests pass (726 before, 41 added), lint and build clean.
redocly lintnow runs inside the suite rather than by hand, so the document cannot go invalid unnoticed.An end-to-end pass against the live playground agent on :3009 covered the gate (401 with no credentials, no leak in the body,
unauthorizedtype), the root path (404), the authenticated fetch (200), redocly validation of the document as served over HTTP, ten contract assertions, and the documented error envelope. 9 checks, all passing. Eight path variants (trailing slash, case change,%6f, dot segments,.., doubled slash) were probed unauthenticated: none serves the document.Known limitations
Action
200responses are typedunknown.mapActionExecuteResulthas a concrete shape and describing it belongs with the action work, not here.Relation list and count skip capabilities validation entirely, so on those two routes the 422 field errors are unreachable and the filter depth cap is not enforced. The
ConditionTreedescription says so rather than pretending otherwise. #1801 is the branch fixing that.The document is a static description of generic routes. A consumer cannot yet generate a client that knows real collection names or per-field operators. That is PRD-684 and PRD-685.
Definition of Done
General
Security