>

Agent identity and robot users: how to give agents their own identity instead of borrowing a human's

Agent identity and robot users: how to give agents their own identity instead of borrowing a human's

Last updated: June 2026

When an agent runs in an engineer's Claude Code session, it authenticates as that engineer. Every tool call it makes appears in the audit log under the engineer's name. When something goes wrong (the agent runs a loop, calls a tool with unexpected arguments, accesses data outside its intended scope) there's no way to distinguish what the agent did from what the human did.

This is the default state for most teams using MCP today. It's not a configuration mistake; it's just how session-based authentication works. The fix requires giving agents their own identity distinct from any human user, with their own credentials, their own role assignments, and their own presence in the audit log.

This matters most for agents running in production infrastructure: on a schedule in CI, as a background worker, or on a cloud server rather than a developer's laptop. When an agent runs unattended, the attribution problem compounds. Tool calls accumulate over time with no way to distinguish the agent's actions from those of the human who deployed it.

Solutions to consider

Do nothing (the default) Most teams start here. Agents run in whatever session deployed them, inherit whatever access that session has, and appear in audit logs as the deploying engineer. This works until you need to investigate something (at which point you can't tell agent actions from human actions) or until an agent runs with more access than it should have because the engineer who deployed it had broad permissions.

Dedicated human accounts for agents Some teams create separate user accounts for each agent and give those accounts minimum necessary permissions. This solves the audit attribution problem partially (the account name identifies the agent) but doesn't scale cleanly, requires managing human-style credentials for non-human principals, and the accounts still look like human users in most systems. It also ties the agent's access to a person who may leave the organization.

Environment variables and direct service credentials Agents connect directly to services using API keys stored as environment variables, bypassing the MCP gateway entirely. This gives agents their own credentials but removes them from the governance layer: no central audit log, no role-based grant enforcement, no visibility into what tools they're calling.

Robot users with a proxy gateway (our approach) A robot is a named non-human principal in the gateway with its own API key, its own role assignments, and its own distinct identity in the audit log. It can only access shared-mode servers (never personal OAuth credentials) and its tool calls are attributed to the robot, not to any human. The rest of this chapter describes how to build and deployed this.

Aptible's solution: robot users

A robot is a named non-human principal registered in your organization's gateway. It authenticates with an API key prefixed aptk-, gets resolved to a set of role-based grants, and appears in the audit log under its own UUID with an empty email field. From the gateway's perspective, a robot and a human user go through the same grant resolution and enforcement logic; the difference is how they authenticate and how they appear in the log.

How robots appear in the audit log

In McpAuditLog, robot tool calls appear with:

  • user_id: the robot's UUID

  • email: an empty string

This is deliberately different from human users, where email is always populated. Any audit log query that filters on email = "" returns only robot activity. Any query that filters on a specific robot UUID returns that specific agent's full call history.

This separation makes forensic investigation straightforward: you can query "what did the alerts-bot do between 14:00 and 15:00 yesterday" independently of "what did any human do during that window."

The two use cases for robot users

Robot users solve two distinct problems. The first is straightforward: automated agents need their own identity. The second is more nuanced: a single human engineer may need different tool access depending on the context they're working in. The implementation looks similar but the reasoning is different.

Agents as non-human principals

The most common use case: an agent running in CI, as a background worker, or as part of an automated workflow should have its own identity so its tool calls are attributable to the agent, not the engineer who deployed it. A robot named deployment-agent or alerts-bot makes it unambiguous in the audit log what was an automated action versus a human one.

This use case is straightforward: create a robot, assign it to a role with the minimum tools it needs, generate an API key, and configure the agent to use that key.

Context-dependent permission profiles

A different use case: a human engineer has different access needs depending on what they're working on. When working with PHI, they should have access only to PHI-enabled tools. When working outside that context, they may need a different set of tools entirely. Those two sets should not overlap.

One way to implement this today is to provision separate robots that represent different permission contexts, and configure the user's agent or tool to connect with the appropriate robot API key for each context. The robots represent "PHI context" and "non-PHI context" rather than specific agents.

This is a workaround, not a first-class feature. It requires the user to explicitly select which API key to use based on their current context, and the audit log will show the robot rather than the human. Per-user context switching with human attribution doesn't exist in Aptible’s current model. If this use case is critical for your team, it warrants a discussion about how to implement it given that constraint (connect with us here to discuss).

How you could structure robot users for your team

The general pattern is one robot per distinct agent workload, assigned to a role that has only the tools that workload needs. Don't share robots between unrelated agent workloads; it couples their access together and makes audit log analysis harder.

Name robots descriptively so audit log entries are self-explanatory: github-triage-agent, weekly-report-bot, deployment-checker are all more useful in an audit log than robot-1 or agent.

For most teams, robots fall into a few natural categories:

  • Read-only analytics agents: query databases and generate reports. Assign to a role with only selectstyle tools on your data warehouse server.

  • Operational automation agents: file tickets, post notifications, trigger workflows. Assign to a role with write tools on specific servers, scoped as narrowly as the task requires.

  • Monitoring and alerting agents: read from observability tools and post to notification systems. Often read-only on multiple servers.

Keep robots out of admin roles. If an agent needs admin-level access to do its job, that's a signal that the job is too broad or the role structure needs refinement.

Operational security for robot credentials

Key hashing at creation. The plaintext API key is generated once and never stored. The database stores only the SHA-256 hash. Treat the plaintext token like a password: store it in a secrets manager, not in environment variables checked into version control.

Key rotation without downtime. Each robot can have multiple active API keys simultaneously. The rotation workflow: generate a new key, update all agents using the robot to use the new key, then revoke the old key. There's no window where the agent is unauthenticated.

Revocation on compromise. If a robot API key is compromised, revoking it immediately prevents further tool calls. Because keys are looked up by hash, revocation takes effect on the next request. The 120-second auth cache means there's a short window of continued access, but it expires quickly. For time-sensitive incidents, assume up to 120 seconds of exposure after revocation.

Soft deletion on decommission. When an agent is decommissioned, soft-delete the robot rather than just revoking its keys. This preserves the audit log relationship (historical tool calls remain attributed to the robot) while preventing any future authentication.

FAQs

Why can't robots use personal OAuth credentials?

Personal OAuth credentials are scoped to an individual user's account at the upstream service. An agent connecting with a personal OAuth token is essentially impersonating that user, which is exactly the attribution problem robot users are designed to solve. Robots are restricted to shared-mode servers so that the credentials they use are organizational, not personal.

Can I have multiple robots with different permissions?

Yes, and this is the recommended approach for agents with different scopes. Each robot gets the role assignments appropriate for its specific workload. An analytics agent and a deployment agent should be separate robots with separate roles, even if both are managed by the same team.

How do I find all the tool calls a specific agent made?

Query McpAuditLog filtering on the robot's user_id. Since robot email fields are empty, you can also use email="" to find all robot activity across your organization, then narrow by user_id for a specific robot.

What's the difference between a robot user and a service account at the upstream service?

A service account at GitHub, Notion, or Snowflake gives you a credential to authenticate to that service. It doesn't give you audit logging of what that credential did through Claude, tool-level access control, or any of the gateway's other governance features. Robot users and upstream service accounts serve different layers: the robot controls what tools can be called through the gateway, the service account controls what those tool calls can do at the upstream service. You likely need both.

Is per-session credential scoping available?

Not yet. The current model gives each robot a persistent API key. Per-session credentials (temporary keys scoped to a single agent run, with the run ID recorded in the audit log) are on the roadmap. This would allow you to query "what did this specific run of the alerts-bot do" rather than just "what did the alerts-bot do." If this use case is critical, plan your robot naming scheme to approximate run-level attribution in the meantime.

Next steps

If you're ready to deploy robots alongside your team's human users: Deploying MCP for your whole team: MDM configuration, server registry, and how robots fit into org-wide deployment

If you need to understand what robots can and can't access: Tool-level access control: how the grant model works and why robots are restricted to shared-mode servers

If you want to see how robots appear in the audit trail: Audit logging for MCP tool calls: what robot tool calls look like in the log and how to query for them

Aptible MCP Gateway gives engineering teams tool-level access control, audit logging, and centralized credential management for MCP without building the proxy infrastructure yourself. Deployed alongside Aptible AI Gateway, it covers both LLM and tool call governance in one place. Join the MCP Gateway waitlist →

>

text

Agent identity and robot users: how to give agents their own identity instead of borrowing a human's

Last updated: June 2026

When an agent runs in an engineer's Claude Code session, it authenticates as that engineer. Every tool call it makes appears in the audit log under the engineer's name. When something goes wrong (the agent runs a loop, calls a tool with unexpected arguments, accesses data outside its intended scope) there's no way to distinguish what the agent did from what the human did.

This is the default state for most teams using MCP today. It's not a configuration mistake; it's just how session-based authentication works. The fix requires giving agents their own identity distinct from any human user, with their own credentials, their own role assignments, and their own presence in the audit log.

This matters most for agents running in production infrastructure: on a schedule in CI, as a background worker, or on a cloud server rather than a developer's laptop. When an agent runs unattended, the attribution problem compounds. Tool calls accumulate over time with no way to distinguish the agent's actions from those of the human who deployed it.

Solutions to consider

Do nothing (the default) Most teams start here. Agents run in whatever session deployed them, inherit whatever access that session has, and appear in audit logs as the deploying engineer. This works until you need to investigate something (at which point you can't tell agent actions from human actions) or until an agent runs with more access than it should have because the engineer who deployed it had broad permissions.

Dedicated human accounts for agents Some teams create separate user accounts for each agent and give those accounts minimum necessary permissions. This solves the audit attribution problem partially (the account name identifies the agent) but doesn't scale cleanly, requires managing human-style credentials for non-human principals, and the accounts still look like human users in most systems. It also ties the agent's access to a person who may leave the organization.

Environment variables and direct service credentials Agents connect directly to services using API keys stored as environment variables, bypassing the MCP gateway entirely. This gives agents their own credentials but removes them from the governance layer: no central audit log, no role-based grant enforcement, no visibility into what tools they're calling.

Robot users with a proxy gateway (our approach) A robot is a named non-human principal in the gateway with its own API key, its own role assignments, and its own distinct identity in the audit log. It can only access shared-mode servers (never personal OAuth credentials) and its tool calls are attributed to the robot, not to any human. The rest of this chapter describes how to build and deployed this.

Aptible's solution: robot users

A robot is a named non-human principal registered in your organization's gateway. It authenticates with an API key prefixed aptk-, gets resolved to a set of role-based grants, and appears in the audit log under its own UUID with an empty email field. From the gateway's perspective, a robot and a human user go through the same grant resolution and enforcement logic; the difference is how they authenticate and how they appear in the log.

How robots appear in the audit log

In McpAuditLog, robot tool calls appear with:

  • user_id: the robot's UUID

  • email: an empty string

This is deliberately different from human users, where email is always populated. Any audit log query that filters on email = "" returns only robot activity. Any query that filters on a specific robot UUID returns that specific agent's full call history.

This separation makes forensic investigation straightforward: you can query "what did the alerts-bot do between 14:00 and 15:00 yesterday" independently of "what did any human do during that window."

The two use cases for robot users

Robot users solve two distinct problems. The first is straightforward: automated agents need their own identity. The second is more nuanced: a single human engineer may need different tool access depending on the context they're working in. The implementation looks similar but the reasoning is different.

Agents as non-human principals

The most common use case: an agent running in CI, as a background worker, or as part of an automated workflow should have its own identity so its tool calls are attributable to the agent, not the engineer who deployed it. A robot named deployment-agent or alerts-bot makes it unambiguous in the audit log what was an automated action versus a human one.

This use case is straightforward: create a robot, assign it to a role with the minimum tools it needs, generate an API key, and configure the agent to use that key.

Context-dependent permission profiles

A different use case: a human engineer has different access needs depending on what they're working on. When working with PHI, they should have access only to PHI-enabled tools. When working outside that context, they may need a different set of tools entirely. Those two sets should not overlap.

One way to implement this today is to provision separate robots that represent different permission contexts, and configure the user's agent or tool to connect with the appropriate robot API key for each context. The robots represent "PHI context" and "non-PHI context" rather than specific agents.

This is a workaround, not a first-class feature. It requires the user to explicitly select which API key to use based on their current context, and the audit log will show the robot rather than the human. Per-user context switching with human attribution doesn't exist in Aptible’s current model. If this use case is critical for your team, it warrants a discussion about how to implement it given that constraint (connect with us here to discuss).

How you could structure robot users for your team

The general pattern is one robot per distinct agent workload, assigned to a role that has only the tools that workload needs. Don't share robots between unrelated agent workloads; it couples their access together and makes audit log analysis harder.

Name robots descriptively so audit log entries are self-explanatory: github-triage-agent, weekly-report-bot, deployment-checker are all more useful in an audit log than robot-1 or agent.

For most teams, robots fall into a few natural categories:

  • Read-only analytics agents: query databases and generate reports. Assign to a role with only selectstyle tools on your data warehouse server.

  • Operational automation agents: file tickets, post notifications, trigger workflows. Assign to a role with write tools on specific servers, scoped as narrowly as the task requires.

  • Monitoring and alerting agents: read from observability tools and post to notification systems. Often read-only on multiple servers.

Keep robots out of admin roles. If an agent needs admin-level access to do its job, that's a signal that the job is too broad or the role structure needs refinement.

Operational security for robot credentials

Key hashing at creation. The plaintext API key is generated once and never stored. The database stores only the SHA-256 hash. Treat the plaintext token like a password: store it in a secrets manager, not in environment variables checked into version control.

Key rotation without downtime. Each robot can have multiple active API keys simultaneously. The rotation workflow: generate a new key, update all agents using the robot to use the new key, then revoke the old key. There's no window where the agent is unauthenticated.

Revocation on compromise. If a robot API key is compromised, revoking it immediately prevents further tool calls. Because keys are looked up by hash, revocation takes effect on the next request. The 120-second auth cache means there's a short window of continued access, but it expires quickly. For time-sensitive incidents, assume up to 120 seconds of exposure after revocation.

Soft deletion on decommission. When an agent is decommissioned, soft-delete the robot rather than just revoking its keys. This preserves the audit log relationship (historical tool calls remain attributed to the robot) while preventing any future authentication.

FAQs

Why can't robots use personal OAuth credentials?

Personal OAuth credentials are scoped to an individual user's account at the upstream service. An agent connecting with a personal OAuth token is essentially impersonating that user, which is exactly the attribution problem robot users are designed to solve. Robots are restricted to shared-mode servers so that the credentials they use are organizational, not personal.

Can I have multiple robots with different permissions?

Yes, and this is the recommended approach for agents with different scopes. Each robot gets the role assignments appropriate for its specific workload. An analytics agent and a deployment agent should be separate robots with separate roles, even if both are managed by the same team.

How do I find all the tool calls a specific agent made?

Query McpAuditLog filtering on the robot's user_id. Since robot email fields are empty, you can also use email="" to find all robot activity across your organization, then narrow by user_id for a specific robot.

What's the difference between a robot user and a service account at the upstream service?

A service account at GitHub, Notion, or Snowflake gives you a credential to authenticate to that service. It doesn't give you audit logging of what that credential did through Claude, tool-level access control, or any of the gateway's other governance features. Robot users and upstream service accounts serve different layers: the robot controls what tools can be called through the gateway, the service account controls what those tool calls can do at the upstream service. You likely need both.

Is per-session credential scoping available?

Not yet. The current model gives each robot a persistent API key. Per-session credentials (temporary keys scoped to a single agent run, with the run ID recorded in the audit log) are on the roadmap. This would allow you to query "what did this specific run of the alerts-bot do" rather than just "what did the alerts-bot do." If this use case is critical, plan your robot naming scheme to approximate run-level attribution in the meantime.

Next steps

If you're ready to deploy robots alongside your team's human users: Deploying MCP for your whole team: MDM configuration, server registry, and how robots fit into org-wide deployment

If you need to understand what robots can and can't access: Tool-level access control: how the grant model works and why robots are restricted to shared-mode servers

If you want to see how robots appear in the audit trail: Audit logging for MCP tool calls: what robot tool calls look like in the log and how to query for them

Aptible MCP Gateway gives engineering teams tool-level access control, audit logging, and centralized credential management for MCP without building the proxy infrastructure yourself. Deployed alongside Aptible AI Gateway, it covers both LLM and tool call governance in one place. Join the MCP Gateway waitlist →

>

text

Agent identity and robot users: how to give agents their own identity instead of borrowing a human's

Last updated: June 2026

When an agent runs in an engineer's Claude Code session, it authenticates as that engineer. Every tool call it makes appears in the audit log under the engineer's name. When something goes wrong (the agent runs a loop, calls a tool with unexpected arguments, accesses data outside its intended scope) there's no way to distinguish what the agent did from what the human did.

This is the default state for most teams using MCP today. It's not a configuration mistake; it's just how session-based authentication works. The fix requires giving agents their own identity distinct from any human user, with their own credentials, their own role assignments, and their own presence in the audit log.

This matters most for agents running in production infrastructure: on a schedule in CI, as a background worker, or on a cloud server rather than a developer's laptop. When an agent runs unattended, the attribution problem compounds. Tool calls accumulate over time with no way to distinguish the agent's actions from those of the human who deployed it.

Solutions to consider

Do nothing (the default) Most teams start here. Agents run in whatever session deployed them, inherit whatever access that session has, and appear in audit logs as the deploying engineer. This works until you need to investigate something (at which point you can't tell agent actions from human actions) or until an agent runs with more access than it should have because the engineer who deployed it had broad permissions.

Dedicated human accounts for agents Some teams create separate user accounts for each agent and give those accounts minimum necessary permissions. This solves the audit attribution problem partially (the account name identifies the agent) but doesn't scale cleanly, requires managing human-style credentials for non-human principals, and the accounts still look like human users in most systems. It also ties the agent's access to a person who may leave the organization.

Environment variables and direct service credentials Agents connect directly to services using API keys stored as environment variables, bypassing the MCP gateway entirely. This gives agents their own credentials but removes them from the governance layer: no central audit log, no role-based grant enforcement, no visibility into what tools they're calling.

Robot users with a proxy gateway (our approach) A robot is a named non-human principal in the gateway with its own API key, its own role assignments, and its own distinct identity in the audit log. It can only access shared-mode servers (never personal OAuth credentials) and its tool calls are attributed to the robot, not to any human. The rest of this chapter describes how to build and deployed this.

Aptible's solution: robot users

A robot is a named non-human principal registered in your organization's gateway. It authenticates with an API key prefixed aptk-, gets resolved to a set of role-based grants, and appears in the audit log under its own UUID with an empty email field. From the gateway's perspective, a robot and a human user go through the same grant resolution and enforcement logic; the difference is how they authenticate and how they appear in the log.

How robots appear in the audit log

In McpAuditLog, robot tool calls appear with:

  • user_id: the robot's UUID

  • email: an empty string

This is deliberately different from human users, where email is always populated. Any audit log query that filters on email = "" returns only robot activity. Any query that filters on a specific robot UUID returns that specific agent's full call history.

This separation makes forensic investigation straightforward: you can query "what did the alerts-bot do between 14:00 and 15:00 yesterday" independently of "what did any human do during that window."

The two use cases for robot users

Robot users solve two distinct problems. The first is straightforward: automated agents need their own identity. The second is more nuanced: a single human engineer may need different tool access depending on the context they're working in. The implementation looks similar but the reasoning is different.

Agents as non-human principals

The most common use case: an agent running in CI, as a background worker, or as part of an automated workflow should have its own identity so its tool calls are attributable to the agent, not the engineer who deployed it. A robot named deployment-agent or alerts-bot makes it unambiguous in the audit log what was an automated action versus a human one.

This use case is straightforward: create a robot, assign it to a role with the minimum tools it needs, generate an API key, and configure the agent to use that key.

Context-dependent permission profiles

A different use case: a human engineer has different access needs depending on what they're working on. When working with PHI, they should have access only to PHI-enabled tools. When working outside that context, they may need a different set of tools entirely. Those two sets should not overlap.

One way to implement this today is to provision separate robots that represent different permission contexts, and configure the user's agent or tool to connect with the appropriate robot API key for each context. The robots represent "PHI context" and "non-PHI context" rather than specific agents.

This is a workaround, not a first-class feature. It requires the user to explicitly select which API key to use based on their current context, and the audit log will show the robot rather than the human. Per-user context switching with human attribution doesn't exist in Aptible’s current model. If this use case is critical for your team, it warrants a discussion about how to implement it given that constraint (connect with us here to discuss).

How you could structure robot users for your team

The general pattern is one robot per distinct agent workload, assigned to a role that has only the tools that workload needs. Don't share robots between unrelated agent workloads; it couples their access together and makes audit log analysis harder.

Name robots descriptively so audit log entries are self-explanatory: github-triage-agent, weekly-report-bot, deployment-checker are all more useful in an audit log than robot-1 or agent.

For most teams, robots fall into a few natural categories:

  • Read-only analytics agents: query databases and generate reports. Assign to a role with only selectstyle tools on your data warehouse server.

  • Operational automation agents: file tickets, post notifications, trigger workflows. Assign to a role with write tools on specific servers, scoped as narrowly as the task requires.

  • Monitoring and alerting agents: read from observability tools and post to notification systems. Often read-only on multiple servers.

Keep robots out of admin roles. If an agent needs admin-level access to do its job, that's a signal that the job is too broad or the role structure needs refinement.

Operational security for robot credentials

Key hashing at creation. The plaintext API key is generated once and never stored. The database stores only the SHA-256 hash. Treat the plaintext token like a password: store it in a secrets manager, not in environment variables checked into version control.

Key rotation without downtime. Each robot can have multiple active API keys simultaneously. The rotation workflow: generate a new key, update all agents using the robot to use the new key, then revoke the old key. There's no window where the agent is unauthenticated.

Revocation on compromise. If a robot API key is compromised, revoking it immediately prevents further tool calls. Because keys are looked up by hash, revocation takes effect on the next request. The 120-second auth cache means there's a short window of continued access, but it expires quickly. For time-sensitive incidents, assume up to 120 seconds of exposure after revocation.

Soft deletion on decommission. When an agent is decommissioned, soft-delete the robot rather than just revoking its keys. This preserves the audit log relationship (historical tool calls remain attributed to the robot) while preventing any future authentication.

FAQs

Why can't robots use personal OAuth credentials?

Personal OAuth credentials are scoped to an individual user's account at the upstream service. An agent connecting with a personal OAuth token is essentially impersonating that user, which is exactly the attribution problem robot users are designed to solve. Robots are restricted to shared-mode servers so that the credentials they use are organizational, not personal.

Can I have multiple robots with different permissions?

Yes, and this is the recommended approach for agents with different scopes. Each robot gets the role assignments appropriate for its specific workload. An analytics agent and a deployment agent should be separate robots with separate roles, even if both are managed by the same team.

How do I find all the tool calls a specific agent made?

Query McpAuditLog filtering on the robot's user_id. Since robot email fields are empty, you can also use email="" to find all robot activity across your organization, then narrow by user_id for a specific robot.

What's the difference between a robot user and a service account at the upstream service?

A service account at GitHub, Notion, or Snowflake gives you a credential to authenticate to that service. It doesn't give you audit logging of what that credential did through Claude, tool-level access control, or any of the gateway's other governance features. Robot users and upstream service accounts serve different layers: the robot controls what tools can be called through the gateway, the service account controls what those tool calls can do at the upstream service. You likely need both.

Is per-session credential scoping available?

Not yet. The current model gives each robot a persistent API key. Per-session credentials (temporary keys scoped to a single agent run, with the run ID recorded in the audit log) are on the roadmap. This would allow you to query "what did this specific run of the alerts-bot do" rather than just "what did the alerts-bot do." If this use case is critical, plan your robot naming scheme to approximate run-level attribution in the meantime.

Next steps

If you're ready to deploy robots alongside your team's human users: Deploying MCP for your whole team: MDM configuration, server registry, and how robots fit into org-wide deployment

If you need to understand what robots can and can't access: Tool-level access control: how the grant model works and why robots are restricted to shared-mode servers

If you want to see how robots appear in the audit trail: Audit logging for MCP tool calls: what robot tool calls look like in the log and how to query for them

Aptible MCP Gateway gives engineering teams tool-level access control, audit logging, and centralized credential management for MCP without building the proxy infrastructure yourself. Deployed alongside Aptible AI Gateway, it covers both LLM and tool call governance in one place. Join the MCP Gateway waitlist →