History

Move product access rules out of the SDK

Rhys Sullivan committed 1 month ago

Commit c676e561 parent a72e51d161 files · +3935 −867Browse files

Showing the changes to apps/cloud/src (5 of 161 files). Show all

Unified · Split

5 files
  1. apps/cloud/src/admin/admin-users-api.ts +1 −1
  2. apps/cloud/src/auth/workos-auth-provider.ts +1 −1
  3. apps/cloud/src/mcp-session.e2e.node.test.ts +2 −0
  4. apps/cloud/src/mcp/session-durable-object.ts +2 −1
  5. apps/cloud/src/observability/oauth-callback-telemetry.test.ts +2 −1
apps/cloud/src/admin/admin-users-api.ts+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717 // acting member, and this plane deliberately serves the whole tenant.
1818 //
1919 // The executor is built by `makePlatformExecutor` — `{ tenant, subject:
20−// undefined, platformView: true }` — so the reads are tenant-wide and read-only
20+// undefined, access: platformObserverAccess() }` — so the reads are tenant-wide and read-only
2121 // by storage policy, and no `subject` row is minted for the caller.
2222 //
2323 // Cross-tenant isolation is structural, not a check in this file: the tenant is
apps/cloud/src/auth/workos-auth-provider.ts+1−1
@@ -174,7 +174,7 @@ const resolveJwtPrincipal = (token: string, jwt: JwtBearerConfig) => · 173 unmodified lines
174174 * `subject: null` + the read-only tenant reach rather than inventing a subject.
175175 *
176176 * The `/admin/*` mount turns this into an executor with `{ tenant:
177− * organizationId, subject: undefined, platformView: true }`.
177+ * organizationId, subject: undefined, access: platformObserverAccess() }`.
178178 */
179179 export interface PlatformAuth {
180180 readonly kind: "platform";
apps/cloud/src/mcp-session.e2e.node.test.ts+2−0
@@ -39,6 +39,7 @@ import { makeTestWorkOSVaultClient } from "@executor-js/plugin-workos-vault/test · 38 unmodified lines
3939 import executorConfig from "../executor.config";
4040 import { DbService } from "./db/db";
4141 import { createDrizzleFumaDb } from "./db/fuma";
42+import { testAccess } from "@executor-js/product-access/testing";
4243
4344 // ---------------------------------------------------------------------------
4445 // Test-only plugin: exposes one in-memory tool that elicits once. Lets the
@@ -124,6 +125,7 @@ const buildScopedExecutor = ( · 79 unmodified lines
124125 plugins,
125126 httpClientLayer: FetchHttpClient.layer,
126127 onElicitation: "accept-all",
128+ access: testAccess.member(),
127129 });
128130 });
129131
apps/cloud/src/mcp/session-durable-object.ts+2−1
@@ -26,6 +26,7 @@ import { · 25 unmodified lines
2626 } from "@executor-js/host-mcp/tool-server";
2727 import { buildResumeApprovalUrl } from "@executor-js/host-mcp/browser-approval";
2828 import { artifactUrlFor } from "@executor-js/host-mcp/create-artifact";
29+import { requestBoundMemberAccess } from "@executor-js/product-access";
2930 import { makeAssetsShellHtmlLoader } from "@executor-js/mcp-apps-shell/worker";
3031 import { smokeRenderArtifact } from "@executor-js/mcp-apps-shell/smoke-render";
3132 import {
@@ -349,7 +350,7 @@ export class McpSessionDOSqlite extends McpAgentSessionDOBase<Env, CloudSessionD · 317 unmodified lines
349350 sessionMeta.organizationName,
350351 {
351352 mcpResource: sessionMeta.resource,
352− orgWrites: "request",
353+ access: requestBoundMemberAccess(),
353354 },
354355 ).pipe(
355356 // The metered stack tracks each execution to Autumn. It requires
apps/cloud/src/observability/oauth-callback-telemetry.test.ts+2−1
@@ -32,6 +32,7 @@ import { createExecutor } from "@executor-js/sdk"; · 31 unmodified lines
3232 import { makeTestConfig } from "@executor-js/sdk/testing";
3333
3434 import { UrlRedactingSpanProcessor } from "./redact-span-urls";
35+import { testAccess } from "@executor-js/product-access/testing";
3536
3637 // Synthetic placeholders — never a real authorization code or CSRF state.
3738 const CODE = "synthetic-authorization-code-9f2c";
@@ -55,7 +56,7 @@ describe("oauth callback telemetry", () => { · 17 unmodified lines
5556 it.effect("exports no span attribute containing the authorization code or state", () =>
5657 Effect.gen(function* () {
5758 const { exporter, provider, tracerLayer } = makeTracing();
58− const executor = yield* createExecutor(makeTestConfig({}));
59+ const executor = yield* createExecutor(makeTestConfig({ access: testAccess.member() }));
5960
6061 const web = yield* Effect.acquireRelease(
6162 Effect.sync(() =>