SERVICE ACCOUNT
DATA WAREHOUSE
Every dataset, table, and analytical pipeline your backend connects to lives in BigQuery. BigQuery (Service Account) MCP gives your agent server-to-server authenticated access using a GCP service account — no user OAuth required.
import { ScalekitClient } from "@scalekit-sdk/node";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { z } from "zod";
const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["bigqueryserviceaccount"], toolNames: ["bqsa_datasets_list", "bqsa_table_schema", "bqsa_query_run"] },
pageSize: 100,
});
const lcTools = tools.map((t) => new DynamicStructuredTool({
name: t.tool.definition.name,
description: t.tool.definition.description,
schema: z.object({}).passthrough(),
func: async (args) => {
const { data } = await sk.tools.executeTool({
toolName: t.tool.definition.name,
identifier: "user_123",
params: args,
});
return JSON.stringify(data);
},
}));
const agent = createReactAgent({ llm, tools: lcTools });import { ScalekitClient } from "@scalekit-sdk/node";
import OpenAI from "openai";
const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const openai = new OpenAI();
const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["bigqueryserviceaccount"], toolNames: ["bqsa_datasets_list", "bqsa_table_schema", "bqsa_query_run"] },
pageSize: 100,
});
const llmTools = tools.map((t) => ({
type: "function",
function: {
name: t.tool.definition.name,
description: t.tool.definition.description,
parameters: t.tool.definition.input_schema,
},
}));
const resp = await openai.responses.create({
model: "gpt-4o", input: prompt, tools: llmTools,
});import { ScalekitClient } from "@scalekit-sdk/node";
import Anthropic from "@anthropic-ai/sdk";
const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const anthropic = new Anthropic();
const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["bigqueryserviceaccount"], toolNames: ["bqsa_datasets_list", "bqsa_table_schema", "bqsa_query_run"] },
pageSize: 100,
});
const llmTools = tools.map((t) => ({
name: t.tool.definition.name,
description: t.tool.definition.description,
input_schema: t.tool.definition.input_schema,
}));
const msg = await anthropic.messages.create({
model: "claude-sonnet-4-6", max_tokens: 1024,
tools: llmTools,
messages: [{ role: "user", content: prompt }],
});import { Agent } from "@google/adk/agents";
import {
MCPToolset, StreamableHTTPConnectionParams,
} from "@google/adk/tools/mcp";
const toolset = new MCPToolset({
connectionParams: new StreamableHTTPConnectionParams({
url: "https://mcp.scalekit.com/bigqueryserviceaccount",
headers: { Authorization: `Bearer ${userScopedToken}` },
}),
});
const agent = new Agent({
name: "agent", model: "gemini-2.0-flash",
tools: await toolset.getTools(),
});// shared token
audit → bot_service_account
user_filter → broken
// scalekit
audit → user_abc
scope → enforced ✓Does the agent use a service account or a user credential?
A service account. Unlike OAuth connectors, no user authorization flow is required. A GCP service account key is configured once by an admin and vaulted in Scalekit. Every call runs under that service account identity.
Where is the BigQuery (Service Account) service account stored?
In Scalekit's managed AES-256 token vault. The JSON key file is never stored on disk or passed to the LLM. Rotation is a single vault update. The key never appears in prompts, logs, or agent context.
Can I limit what the agent is allowed to query in BigQuery?
Yes. Pass a tool name filter to listScopedTools so the analytics agent only sees the subset you authorize. Additionally, scope the service account IAM role to the minimum datasets required — Scalekit enforces both layers.
What happens if the service account key is rotated?
Update the key in the Scalekit vault. No code changes required. Subsequent calls resolve the new key automatically. The old key can be disabled in GCP immediately after the vault update. The event is logged for audit.
Does the agent respect BigQuery IAM, dataset ACLs, and row-level security?
Yes. All queries run under the service account IAM role. Dataset-level access, table ACLs, column-level security, and row-level security policies all apply. The agent cannot read or write what the service account is not granted.