The situation

The requests started the way they always do: someone built a proof of concept that summarizes tickets, pulls device health and drafts a reply, and it worked well enough that people wanted it pointed at production. In an MSP, production means the remote management platform that can run scripts on every endpoint, the documentation platform that stores client credentials, and the ticketing system that holds every customer conversation.

Security had two options. Say no and watch the agents get built anyway with a technician’s personal API key pasted into a config file, or publish a short, clear set of requirements and make the safe path the fast one. We went with the second. This post is the generalized version of that handout, with the vendor specifics stripped out, because the pattern applies to any agent you connect to any admin platform.

Why an agent is different

The first instinct is to treat an agent like any other integration: create an API user, scope it, done. That misses what changed. The permissions haven’t changed, but who’s pulling the trigger has.

PropertyTraditional integrationAI agent
Decision logicFixed code you reviewedA model reacting to whatever is in its context
Input trustStructured data from known systemsTicket notes, customer emails, docs and script output, any of which can carry instructions
Speed and volumePredictableCan loop, retry and fan out across every client in minutes
Credential exposureOne service, one secret storeAgent configs, environment files, logs and prompts become new places for keys to leak

The input trust row is the one that matters most. Prompt injection, and specifically the indirect kind where the instructions arrive inside data the agent retrieves, is catalogued as MITRE ATLAS AML.T0051.001 and still sits at the top of the OWASP Top 10 for LLM Applications 2026 as LLM01. In an MSP, anyone who can email a support address can put text in front of your agent.

A useful mental model for leadership: treat the agent like an untrusted junior tech with admin credentials and no judgment about what it reads.

The real risk: blast radius

When we walked through what a single leaked or misused credential could reach on each platform, two scenarios stood out as deal-breakers:

  1. Unattended code execution across the fleet. Remote management platforms run jobs as SYSTEM or root. An over-granted key that can launch a job, or change the variables a script reads at runtime, is a mass-deployment path across every client.
  2. Bulk credential theft. Documentation platforms hold client admin passwords, network diagrams and runbooks. A key with password access is every client’s credentials plus a map of where to use them.

Behind those sat a set of high-rated risks that apply to any platform: injected instructions in returned content, long-lived keys leaking from agent configs, one key spanning every client tenant with no per-client isolation, an untrusted third-party agent server or proxy capturing keys, and a runaway loop exhausting a shared API rate limit and getting your egress IP blocked, which breaks every other integration on that account.

OWASP calls the underlying condition Excessive Agency: an LLM with more functionality, permissions or autonomy than the task needs. It climbed from LLM06 in the 2025 list to LLM03 in the 2026 edition, driven by agentic deployments. Prompt injection gets the model to try something it shouldn’t. Excessive agency decides whether that attempt does any damage. You can’t fully stop the first, so you constrain the second.

Requirement 1: Read-only

The rule is simple: agents read and recommend; people make changes. No create, update or delete calls, for every client and every environment, including the pilot.

Enforce it twice

Don’t trust a single layer. Enforce read-only at the vendor and again at a gateway you control, so a mistake in one is caught by the other.

At the vendor: create a dedicated API identity for each agent with view-only permissions. In practice, platforms differ a lot here:

  • Some offer role-based API users where an “inquire only” role is enforced by the vendor. That’s the clean case.
  • Some have no built-in read-only level, so you build a custom permission set with every item at view and the lowest script or job execution level available.
  • Some issue API keys that are read/write by design. There, the gateway is your only write barrier, so lock the key to the gateway’s egress IP and turn off any password or secrets access on it.

None of the platforms we reviewed could scope a single key to one client, so client isolation has to live in the gateway too.

At the gateway: the agent never talks to vendor APIs directly. It calls tools on a gateway (in most current stacks, an MCP server or proxy) that enforces what the vendors can’t:

ControlWhat it does
Method and path allowlist, deny by defaultEach catalogued tool maps to a fixed method and endpoint pair, almost always GET. Anything else is rejected before it leaves the gateway, then logged and alerted. No generic “make an HTTP request” tool.
Tenant and user filterEach session is scoped to one client that the requesting human is entitled to see. Cross-client queries are blocked.
Rate budgetStay well under the vendor’s account-wide limits so one agent can’t starve other integrations.
Output redactionStrip passwords, license keys and secrets from responses before the model sees them.
Untrusted content handlingReturned text is data. Content never authorizes an action.

The user filter is the one that’s easy to miss. The agent’s vendor identity can see every in-scope client, but the person driving the session usually can’t. Without a check on the human’s own entitlements, a tech scoped to three clients can ask the agent about a fourth. The joint CISA/NSA agentic guidance calls this the confused deputy: a lower-privileged party getting a trusted agent to do what it couldn’t do directly. NIST SP 800-228 makes the same point for APIs generally: every call carries two identities, the calling service and the user it acts for, and both need authorizing.

Tier the tools

Read-only gets easier to defend when people can see where everything else goes:

TierExampleControl
0: ReadDevice status, alerts, tickets, docs (no secrets)Automatic, logged, tenant-filtered
1: SuggestAgent drafts a proposed change and returns it to the technician in the sessionAgent has no write tool; the tech reviews it, files it and makes the change
2: Human onlyRunning jobs, moving devices, resolving alerts, single password lookupsTechnician in the console under their own named account
3: Never exposedAll write methods, password values, account and key managementNot implemented in the gateway and blocked at the vendor

The agent can propose a change. It never holds a credential that can make one, and it never decides for itself when a human needs to approve something. The design makes that call.

Handle credentials like they matter

  • One dedicated identity per agent, per platform. Never a technician’s personal account, never an admin role, never a key shared across agents or environments.
  • Vendor secrets usually show once at creation. Paste them straight into your secrets vault, never into a ticket or chat as a staging step.
  • The gateway reads keys at runtime using its own managed identity. Keys never appear in agent config files, environment files, repos, prompts or tool arguments.
  • No token passthrough: the gateway never hands vendor tokens back to the agent. The MCP security best practices call token passthrough an explicitly forbidden anti-pattern for the same reasons.
  • Prefer short-lived, federated credentials wherever a platform supports them. Where it only offers static keys, rotate on a fixed schedule (we use 90 days), revoke immediately when an agent is retired, and separate duties: the person who creates the key doesn’t build the agent.

Know what you’re plugging in and where the data goes

Three pre-deployment questions sit outside the API permissions entirely, and they’re the ones most often skipped:

  • Where does client data go? Everything the agent reads is sent to a model provider. Before go-live, confirm the provider’s retention and training terms, where the data is processed, and that the contract covers the data in scope. For health data that means a business associate agreement under HIPAA; for CUI it means a provider that meets the FedRAMP Moderate equivalency in DFARS 252.204-7012. If the answer is no, that client is out of scope, whatever the permissions look like.
  • What code is in the path? Third-party agent servers, plugins and connectors are supply chain. Use only vetted sources, pin versions, record a hash of each approved tool definition and re-review when it changes, so a tool can’t quietly change behaviour after approval (a “rug pull”). Never point an agent at a server you can’t inspect that holds your vendor credentials.
  • Can you say what the agent is made of? Keep an inventory record per agent: owner, model and provider, connectors and their versions, the tools in its catalogue and the clients in scope. The UK AI Cyber Security Code of Practice asks for an asset inventory (Principle 5), and the joint agentic guidance goes further with approved tool allowlists and an SBOM-style record for agentic workflows.

Start small. Pilot against an internal test tenant with seeded data, then one low-risk use case, and widen scope only after the logs show the agent behaving as expected. That incremental rollout is the primary structural recommendation in the joint CISA/NSA agentic AI guidance.

Requirement 2: Logged

No logs, no go-live. Every tool call, allowed or blocked, produces one structured event in the SIEM, tied to a human.

What every event needs

{
  "ts": "2026-01-01T12:00:00Z",
  "agent": "ticket-triage-v2",
  "session": "a91f...",
  "user": "tech@example.com",
  "tool": "tickets.get",
  "method": "GET",
  "endpoint": "/tickets/{id}",
  "client": "<client-id>",
  "decision": "allowed",
  "rule": "ro-allowlist-v3",
  "status": 200,
  "records": 1,
  "params_hash": "sha256:..."
}

The user field is the one teams forget most and the one incident response needs most. Without it, every action traces back to a shared service account and attribution during an investigation is guesswork. That’s the same accountability requirement as NIST SP 800-171 3.3.2 (AU.L2-3.3.2 in CMMC): actions must be uniquely traceable to individual users.

Never put secrets in any log: API keys, tokens or password values. Keep the SIEM event lean as well: hash the parameters so you can correlate calls without copying client data into the SIEM.

That doesn’t mean throwing away the context. Current guidance expects you to be able to reconstruct why an agent did something, not just what it called. Keep the full session record (prompt, tool calls, tool output and the agent’s response) in a separate, encrypted, access-controlled store under the same retention as the SIEM, keyed by session. The SIEM event tells you which session to pull; the transcript tells you what the agent was looking at when it made the call.

Pipeline and retention

  • Gateway events, plus each vendor’s own activity or audit logs and the vault’s secret-access events, all land in the SIEM. The vendor logs are an independent record, not something the agent or gateway reports about itself, which is what the joint agentic guidance asks for when it recommends cross-checking agent activity against separate monitoring.
  • Delivery within about a minute; retention matched to the strictest compliance requirement in scope.
  • Append-only and SIEM-managed: builders can read their logs but can’t delete them.
  • Clocks in UTC, synced to an authoritative time source.
  • If the gateway goes quiet for a set window, that’s an alert, not a relief.

Publish the detections

Telling builders what trips an alert up front is part of not being a blocker:

SeverityDetectionResponse
HighAny write-method attempt, even when blockedSession reviewed same day; agent paused if unexplained
HighVendor key used from anywhere but the gatewayKey revoked and rotated; IR process opened
HighGateway stops sending logsAgent traffic suspended until logging is restored
HighAgent identity’s vendor role, permissions or key changed outside change controlChange reviewed; reverted and key rotated if unauthorized
MediumCross-client queries in one sessionSession reviewed; tenant filter checked
MediumVolume spike or rate-limit responsesBuilder contacted; rate budget tuned
LowInjection-style strings in returned contentLogged for trend review; source record flagged

Verification

Every agent goes through the same gate before it touches client data, with evidence attached to the intake request.

First, prove a write is refused. Run this through the gateway with the agent’s own session, and run the equivalent call against each vendor API with the agent’s vendor credential:

# Attempt a write through the gateway; it should be refused and raise a High alert
# $token = the agent's own gateway session token (never a vendor key)
$uri  = "https://<gateway>/tools/tickets"
$body = @{ summary = "agent-write-test" } | ConvertTo-Json
try {
    Invoke-RestMethod -Method Post -Uri $uri -Body $body -ContentType "application/json" `
        -Headers @{ Authorization = "Bearer $token" }
    "FAIL: write was accepted"
} catch {
    if ($_.Exception.Response) {
        # Expect 403 (or 405) and a matching blocked event in the SIEM
        "Status: {0}" -f [int]$_.Exception.Response.StatusCode
    } else {
        "No HTTP response: $($_.Exception.Message)"   # network/TLS error, not a pass
    }
}

Then the rest of the checklist:

AreaCheck
AccessDedicated read-only identity per platform; write test returns 403 everywhere; gateway allows GET on catalogued endpoints only
AccessA call with the vendor key from a non-gateway IP is rejected (where the platform supports IP restriction)
AccessA test user asks about a client outside their entitlements and the gateway refuses
SecretsKeys in the vault with expiry, owner and ticket tags; none in configs, repos, prompts or tickets
LoggingTest call appears in the SIEM with every required field; blocked write raised a High alert; vendor activity logs flowing; session transcript retrievable by session ID
DataModel provider terms reviewed for retention, training and processing location; agreements in place for regulated data in scope
Supply chainAgent servers and connectors from vetted sources, versions pinned, approved tool definitions hashed; inventory record complete
SafetyPrompt-injection test pack run in the sandbox tenant; kill switch drilled (revoke key, stop gateway); IR playbook updated for agent compromise; owner named

How this lines up with published guidance

None of this is new invention. It’s the existing least privilege, logging and supply chain controls, applied to a new kind of principal. The joint CISA/NSA/Five Eyes guidance, Careful Adoption of Agentic AI Services, groups agentic risk into five categories, which makes a handy coverage check for a first review:

Risk categoryCovered here by
PrivilegeRead-only identity per agent, enforced at vendor and gateway; user entitlement check against confused deputy; tool tiers; alerts on privilege changes
Design and configurationGateway allowlists and tenant filter; credential handling; provider, supply chain and inventory review before go-live
BehaviourAgent can’t act, only propose; injection test pack; rate budget; humans decide when approval is needed
StructuralGateway as the single path; rate budgets protecting shared integrations; kill switch
AccountabilityOne event per call tied to a human; session transcripts; vendor logs as an independent record; append-only retention; published detections

The rest of the government guidance points the same way:

GuidanceWhat it adds for a first reviewCovered here by
NSA, MCP security design considerations (May 2026)Least privilege at the tool-call boundary, vet servers before trusting them, treat tool output as untrusted, log every tool call with the identity behind itGateway allowlists; supply chain review; untrusted content handling; per-call events
NSA/CISA and partners, Deploying AI Systems Securely (April 2024)Secure exposed APIs, strict access control with MFA for administrators, validate before deployment, robust logging, audits and penetration testingGateway hardening callout; verification gate
UK DSIT/NCSC, AI Cyber Security Code of Practice (now ETSI EN 304 223)Human responsibility, asset inventory, supply chain, testing, monitoring system behaviour, secure disposal at end of lifeTool tiers; inventory record; checklist; detections; retirement caveat
NIST, SP 800-228 API protection (June 2025)Gateways as enforcement points; authorize both the calling service and the user it acts for; rate limitingGateway design; user filter; rate budget
NIST NCCoE, agent identity and authorization concept paper (Feb 2026, draft)Distinct agent identities, binding agent actions to the human who delegated them, tamper-resistant loggingDedicated identity per agent; user field; append-only logs

NIST’s SP 800-53 control overlays for AI agent systems are still in development, so for now the mapping runs through the existing controls listed under Caveats.

What this post doesn’t cover: multi-agent designs, where one agent’s output becomes another’s input, and agents with persistent memory. Both add risk categories (see the OWASP Top 10 for Agentic Applications) and deserve their own review.

Caveats

  • Vendor permission models drift. Settings get renamed and new endpoints ship. Confirm the current options in each admin console before relying on them, and rerun the write test after vendor updates.
  • Read-only is not harmless. A read-only agent can still leak data through its own output or be steered into a misleading recommendation. Redaction, tenant filtering and the human in the loop for Tier 1 changes carry that weight.
  • Not every read is a GET. Some vendor search and reporting APIs use POST for queries. Allow those as specific method and endpoint pairs in the catalogue rather than loosening the method rule, and confirm at the vendor that the identity can’t write anyway.
  • Compliance evidence. The access and logging controls map cleanly to least privilege (NIST SP 800-171 3.1.5), audit logging and user accountability (3.3.1, 3.3.2), audit protection (3.3.8) and time sync (3.3.7). The same artifacts serve SOC 2 and HIPAA audit-control evidence. Retention values have to match each client’s requirement, not one internal default.
  • People over-trust fluent answers. A recommendation that reads well isn’t verified. Tell technicians that agent output is a starting point, that they never paste secrets into a session, and how to report an answer that looks steered.
  • Plan the exit. Retiring an agent means revoking its keys, removing its tools from the catalogue, closing its inventory record and disposing of its transcripts on the retention schedule. The UK Code treats end of life as its own principle for a reason.
  • Risk acceptance. If a team needs an agent that writes, it doesn’t get a write-capable key. It gets a Tier 2 design review, a named owner and a documented risk acceptance, with a human approval step on every action.

Key takeaways

  1. An AI agent is a new privileged user that reads untrusted text at machine speed. Threat-model it like one.
  2. You can’t fully prevent prompt injection, so limit what a successful injection can do: read-only, enforced at the vendor and again at the gateway, with per-client and per-user scoping in the gateway because vendors rarely offer it.
  3. Before the first call, know where client data goes (model provider terms and agreements) and what code sits in the path (pinned, vetted connectors).
  4. Every call gets logged with the human behind it, and the session can be replayed. No logs, no go-live.
  5. Make the secure path the fast path: a tool catalog, a sandbox, a short checklist and published detections get you more compliant agents than a policy that says no.

References