Representative interview topic

System Design Interview: How Do You Secure MCP Tool Invocation Boundaries?

System designHard
Offer.cc Editorial TeamPublished Updated

Question

You are building an enterprise agent that connects to multiple MCP servers. How would you design permission boundaries, human approval, result validation, and auditability for tool calls?

Prompt and applicable context

You own an enterprise agent platform. The agent can call ticketing, source-control, and finance systems through MCP. Some tools are read-only; others deploy code, issue refunds, or delete data. Servers can change over time, and tool descriptions or results may come from servers that are not fully trusted. Design discovery, authorization, invocation, result handling, auditing, and recovery. Explain which operations require human approval.

The core question is whether every call has a clear answer to four questions: who is acting for whom and within what scope, which tool version was used, whether inputs and results were validated, and whether a failure can be traced and reversed. Amazon’s SDE II guidance explicitly evaluates reliability, scalability, security, and trade-offs in system design, making this an appropriate end-to-end design exercise.

What the interviewer assesses

A strong answer separates the model’s ability to propose a call from the platform’s authority to execute it. The model may suggest a tool and arguments; a policy engine must authorize again using the user, tenant, resource, risk level, and approval state.

You should also recognize MCP’s boundary. Tool annotations supplied by a server must be treated as untrusted; a readOnlyHint is not an authorization fact. Results may contain structured data, text, resource links, or embedded resources. NSA guidance further highlights dynamic invocation, implicit trust, and context sharing as systemic risks.

The interviewer will probe failure paths: a poisoned catalog, a cross-tenant argument that passes schema validation, parameters changed after approval, timeouts, repeated side effects, and an unavailable audit pipeline.

Clarifying questions

First ask about side effects. Can queries, writes, deployments, and deletions be risk-ranked? If every tool is read-only, approval and recovery can be simpler; money movement, production changes, and personal data require stronger controls.

Then ask about trust boundaries. Are servers company-managed, third-party hosted, or user-supplied? If the platform does not control a server, its descriptions, annotations, result text, and resource URIs are input data, not policy.

Finally ask about compliance and recovery objectives. Which principals, tenants, and data classes must be recorded? Is reversal a compensating transaction, an inverse operation, or a manual procedure? Those answers change retention, credential scope, and workflow design.

30-second answer framework

You can say:

“I would treat the model as an untrusted proposer and put execution behind a policy engine and an isolated runner. The platform registers and versions each tool, applies least privilege by user, tenant, resource, and side effect, and binds high-risk actions such as deployments, refunds, and deletion to approval of the exact parameters. Read-only calls still validate inputs and results. Before and after execution, we write correlated audit events; results cannot become authorization for the next call. Idempotency, timeouts, circuit breakers, and rollback or manual recovery cover retries, server changes, approval mismatch, and partial failure.”

Step-by-step deep answer

Create an identity-aware tool catalog

Register the server identity, tool name, input and output JSON Schemas, code version, network scope, and actual side effects. A catalog change creates a version and review record; runtime calls only use approved versions. The MCP specification defines names, descriptions, and input schemas, and permits output schemas, but clients still need independent validation.

Bind authorization to one invocation

Policy input should include principal, tenant, resource, action, data class, environment, and tool version. The decision is allow, deny, or approval-required, and it produces a short-lived invocation token. Bind the token to a parameter digest so the model cannot change an amount, repository, or resource after approval.

Interpret annotations and descriptions as hints

readOnlyHint and destructiveHint can improve ranking, but they cannot authorize execution. If a server claims to be read-only, the policy still relies on reviewed registration and observed capabilities. Text such as “ignore previous instructions” is data, not a policy update.

Execute inside an isolated runner

Use short-lived credentials, restricted egress, and resource quotas. The runner receives only policy-checked structured arguments; it does not receive the full conversation or another tenant’s data. Tool text, links, and embedded resources first enter a result quarantine, then pass output-schema, size, content-type, and data-label checks.

Make approval explicit and parameter-bound

The approval view shows the principal, server, tool version, complete parameter summary, target resource, expected side effect, expiry, and revocation path. Store the approval with the parameter digest; any field change invalidates it. Low-risk reads may use post-hoc sampling, while high-risk actions require approval before execution.

Handle retries and partial completion

Writes carry an idempotency key derived from the business action and invocation intent, not only a random model value. Persist request, result, and retry state. On timeout, query execution status before retrying. If compensation is not safe, move the action to a human queue instead of blindly repeating a refund or deployment.

Emit correlated audit events

An event includes request ID, principal, tenant, server fingerprint, tool version, parameter digest, policy decision, approver, execution result, and downstream credential ID. Store sensitive arguments only as redacted digests or encrypted references. If audit storage is unavailable, high-risk calls should fail closed or enter a pending state rather than silently proceed.

Roll out and revoke incrementally

Validate the catalog, policies, and result checks against sandbox servers and shadow traffic before a small tenant or version rollout. Keep the old catalog version and a credential-revocation switch. If you detect privilege escalation, prompt injection, or result contamination, block new calls and revoke tokens first, then use audit events to handle completed side effects.

High-quality sample answer

“I would split the MCP integration into catalog, policy, approval, runner, and audit layers. The catalog records server fingerprints, tool versions, schemas, and real side effects. The model can propose a call, but the policy engine authorizes it by principal, tenant, resource, and environment. Approval is bound to a parameter digest, so changing an amount or target invalidates it. The runner uses short-lived credentials, restricted networking, and idempotency keys. Results are quarantined and checked for schema, size, content type, and data labels before they reach the agent. Every decision and downstream request is correlated in the audit log. Server changes, timeouts, duplicate effects, and audit failures have deny, circuit-breaker, and recovery paths, validated through sandbox and staged rollout.”

Common mistakes

Treating an annotation as permission

Failure pattern: automatically allowing a call because it carries readOnlyHint. Why it fails: the MCP specification says annotations from untrusted servers cannot be treated as security facts. Correction: use annotations as hints; derive permission from registration, policy, and runtime capability checks.

Validating only the generated arguments

Failure pattern: executing as soon as JSON Schema validation passes. Why it fails: well-typed arguments can still cross tenants, target production, or repeat an irreversible action. Correction: validate principal, resource ownership, risk, idempotency, and approval digest as well.

Showing only a natural-language approval

Failure pattern: asking the user to approve “handle the refund.” Why it fails: the approved object is ambiguous, so amount or account can change at execution time. Correction: display target, amount, version, parameter digest, expiry, and bind approval to that digest.

Treating tool output as trusted instructions

Failure pattern: concatenating returned text into the next system prompt. Why it fails: results can contain prompt injection, cross-tenant data, or malicious URIs. Correction: quarantine results, validate types, label data, and pass only the minimum needed fields.

Designing only the happy path

Failure pattern: retrying every timeout and moving on after every error. Why it fails: an unknown execution state can duplicate a write, while partial completion can violate a business invariant. Correction: design idempotency, status lookup, compensation, circuit breaking, and human escalation together.

Follow-up questions and responses

What if the tool catalog changes during a call?

Freeze the server fingerprint, tool version, and schemas used by that call. Catalog changes affect new calls only. If the version is revoked, the policy engine rejects the old token and requests fresh approval.

What if the approval service is unavailable?

Fail closed for high-risk actions, retaining the proposal in a pending queue. Low-risk reads may continue under a pre-approved policy, but they still emit audit events; an approval timeout is not authorization.

What if valid JSON contains another tenant’s data?

An output schema validates shape, not authorization scope. Pass tenant and resource scope downstream and check ownership, data labels, and result cardinality before releasing the result. Quarantine and alert on a violation.

How do you decide whether a tool may run automatically?

Score reversibility, blast radius, data sensitivity, duplicate cost, and detectability. Reversible, low-sensitivity, low-impact queries may run automatically; money movement, production changes, deletion, and cross-tenant reads need human approval or a dedicated workflow.

How do you investigate prompt injection?

Correlate the original input, tool-description version, model proposal, policy decision, approval view, tool result, and subsequent calls by request ID. Revoke the affected server and tokens first, then replay decisions from quarantined logs to identify completed side effects.

Public sources

Related questions

Related interview tool

Use Solve for a system design answer

Clarify the requirements first, then move through scale, architecture, component choices, and trade-offs.

View the tool