Skip to content

feat(api): add provider terms to the Exchange preview proxy - #4608

Open
developersdigest wants to merge 1 commit into
mainfrom
codex/provider-terms-proxy
Open

feat(api): add provider terms to the Exchange preview proxy#4608
developersdigest wants to merge 1 commit into
mainfrom
codex/provider-terms-proxy

Conversation

@developersdigest

@developersdigest developersdigest commented Sep 11, 2026

Copy link
Copy Markdown
Member

The existing Exchange retrieval proxy forwards requests without checking whether the caller's organization accepted the provider's agreement. This adds an interim consent gate that can ship independently of #4582.

  • Expose authenticated, non-billable GET /exchange/provider-terms for the dashboard, without requiring the retrieval preview flag.
  • Before forwarding /exchange/retrieve, validate the single request or batch, load authoritative provider requirements from Exchange, and check the authenticated team's organization against the primary organization_data_source_access table. Missing/stale required acceptance and disabled/suspended access reject the entire batch before execution. Discovery remains independent of consent.
  • Derive upstream identity/catalog-access headers from authentication, mark proxy responses non-cacheable, and keep the requirement lookup and execution within the existing request deadline.

Billing behavior is unchanged. This PR adds no v1/v2 scrape, crawl, batch-scrape, SDK, or database-schema changes. Acceptance writes remain in the signed-in dashboard; no API-key acceptance endpoint is introduced.

Preview rollout dependencies

Keep this draft until the companion Exchange endpoints (GET /v1/provider-terms and POST /v1/provider-terms/requirements) and dashboard acceptance flow are available. Those changes are currently local and not included in this PR. Deploy Exchange first: if the requirements endpoint is absent or unavailable, retrieval fails closed, including for providers without agreements. The dashboard must be available before enabling required agreements.

Provider agreements must contain approved real documents; local preview fixtures are not production agreements. PlanetScale agreement persistence is not part of this PR. This only enforces the existing /exchange/retrieve proxy; the billing PR must carry the same check into its shared execution path before adding other execution routes.

Validation

  • 33 focused tests pass: request/batch validation, exact version/digest acceptance, disablement/suspension, missing or malformed requirements, database failures, authenticated route behavior, identity spoofing, and discovery independence.
  • TypeScript tsc --noEmit, Prettier, Knip, and lint-staged pass.
  • Route tests exercise Express with mocked authentication, Exchange transport, and database. Live cross-service/real-database validation remains pending the companion deployments.

Summary by cubic

Gates Exchange retrieval on the caller's organization having accepted the provider's agreement, and exposes a non-billable provider-terms endpoint for the dashboard. Previously, /exchange/retrieve forwarded requests without checking consent; now a missing or stale acceptance, or disabled/suspended access, rejects the entire request or batch before execution.

  • New authenticated GET /exchange/provider-terms works without the retrieval preview flag.
  • Before forwarding /exchange/retrieve, loads authoritative requirement metadata from Exchange and checks the authenticated team's organization in organization_data_source_access; discovery remains independent of consent.
  • Proxy responses are now non-cacheable, and upstream identity/catalog-access headers come from authentication.
  • Billing behavior is unchanged; this PR adds no v1/v2 scrape, crawl, batch-scrape, SDK, or database-schema changes.

Rollout dependencies

  • Keep this draft until the companion Exchange endpoints (GET /v1/provider-terms and POST /v1/provider-terms/requirements) and dashboard acceptance flow are available; those changes are currently local and not included here.
  • Deploy Exchange first — if the requirements endpoint is absent or unavailable, retrieval fails closed, including for providers without agreements.
  • The dashboard must be available before enabling required agreements.
  • Provider agreements must contain approved real documents; local preview fixtures are not production agreements.
  • This only enforces the existing /exchange/retrieve proxy; the billing PR must carry the same check into its shared execution path before adding other execution routes.

Validation

  • 33 focused tests pass: request/batch validation, exact version/digest acceptance, disablement/suspension, missing or malformed requirements, database failures, authenticated route behavior, identity spoofing, and discovery independence.
  • TypeScript tsc --noEmit, Prettier, Knip, and lint-staged pass.
  • Live cross-service/real-database validation remains pending the companion deployments.

Written for commit e670997. Summary will update on new commits.

Review in cubic

@developersdigest
developersdigest marked this pull request as ready for review September 11, 2026 00:46

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 4 files

Confidence score: 3/5

  • In apps/api/src/lib/exchange-provider-access.ts, a stalled primary database query can leave /exchange/retrieve waiting past its 50-second deadline because the authorization lookup ignores the proxy abort signal; propagate the deadline into this query to ensure timely cancellation.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/api/src/lib/exchange-provider-access.ts">

<violation number="1" location="apps/api/src/lib/exchange-provider-access.ts:84">
P2: When the primary database query stalls, `/exchange/retrieve` can wait beyond its 50-second deadline because the authorization query is not tied to the proxy's abort signal. Propagate the deadline into this lookup and use a cancellable or bounded database query before allowing the request to continue.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

);
try {
// Read the primary database so disabling access does not wait for an auth-cache refresh.
const result = await db.execute(sql`

@cubic-dev-ai cubic-dev-ai Bot Sep 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: When the primary database query stalls, /exchange/retrieve can wait beyond its 50-second deadline because the authorization query is not tied to the proxy's abort signal. Propagate the deadline into this lookup and use a cancellable or bounded database query before allowing the request to continue.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/api/src/lib/exchange-provider-access.ts, line 84:

<comment>When the primary database query stalls, `/exchange/retrieve` can wait beyond its 50-second deadline because the authorization query is not tied to the proxy's abort signal. Propagate the deadline into this lookup and use a cancellable or bounded database query before allowing the request to continue.</comment>

<file context>
@@ -0,0 +1,132 @@
+    );
+  try {
+    // Read the primary database so disabling access does not wait for an auth-cache refresh.
+    const result = await db.execute(sql`
+      SELECT t.org_id, a.data_source_id, a.status, a.terms_key, a.terms_version,
+             a.terms_accepted_at, a.settings
</file context>
Fix with cubic

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.

1 participant