>

Governing AI usage across your engineering team: the problem and our approach

Governing AI usage across your engineering team: the problem and our approach

Last updated: June 2026

AI adoption has outpaced the controls that typically govern production system access. Developers connect Claude to databases, issue trackers, and code repositories without any approval process. Agents take actions in those same systems with whatever access the deploying engineer happens to have, and nobody has visibility into what's being called, what data is flowing where, or who is responsible when something goes wrong.

For example: one customer recently told me he discovered a developer had built a Claude Code skill that opened a Rails console in their production read replica. It was originally for debugging, but then it was shared with a few colleagues, then quietly adopted by non-technical staff who used it to run ad hoc queries. By the time the security team became aware of it, there was no log of what had been queried, no way to restrict access without disabling individual developer accounts, and no clear picture of what else might be running that they didn't know about.

That's the governance gap this guide is designed to close.

The MCP spec deliberately doesn't define how organizations should govern tool access, manage credentials across users, or log tool calls for audit purposes. Those are left as implementation concerns. This chapter covers what that gap looks like in practice, and why filling it requires more than what Claude Desktop and Claude Code offer out of the box.

Approaches to consider

There's no single right answer here, and most teams end up combining several of these. The tradeoffs are real.

Platform-native controls (Claude Desktop and Claude Code)

Both clients let you configure which MCP servers are available and restrict access at the server level. This is zero-friction to implement and covers the most common case. The ceiling is low: a user either has access to a server or they don't. There's no tool-level differentiation, no audit trail of what was called, no central credential management, and no way to distinguish a human user from an agent in your logs. For a single developer, this is often enough. For a team, it creates the governance problems this guide is designed to solve.

Endpoint protection and outbound filtering

Some teams use MDM-enforced network controls to restrict what AI tools can connect to, blocking connections to unapproved services at the device or network level. This is the most comprehensive approach in theory: nothing gets through that you haven't explicitly allowed. In practice, it's brittle and intrusive. It creates significant friction for legitimate development workflows, requires constant maintenance as the ecosystem of approved tools changes, and critically, doesn't cover agents running in cloud environments (CI pipelines, EC2 instances, containers) that aren't managed devices.

Data Loss Prevention (DLP)

DLP tools monitor and filter data flows, scanning what's being sent to AI systems and blocking or alerting on sensitive data patterns. This addresses the data exfiltration concern but has a different limitation: it's data-focused, not action-focused. It can tell you that someone sent something that looks like a social security number to an external endpoint, but it can't tell you which tool was called, with what arguments, or what the agent did afterward. It also adds latency and requires significant per-environment configuration. DLP is useful as a defense-in-depth layer; it's not a substitute for access control or audit logging.

Proxy-layer MCP gateway (our approach)

A gateway sits between your Claude clients and the upstream MCP servers, enforcing tool-level access controls, logging every tool call, and managing credentials centrally. Less intrusive than endpoint protection, more control than platform-native, and it covers both local developer tools and cloud-hosted agents. The tradeoff: it only controls what flows through the gateway. An engineer who configures a direct connection to an MCP server (bypassing the gateway) is outside its scope. MDM deployment helps close that gap; we'll cover this in Deploying MCP for your whole team.

We chose this approach because it gave us the right balance of control and usability, and because the audit trail it provides is what we actually needed: not just "was sensitive data sent somewhere" but "which user called which tool, with what arguments, at what time."

What platform-native controls actually cover

Since this guide focuses on the proxy-layer approach, it's worth being specific about where platform-native controls stop. Both Claude Desktop and Claude Code give you a binary: a user either has access to a server or they don't. There is no native mechanism for restricting which tools within a server a given role can call, differentiating access across team members, auditing which tools were called with what arguments, managing credentials centrally, or giving agents a distinct identity separate from the human whose session they're running in.

If five engineers on your team have Claude Desktop connected to Notion, GitHub, and Snowflake, there is no record of what those five engineers have called against those systems. There is no way to say engineer A can query Snowflake but not write to it. There is no way to know that an agent running in engineer B's session made 200 calls to the GitHub API yesterday.

What breaks at team scale

Individual MCP setup doesn't translate cleanly to team deployment, and the failure modes tend to emerge gradually rather than all at once.

Credential sprawl. Each engineer manages their own tokens for each server, some using shared service account credentials and others using personal tokens, with nobody tracking rotation schedules. When an engineer leaves, it's often unclear which shared credentials they had access to. When a credential leaks, attribution is unclear.

No audit trail. Tool calls are invisible to anyone other than the user who made them. There's no central record of what was called against your production database, your customer data in Notion, or any other system your team has connected through Claude. When a security review asks what your AI systems did with customer data last quarter, the answer requires reconstructing from scattered logs (if those logs exist at all).

No access differentiation. A junior engineer and a senior engineer with admin credentials have the same access to every tool every server exposes, as long as both have the server configured. The principle of least privilege (which your compliance program almost certainly requires) has no enforcement mechanism at the MCP layer.

No agent accountability. An agent running in an engineer's Claude Code session uses that engineer's credentials and identity. When that agent makes tool calls, the audit log (if one exists) shows the engineer's name, not the agent's. When something goes wrong, attribution is impossible.

The Day-Zero Normal CISO brief, one of the more practically useful security frameworks published in 2026, puts it in perspective: "Agents, service accounts, and workload identities outnumber human users by roughly 45-to-1. Most programs govern them like an afterthought." MCP only makes this worse.

One of our healthcare customers described this exact situation to us recently: they'd opened Claude Desktop access to about 30 people on their engineering and data teams. Within days the first questions arrived: can I connect it to Snowflake? Can I connect it to Slack? The security team quickly realized there was zero ability to control how data flowed between connectors in the default setup. Designers wanting access to Notion and Figma would also, unavoidably, have access to the PHI-containing Snowflake instance. Engineers working in PHI contexts would have the same tool set as those who weren't. Nobody could see who had configured what.

Their solution, for now, was the only option available: conservative access restrictions and user education. "If we can't enforce things," one of their security engineers told us, "then what can we see? So we can at least try to catch stuff." That's the fallback position for most teams today.

The real risk surface

The abstract threat taxonomy for MCP includes tool poisoning, prompt injection, and confused deputy attacks (covered in Prompt injection in MCP). These are real threats, but for most engineering teams the more immediate risks are operational rather than adversarial.

Over-permissioned access. A developer using Claude to analyze data in a read replica also has access to write tools on the same server. An agent built for a specific task has access to everything the user's account can reach. The blast radius of a prompt injection attack, a misbehaving agent, or a mistaken tool call is determined entirely by what the caller can reach.

Third-party server risk. As the Day-Zero Normal notes, "any MCP server with shell access or credential access is tier-0 supply chain." A server that updates its tool list, changes a tool's behavior, or introduces unexpected new capabilities affects every user and agent connecting through it. Without a central registry and audit log, there's no baseline against which to detect when a server's behavior changes.

Sensitive data in agentic workflows. An agent with access to a Snowflake MCP server may execute queries that retrieve sensitive records as part of a broader task, not because it was told to retrieve them, but because the data was reachable. Without tool-level access controls, the only safeguard is the agent's judgment… and that’s not a real safeguard.

No forensic trail. When something goes wrong (an agent runs a loop, a query returns unexpected data, an action is taken that shouldn't have been), the investigation depends on logs. If no tool call logs exist, there's nothing to investigate. In regulated environments, this gap isn't just operationally painful; it's a compliance failure.

What a proxy-layer gateway needs to provide

Four things need to exist for an MCP gateway to meaningfully close these gaps:

  1. Tool-level access control. Role-based grants that specify which tools each role can call on each server, enforced at the infrastructure layer rather than just filtered from the client's view. Covered in Tool-level access control.

  2. Audit logging. An immutable, queryable record of every tool call: user identity, tool name, server, arguments, timestamp, and IP address. Arguments encrypted at rest. Records that survive server deletion and renames. Covered in Audit logging for MCP tool calls.

  3. Credential management. Centralized management of both shared credentials (one account for the whole org) and personal credentials (each user authenticates individually), with OAuth support, token lifecycle management, and rotation. Covered in MCP authentication.

  4. Agent identity. A distinct identity for non-human principals with their own API keys, role-based grants, and appearance in the audit log separate from any human user. Covered in Agent identity and robot users.

How Aptible approached this internally

Aptible's team uses Claude Desktop and Claude Code connected to a growing set of internal tools: Notion, GitHub, Shortcut, Pylon, Sentry, Metabase, Granola, and a custom Aptible MCP server. As the list grew, managing individual credentials, keeping tool access consistent across the team, and having any visibility into what was being called against shared systems became untenable.

We considered endpoint protection and evaluated DLP tooling. Both felt like the wrong tradeoff: too much friction for our engineering team, and neither addressed the audit logging gap that was our primary concern. We ended up building a proxy layer instead (an MCP gateway) that sits between our team's Claude clients and the upstream servers. It handles authentication, enforces role-based tool grants, logs every tool call, and provides a unified server registry that the whole team connects to instead of maintaining individual configurations. We've deployed it via Jamf MDM profiles, so every team member's Claude Desktop and Claude Code automatically connects to both the MCP gateway and our LLM gateway without any individual setup.

The specific implementation (the data model, the proxy architecture, the audit log schema, the credential management approach) is what the rest of this guide covers. Everything described here is running in production for our own team. Where we've made specific technical choices, we'll explain why.

FAQs

Does MCP have built-in access control?

The protocol defines how servers expose tools and how clients discover and call them, but deliberately leaves access governance as an implementation concern. There is no native mechanism in the spec for restricting which tools a specific user can call, enforcing role-based permissions, or logging tool calls for audit purposes. Those are the gaps this guide addresses.

Why not just use endpoint protection?

Endpoint protection gives you broad coverage but at the cost of significant friction and maintenance overhead. More importantly, it doesn't cover agents running in cloud environments (CI pipelines, EC2 instances, containers) that aren't managed devices. The proxy-layer approach covers both local and cloud-hosted AI usage through the same gateway, and does so without restricting what developer machines can access at the network level.

Is server-level restriction enough for a small team?

For very small teams where everyone has identical access needs, it may be sufficient temporarily. But even small teams run into the audit trail problem quickly: when a security review asks what your AI systems did with internal data last month, there's no record. Audit logging is worth implementing from day one regardless of team size; access differentiation becomes critical as headcount and tool sets grow.

What's the difference between MCP security and prompt injection defense?

MCP security as covered in this guide is primarily about governance: access control, audit logging, credential management, and agent identity. Prompt injection and tool poisoning are protocol-level attack vectors covered separately in Prompt injection in MCP. The two are related (strong access controls reduce the blast radius of a successful injection) but they're distinct problems requiring different mitigations.

Do I also need a dedicated MCP gateway, or can I handle this in application code?

You can implement access control and logging in application code, but proxy-layer enforcement is structurally more reliable. Application-layer controls depend on every service applying them correctly; a proxy enforces them once, for all callers. The chapters in this guide describe the proxy approach, which is what Aptible runs in production for its own team.

Next steps

If you're ready to implement access control: Tool-level access control: how to define role-based grants for specific tools on specific servers, enforced at the proxy layer

If you need audit logging before anything else: Audit logging for MCP tool calls: what to record, how to store it, and how to make it queryable when you need it

If you're in a regulated industry: HIPAA AI security: what MCP governance looks like when HIPAA audit requirements apply

If you're also governing LLM API access: Aptible AI Gateway: the same control layer for LLM requests alongside MCP tool calls

Join the MCP Gateway waitlist →

>

text

Governing AI usage across your engineering team: the problem and our approach

Last updated: June 2026

AI adoption has outpaced the controls that typically govern production system access. Developers connect Claude to databases, issue trackers, and code repositories without any approval process. Agents take actions in those same systems with whatever access the deploying engineer happens to have, and nobody has visibility into what's being called, what data is flowing where, or who is responsible when something goes wrong.

For example: one customer recently told me he discovered a developer had built a Claude Code skill that opened a Rails console in their production read replica. It was originally for debugging, but then it was shared with a few colleagues, then quietly adopted by non-technical staff who used it to run ad hoc queries. By the time the security team became aware of it, there was no log of what had been queried, no way to restrict access without disabling individual developer accounts, and no clear picture of what else might be running that they didn't know about.

That's the governance gap this guide is designed to close.

The MCP spec deliberately doesn't define how organizations should govern tool access, manage credentials across users, or log tool calls for audit purposes. Those are left as implementation concerns. This chapter covers what that gap looks like in practice, and why filling it requires more than what Claude Desktop and Claude Code offer out of the box.

Approaches to consider

There's no single right answer here, and most teams end up combining several of these. The tradeoffs are real.

Platform-native controls (Claude Desktop and Claude Code)

Both clients let you configure which MCP servers are available and restrict access at the server level. This is zero-friction to implement and covers the most common case. The ceiling is low: a user either has access to a server or they don't. There's no tool-level differentiation, no audit trail of what was called, no central credential management, and no way to distinguish a human user from an agent in your logs. For a single developer, this is often enough. For a team, it creates the governance problems this guide is designed to solve.

Endpoint protection and outbound filtering

Some teams use MDM-enforced network controls to restrict what AI tools can connect to, blocking connections to unapproved services at the device or network level. This is the most comprehensive approach in theory: nothing gets through that you haven't explicitly allowed. In practice, it's brittle and intrusive. It creates significant friction for legitimate development workflows, requires constant maintenance as the ecosystem of approved tools changes, and critically, doesn't cover agents running in cloud environments (CI pipelines, EC2 instances, containers) that aren't managed devices.

Data Loss Prevention (DLP)

DLP tools monitor and filter data flows, scanning what's being sent to AI systems and blocking or alerting on sensitive data patterns. This addresses the data exfiltration concern but has a different limitation: it's data-focused, not action-focused. It can tell you that someone sent something that looks like a social security number to an external endpoint, but it can't tell you which tool was called, with what arguments, or what the agent did afterward. It also adds latency and requires significant per-environment configuration. DLP is useful as a defense-in-depth layer; it's not a substitute for access control or audit logging.

Proxy-layer MCP gateway (our approach)

A gateway sits between your Claude clients and the upstream MCP servers, enforcing tool-level access controls, logging every tool call, and managing credentials centrally. Less intrusive than endpoint protection, more control than platform-native, and it covers both local developer tools and cloud-hosted agents. The tradeoff: it only controls what flows through the gateway. An engineer who configures a direct connection to an MCP server (bypassing the gateway) is outside its scope. MDM deployment helps close that gap; we'll cover this in Deploying MCP for your whole team.

We chose this approach because it gave us the right balance of control and usability, and because the audit trail it provides is what we actually needed: not just "was sensitive data sent somewhere" but "which user called which tool, with what arguments, at what time."

What platform-native controls actually cover

Since this guide focuses on the proxy-layer approach, it's worth being specific about where platform-native controls stop. Both Claude Desktop and Claude Code give you a binary: a user either has access to a server or they don't. There is no native mechanism for restricting which tools within a server a given role can call, differentiating access across team members, auditing which tools were called with what arguments, managing credentials centrally, or giving agents a distinct identity separate from the human whose session they're running in.

If five engineers on your team have Claude Desktop connected to Notion, GitHub, and Snowflake, there is no record of what those five engineers have called against those systems. There is no way to say engineer A can query Snowflake but not write to it. There is no way to know that an agent running in engineer B's session made 200 calls to the GitHub API yesterday.

What breaks at team scale

Individual MCP setup doesn't translate cleanly to team deployment, and the failure modes tend to emerge gradually rather than all at once.

Credential sprawl. Each engineer manages their own tokens for each server, some using shared service account credentials and others using personal tokens, with nobody tracking rotation schedules. When an engineer leaves, it's often unclear which shared credentials they had access to. When a credential leaks, attribution is unclear.

No audit trail. Tool calls are invisible to anyone other than the user who made them. There's no central record of what was called against your production database, your customer data in Notion, or any other system your team has connected through Claude. When a security review asks what your AI systems did with customer data last quarter, the answer requires reconstructing from scattered logs (if those logs exist at all).

No access differentiation. A junior engineer and a senior engineer with admin credentials have the same access to every tool every server exposes, as long as both have the server configured. The principle of least privilege (which your compliance program almost certainly requires) has no enforcement mechanism at the MCP layer.

No agent accountability. An agent running in an engineer's Claude Code session uses that engineer's credentials and identity. When that agent makes tool calls, the audit log (if one exists) shows the engineer's name, not the agent's. When something goes wrong, attribution is impossible.

The Day-Zero Normal CISO brief, one of the more practically useful security frameworks published in 2026, puts it in perspective: "Agents, service accounts, and workload identities outnumber human users by roughly 45-to-1. Most programs govern them like an afterthought." MCP only makes this worse.

One of our healthcare customers described this exact situation to us recently: they'd opened Claude Desktop access to about 30 people on their engineering and data teams. Within days the first questions arrived: can I connect it to Snowflake? Can I connect it to Slack? The security team quickly realized there was zero ability to control how data flowed between connectors in the default setup. Designers wanting access to Notion and Figma would also, unavoidably, have access to the PHI-containing Snowflake instance. Engineers working in PHI contexts would have the same tool set as those who weren't. Nobody could see who had configured what.

Their solution, for now, was the only option available: conservative access restrictions and user education. "If we can't enforce things," one of their security engineers told us, "then what can we see? So we can at least try to catch stuff." That's the fallback position for most teams today.

The real risk surface

The abstract threat taxonomy for MCP includes tool poisoning, prompt injection, and confused deputy attacks (covered in Prompt injection in MCP). These are real threats, but for most engineering teams the more immediate risks are operational rather than adversarial.

Over-permissioned access. A developer using Claude to analyze data in a read replica also has access to write tools on the same server. An agent built for a specific task has access to everything the user's account can reach. The blast radius of a prompt injection attack, a misbehaving agent, or a mistaken tool call is determined entirely by what the caller can reach.

Third-party server risk. As the Day-Zero Normal notes, "any MCP server with shell access or credential access is tier-0 supply chain." A server that updates its tool list, changes a tool's behavior, or introduces unexpected new capabilities affects every user and agent connecting through it. Without a central registry and audit log, there's no baseline against which to detect when a server's behavior changes.

Sensitive data in agentic workflows. An agent with access to a Snowflake MCP server may execute queries that retrieve sensitive records as part of a broader task, not because it was told to retrieve them, but because the data was reachable. Without tool-level access controls, the only safeguard is the agent's judgment… and that’s not a real safeguard.

No forensic trail. When something goes wrong (an agent runs a loop, a query returns unexpected data, an action is taken that shouldn't have been), the investigation depends on logs. If no tool call logs exist, there's nothing to investigate. In regulated environments, this gap isn't just operationally painful; it's a compliance failure.

What a proxy-layer gateway needs to provide

Four things need to exist for an MCP gateway to meaningfully close these gaps:

  1. Tool-level access control. Role-based grants that specify which tools each role can call on each server, enforced at the infrastructure layer rather than just filtered from the client's view. Covered in Tool-level access control.

  2. Audit logging. An immutable, queryable record of every tool call: user identity, tool name, server, arguments, timestamp, and IP address. Arguments encrypted at rest. Records that survive server deletion and renames. Covered in Audit logging for MCP tool calls.

  3. Credential management. Centralized management of both shared credentials (one account for the whole org) and personal credentials (each user authenticates individually), with OAuth support, token lifecycle management, and rotation. Covered in MCP authentication.

  4. Agent identity. A distinct identity for non-human principals with their own API keys, role-based grants, and appearance in the audit log separate from any human user. Covered in Agent identity and robot users.

How Aptible approached this internally

Aptible's team uses Claude Desktop and Claude Code connected to a growing set of internal tools: Notion, GitHub, Shortcut, Pylon, Sentry, Metabase, Granola, and a custom Aptible MCP server. As the list grew, managing individual credentials, keeping tool access consistent across the team, and having any visibility into what was being called against shared systems became untenable.

We considered endpoint protection and evaluated DLP tooling. Both felt like the wrong tradeoff: too much friction for our engineering team, and neither addressed the audit logging gap that was our primary concern. We ended up building a proxy layer instead (an MCP gateway) that sits between our team's Claude clients and the upstream servers. It handles authentication, enforces role-based tool grants, logs every tool call, and provides a unified server registry that the whole team connects to instead of maintaining individual configurations. We've deployed it via Jamf MDM profiles, so every team member's Claude Desktop and Claude Code automatically connects to both the MCP gateway and our LLM gateway without any individual setup.

The specific implementation (the data model, the proxy architecture, the audit log schema, the credential management approach) is what the rest of this guide covers. Everything described here is running in production for our own team. Where we've made specific technical choices, we'll explain why.

FAQs

Does MCP have built-in access control?

The protocol defines how servers expose tools and how clients discover and call them, but deliberately leaves access governance as an implementation concern. There is no native mechanism in the spec for restricting which tools a specific user can call, enforcing role-based permissions, or logging tool calls for audit purposes. Those are the gaps this guide addresses.

Why not just use endpoint protection?

Endpoint protection gives you broad coverage but at the cost of significant friction and maintenance overhead. More importantly, it doesn't cover agents running in cloud environments (CI pipelines, EC2 instances, containers) that aren't managed devices. The proxy-layer approach covers both local and cloud-hosted AI usage through the same gateway, and does so without restricting what developer machines can access at the network level.

Is server-level restriction enough for a small team?

For very small teams where everyone has identical access needs, it may be sufficient temporarily. But even small teams run into the audit trail problem quickly: when a security review asks what your AI systems did with internal data last month, there's no record. Audit logging is worth implementing from day one regardless of team size; access differentiation becomes critical as headcount and tool sets grow.

What's the difference between MCP security and prompt injection defense?

MCP security as covered in this guide is primarily about governance: access control, audit logging, credential management, and agent identity. Prompt injection and tool poisoning are protocol-level attack vectors covered separately in Prompt injection in MCP. The two are related (strong access controls reduce the blast radius of a successful injection) but they're distinct problems requiring different mitigations.

Do I also need a dedicated MCP gateway, or can I handle this in application code?

You can implement access control and logging in application code, but proxy-layer enforcement is structurally more reliable. Application-layer controls depend on every service applying them correctly; a proxy enforces them once, for all callers. The chapters in this guide describe the proxy approach, which is what Aptible runs in production for its own team.

Next steps

If you're ready to implement access control: Tool-level access control: how to define role-based grants for specific tools on specific servers, enforced at the proxy layer

If you need audit logging before anything else: Audit logging for MCP tool calls: what to record, how to store it, and how to make it queryable when you need it

If you're in a regulated industry: HIPAA AI security: what MCP governance looks like when HIPAA audit requirements apply

If you're also governing LLM API access: Aptible AI Gateway: the same control layer for LLM requests alongside MCP tool calls

Join the MCP Gateway waitlist →

>

text

Governing AI usage across your engineering team: the problem and our approach

Last updated: June 2026

AI adoption has outpaced the controls that typically govern production system access. Developers connect Claude to databases, issue trackers, and code repositories without any approval process. Agents take actions in those same systems with whatever access the deploying engineer happens to have, and nobody has visibility into what's being called, what data is flowing where, or who is responsible when something goes wrong.

For example: one customer recently told me he discovered a developer had built a Claude Code skill that opened a Rails console in their production read replica. It was originally for debugging, but then it was shared with a few colleagues, then quietly adopted by non-technical staff who used it to run ad hoc queries. By the time the security team became aware of it, there was no log of what had been queried, no way to restrict access without disabling individual developer accounts, and no clear picture of what else might be running that they didn't know about.

That's the governance gap this guide is designed to close.

The MCP spec deliberately doesn't define how organizations should govern tool access, manage credentials across users, or log tool calls for audit purposes. Those are left as implementation concerns. This chapter covers what that gap looks like in practice, and why filling it requires more than what Claude Desktop and Claude Code offer out of the box.

Approaches to consider

There's no single right answer here, and most teams end up combining several of these. The tradeoffs are real.

Platform-native controls (Claude Desktop and Claude Code)

Both clients let you configure which MCP servers are available and restrict access at the server level. This is zero-friction to implement and covers the most common case. The ceiling is low: a user either has access to a server or they don't. There's no tool-level differentiation, no audit trail of what was called, no central credential management, and no way to distinguish a human user from an agent in your logs. For a single developer, this is often enough. For a team, it creates the governance problems this guide is designed to solve.

Endpoint protection and outbound filtering

Some teams use MDM-enforced network controls to restrict what AI tools can connect to, blocking connections to unapproved services at the device or network level. This is the most comprehensive approach in theory: nothing gets through that you haven't explicitly allowed. In practice, it's brittle and intrusive. It creates significant friction for legitimate development workflows, requires constant maintenance as the ecosystem of approved tools changes, and critically, doesn't cover agents running in cloud environments (CI pipelines, EC2 instances, containers) that aren't managed devices.

Data Loss Prevention (DLP)

DLP tools monitor and filter data flows, scanning what's being sent to AI systems and blocking or alerting on sensitive data patterns. This addresses the data exfiltration concern but has a different limitation: it's data-focused, not action-focused. It can tell you that someone sent something that looks like a social security number to an external endpoint, but it can't tell you which tool was called, with what arguments, or what the agent did afterward. It also adds latency and requires significant per-environment configuration. DLP is useful as a defense-in-depth layer; it's not a substitute for access control or audit logging.

Proxy-layer MCP gateway (our approach)

A gateway sits between your Claude clients and the upstream MCP servers, enforcing tool-level access controls, logging every tool call, and managing credentials centrally. Less intrusive than endpoint protection, more control than platform-native, and it covers both local developer tools and cloud-hosted agents. The tradeoff: it only controls what flows through the gateway. An engineer who configures a direct connection to an MCP server (bypassing the gateway) is outside its scope. MDM deployment helps close that gap; we'll cover this in Deploying MCP for your whole team.

We chose this approach because it gave us the right balance of control and usability, and because the audit trail it provides is what we actually needed: not just "was sensitive data sent somewhere" but "which user called which tool, with what arguments, at what time."

What platform-native controls actually cover

Since this guide focuses on the proxy-layer approach, it's worth being specific about where platform-native controls stop. Both Claude Desktop and Claude Code give you a binary: a user either has access to a server or they don't. There is no native mechanism for restricting which tools within a server a given role can call, differentiating access across team members, auditing which tools were called with what arguments, managing credentials centrally, or giving agents a distinct identity separate from the human whose session they're running in.

If five engineers on your team have Claude Desktop connected to Notion, GitHub, and Snowflake, there is no record of what those five engineers have called against those systems. There is no way to say engineer A can query Snowflake but not write to it. There is no way to know that an agent running in engineer B's session made 200 calls to the GitHub API yesterday.

What breaks at team scale

Individual MCP setup doesn't translate cleanly to team deployment, and the failure modes tend to emerge gradually rather than all at once.

Credential sprawl. Each engineer manages their own tokens for each server, some using shared service account credentials and others using personal tokens, with nobody tracking rotation schedules. When an engineer leaves, it's often unclear which shared credentials they had access to. When a credential leaks, attribution is unclear.

No audit trail. Tool calls are invisible to anyone other than the user who made them. There's no central record of what was called against your production database, your customer data in Notion, or any other system your team has connected through Claude. When a security review asks what your AI systems did with customer data last quarter, the answer requires reconstructing from scattered logs (if those logs exist at all).

No access differentiation. A junior engineer and a senior engineer with admin credentials have the same access to every tool every server exposes, as long as both have the server configured. The principle of least privilege (which your compliance program almost certainly requires) has no enforcement mechanism at the MCP layer.

No agent accountability. An agent running in an engineer's Claude Code session uses that engineer's credentials and identity. When that agent makes tool calls, the audit log (if one exists) shows the engineer's name, not the agent's. When something goes wrong, attribution is impossible.

The Day-Zero Normal CISO brief, one of the more practically useful security frameworks published in 2026, puts it in perspective: "Agents, service accounts, and workload identities outnumber human users by roughly 45-to-1. Most programs govern them like an afterthought." MCP only makes this worse.

One of our healthcare customers described this exact situation to us recently: they'd opened Claude Desktop access to about 30 people on their engineering and data teams. Within days the first questions arrived: can I connect it to Snowflake? Can I connect it to Slack? The security team quickly realized there was zero ability to control how data flowed between connectors in the default setup. Designers wanting access to Notion and Figma would also, unavoidably, have access to the PHI-containing Snowflake instance. Engineers working in PHI contexts would have the same tool set as those who weren't. Nobody could see who had configured what.

Their solution, for now, was the only option available: conservative access restrictions and user education. "If we can't enforce things," one of their security engineers told us, "then what can we see? So we can at least try to catch stuff." That's the fallback position for most teams today.

The real risk surface

The abstract threat taxonomy for MCP includes tool poisoning, prompt injection, and confused deputy attacks (covered in Prompt injection in MCP). These are real threats, but for most engineering teams the more immediate risks are operational rather than adversarial.

Over-permissioned access. A developer using Claude to analyze data in a read replica also has access to write tools on the same server. An agent built for a specific task has access to everything the user's account can reach. The blast radius of a prompt injection attack, a misbehaving agent, or a mistaken tool call is determined entirely by what the caller can reach.

Third-party server risk. As the Day-Zero Normal notes, "any MCP server with shell access or credential access is tier-0 supply chain." A server that updates its tool list, changes a tool's behavior, or introduces unexpected new capabilities affects every user and agent connecting through it. Without a central registry and audit log, there's no baseline against which to detect when a server's behavior changes.

Sensitive data in agentic workflows. An agent with access to a Snowflake MCP server may execute queries that retrieve sensitive records as part of a broader task, not because it was told to retrieve them, but because the data was reachable. Without tool-level access controls, the only safeguard is the agent's judgment… and that’s not a real safeguard.

No forensic trail. When something goes wrong (an agent runs a loop, a query returns unexpected data, an action is taken that shouldn't have been), the investigation depends on logs. If no tool call logs exist, there's nothing to investigate. In regulated environments, this gap isn't just operationally painful; it's a compliance failure.

What a proxy-layer gateway needs to provide

Four things need to exist for an MCP gateway to meaningfully close these gaps:

  1. Tool-level access control. Role-based grants that specify which tools each role can call on each server, enforced at the infrastructure layer rather than just filtered from the client's view. Covered in Tool-level access control.

  2. Audit logging. An immutable, queryable record of every tool call: user identity, tool name, server, arguments, timestamp, and IP address. Arguments encrypted at rest. Records that survive server deletion and renames. Covered in Audit logging for MCP tool calls.

  3. Credential management. Centralized management of both shared credentials (one account for the whole org) and personal credentials (each user authenticates individually), with OAuth support, token lifecycle management, and rotation. Covered in MCP authentication.

  4. Agent identity. A distinct identity for non-human principals with their own API keys, role-based grants, and appearance in the audit log separate from any human user. Covered in Agent identity and robot users.

How Aptible approached this internally

Aptible's team uses Claude Desktop and Claude Code connected to a growing set of internal tools: Notion, GitHub, Shortcut, Pylon, Sentry, Metabase, Granola, and a custom Aptible MCP server. As the list grew, managing individual credentials, keeping tool access consistent across the team, and having any visibility into what was being called against shared systems became untenable.

We considered endpoint protection and evaluated DLP tooling. Both felt like the wrong tradeoff: too much friction for our engineering team, and neither addressed the audit logging gap that was our primary concern. We ended up building a proxy layer instead (an MCP gateway) that sits between our team's Claude clients and the upstream servers. It handles authentication, enforces role-based tool grants, logs every tool call, and provides a unified server registry that the whole team connects to instead of maintaining individual configurations. We've deployed it via Jamf MDM profiles, so every team member's Claude Desktop and Claude Code automatically connects to both the MCP gateway and our LLM gateway without any individual setup.

The specific implementation (the data model, the proxy architecture, the audit log schema, the credential management approach) is what the rest of this guide covers. Everything described here is running in production for our own team. Where we've made specific technical choices, we'll explain why.

FAQs

Does MCP have built-in access control?

The protocol defines how servers expose tools and how clients discover and call them, but deliberately leaves access governance as an implementation concern. There is no native mechanism in the spec for restricting which tools a specific user can call, enforcing role-based permissions, or logging tool calls for audit purposes. Those are the gaps this guide addresses.

Why not just use endpoint protection?

Endpoint protection gives you broad coverage but at the cost of significant friction and maintenance overhead. More importantly, it doesn't cover agents running in cloud environments (CI pipelines, EC2 instances, containers) that aren't managed devices. The proxy-layer approach covers both local and cloud-hosted AI usage through the same gateway, and does so without restricting what developer machines can access at the network level.

Is server-level restriction enough for a small team?

For very small teams where everyone has identical access needs, it may be sufficient temporarily. But even small teams run into the audit trail problem quickly: when a security review asks what your AI systems did with internal data last month, there's no record. Audit logging is worth implementing from day one regardless of team size; access differentiation becomes critical as headcount and tool sets grow.

What's the difference between MCP security and prompt injection defense?

MCP security as covered in this guide is primarily about governance: access control, audit logging, credential management, and agent identity. Prompt injection and tool poisoning are protocol-level attack vectors covered separately in Prompt injection in MCP. The two are related (strong access controls reduce the blast radius of a successful injection) but they're distinct problems requiring different mitigations.

Do I also need a dedicated MCP gateway, or can I handle this in application code?

You can implement access control and logging in application code, but proxy-layer enforcement is structurally more reliable. Application-layer controls depend on every service applying them correctly; a proxy enforces them once, for all callers. The chapters in this guide describe the proxy approach, which is what Aptible runs in production for its own team.

Next steps

If you're ready to implement access control: Tool-level access control: how to define role-based grants for specific tools on specific servers, enforced at the proxy layer

If you need audit logging before anything else: Audit logging for MCP tool calls: what to record, how to store it, and how to make it queryable when you need it

If you're in a regulated industry: HIPAA AI security: what MCP governance looks like when HIPAA audit requirements apply

If you're also governing LLM API access: Aptible AI Gateway: the same control layer for LLM requests alongside MCP tool calls

Join the MCP Gateway waitlist →