If you’re building a product that serves multiple customers, you need their
cached snippets to be completely isolated. Customer A should never see
Customer B’s code.Raysurfer workspaces provide this isolation. Each workspace is a completely
separate cache — snippets uploaded to one workspace can never be retrieved
from another.
from raysurfer import RaysurferClientfrom claude_agent_sdk import ClaudeAgentOptionsoptions = ClaudeAgentOptions(allowed_tools=["Read", "Write", "Bash"])# Each customer gets their own isolated workspaceasync with RaysurferClient(options, workspace_id="acme") as client: await client.query("Process shipment data") async for msg in client.response(): print(msg)
import { RaysurferClient } from "raysurfer";// Each customer gets their own isolated workspaceconst client = new RaysurferClient({ allowedTools: ["Read", "Write", "Bash"], workspaceId: "acme",});for await (const msg of client.query("Process shipment data")) { console.log(msg);}
That’s it. All uploads and retrievals are now isolated to that customer.
from raysurfer import RaysurferClientfrom claude_agent_sdk import ClaudeAgentOptionsasync def handle_customer_request(customer_id: str, task: str): options = ClaudeAgentOptions(allowed_tools=["Read", "Write", "Bash"]) # Pass the customer ID as workspace_id async with RaysurferClient(options, workspace_id=customer_id) as client: await client.query(task) async for msg in client.response(): yield msg
import { RaysurferClient } from "raysurfer";async function* handleCustomerRequest(customerId: string, task: string) { // Pass the customer ID as workspaceId const client = new RaysurferClient({ allowedTools: ["Read", "Write", "Bash"], workspaceId: customerId, }); for await (const msg of client.query(task)) { yield msg; }}
A workspace is just a cache partition — it siloes which cached code snippets
are visible, nothing more. Raysurfer does not manage your underlying
permissions (database access, column-level security, API scopes, etc.). Your
application decides which workspace_id to assign each user based on whatever
permission model you already have.For example, if user A can query columns M and N, and user B can query columns
M, N, O, and P, give them different workspace IDs (e.g. "mn" and "mnop").
User A’s cached scripts will only ever reference their allowed columns, and
user B’s are completely separate. Raysurfer guarantees no cross-workspace
leakage — your app still enforces the actual data permissions.
Any string that uniquely maps to a permission boundary — a customer ID, a role
name, a hash of allowed scopes, or a permission profile key. It’s an arbitrary
string you choose.
When you provide a workspace_id, Raysurfer searches both the workspace
namespace and the org-wide namespace in parallel, merges results by score,
and returns the top results. This means workspace-specific snippets compete
on equal footing with company-wide snippets.