AgentPAM.ai

AI Privileged Access Control Plane

The control point is the credential,
not the approval prompt.

In every high-impact MCP incident so far, the tool call was one the agent was authorized to make. The damage came from the scope and lifetime of the credential the MCP server was holding.

AgentPAM gives every AI agent a first-class identity, binds it to an accountable human sponsor, and issues short-lived, task-scoped, sender-constrained credentials — and the agent never sees them.
Up front: MCP Gateway — you already have one IdP — you already have one prompt-injection defense — we only degrade it

Token Ladder · RFC 8693

A four-step ladder that narrows at every hop

Illustrative · 40× accelerated clock
  1. [1]
    Tu Human → your IdP (Okta / Entra / Google)
    OIDC id_token · scope = this person's full session under your policy
    1h 00mTTL
  2. [2]
    Ts Agent → AgentPAM, RFC 8693 token exchange
    sub=human · act={agent_instance} · cnf.jkt (DPoP) · authorization_details=[agent_task]
    15:00TTL
  3. [3]
    Tup Your gateway → AgentPAM, exchanged for the upstream credential
    Header-injected into the upstream API · unbound · the highest-value thing on the chain, so the shortest-lived
    3:00TTL
    THE AGENT NEVER SEES THIS ROW
  4. [4]
    Ts′ Sub-agent delegation — re-runs [2], does not follow [3]
    scope ⊂ parent Ts scope (strict subset enforced) · TTL ≤ parent Ts 15:00 · act chain nests
    5:00TTL
Width = scopeEvery hop may only get narrower and shorter-livedNo bare bearer tokens: DPoP RFC 9449 binding

The TTL ladder is asymmetric on purpose: Ts is DPoP-bound and re-checked against policy on every call, so a stolen copy is waste paper without the private key — it can afford to live longer. Tup is an unbound upstream credential that works for whoever holds it — so it must be the shortest-lived thing on the chain. See the full claim design →

The empirical argument

There is no server-side patch, because the PAT's scope itself is the vulnerability.
  • GitHub MCP — prompt injection exfiltrated private repositories
  • Supabase MCP / Cursor — data leaked through an authorized query path
  • Asana MCP — cross-tenant data exposure
  • Salesloft Drift → Salesforce — OAuth tokens stolen
  • Nx — malware drove the coding agent itself to hunt for secrets

Line these up and you get a counter-intuitive but consistent conclusion: none of them was a memory-safety bug, and none of them was a missing approval prompt. In each case the tool call was inside the agent's authorized scope. What turned it into a disaster was that the credential was too broad and lived too long.

That fixes where the control point has to be. Prompt-injection defenses, tool-description pinning, approval dialogs — all of them sit above the credential. They can stop the agent from asking; they cannot stop the credential from working. A poisoned tool description, a compromised npm version, and an infostealer reading ~/.claude.json all reach the same static PAT, and none of them passes through a PreToolUse hook.

Put the other way round: if the credential never lands on the laptop, tool poisoning degrades from “exfiltrate the entire private repository” to “make one authorized, logged, revocable call.”

— that single sentence is the whole design premise of AgentPAM

The problem

Identity collapse

Today, everything identifying an AI agent to a sensitive API is one long-lived API key sitting in a dotfile. That static string flattens four dimensions into a single value.

which humanhuman
which instanceagent
for what tasktask
at what momenttime
flattened
"ghp_xxxxxxxxxxxx"

Every downstream control — authorization, audit, revocation — is built on that string, so all of them lose resolution. The target API's log can only say “some token called me.” It can never answer “whose agent, which one, for what task.”

Evidence

  • > 2/3of enterprises cannot cleanly distinguish AI agent actions from human onesCSA survey
  • 88%of security decision-makers define “privileged user” as humans onlyIndustry survey
  • 79%of MCP servers store credentials in plaintext; only 8.5% use OAuthMCP ecosystem scan

These are third-party survey figures, not our own measurements. Verify the sources before citing them.

Self-diagnosis

Eight challenges in AI agent access

This taxonomy is written in customer language. Count how many you recognise — then read our answer, and how far our coverage actually goes.

  1. 1

    Uncontrolled OAuth Permissions

    Maximal grants nobody scoped

    Our answerRFC 9396 RAR authorization_details expresses fine-grained authorization; MCP incremental scope consent (requested mid-flight via WWW-Authenticate) means no maximal grant up front.

    Covered
  2. 2

    Human-Equivalent Agent Access

    The agent inherits everything the person has

    Our answerThe agent receives a strict subset of that person: granted_capabilities ⊆ blueprint ceiling, with the act chain narrowing monotonically. The agent is never equivalent to the human behind it.

    Core capability
  3. 3

    Opaque Agent Actions & Decisions

    You cannot tell what the agent did or why

    Our answerAudit carries task.purpose and sensitivity — we actively collect declared intent rather than passively recording traffic, and bind every call to that declaration.

    Partial coverage
  4. 4

    Standing Tokens & Secrets

    Long-lived credentials sitting on disk

    Our answerTier 0 credential custody plus the four-step TTL ladder (Tup 60–300s). There is no standing token because the agent never received one.

    Core capability
  5. 5

    Lack of Auditability & Traceability

    The log cannot answer who did what

    Our answerA vendor-neutral event schema (human / agent / blueprint / task / tool / resource / decision / obligations / delegation chain), correlated by W3C Trace Context, with hash-chained tamper evidence.

    Covered
  6. 6

    Inconsistent Guardrails Across Tools

    Every platform enforces differently

    Our answerA single policy plane across IdPs and clouds. Entra governs the agents inside Entra, AgentCore governs the ones inside AWS — nobody governs all of them.

    Differentiator
  7. 7

    User-Driven Agent Connections

    Developers wire up their own agents

    Our answerEMA / ID-JAG moves consent and policy decisions from the end user to the enterprise IdP — no OAuth consent screen, no shadow connections, one revocation point.

    Open gap
  8. 8

    Privilege Creep in AI Workflows

    Scope only ever grows

    Our answerMonotonic narrowing (scope can only shrink) + lifecycle_binding (the task terminates and credentials die without waiting for the TTL) + no scope expansion along the chain.

    Differentiator
The real boundary on #3 — a line we will not crossThe transcript that explains why an agent acted lives in the client, not on the wire. From the broker / gateway position we can record what was done; we cannot record why. What we can do is require the agent to declare its intent when it opens a task, then bind every call to that declaration — which lets an auditor ask “does this call match what it claimed to be doing”. But that is not ground truth about the reasoning. We will never claim full decision explainability, and we will not say we can explain the agent's reasoning — that would be a false security claim.
#7 is also an open question we have not settledThe flip side of user-driven connections is what to do about unregistered agents, and we have not settled it. Deny and you are safe, but developers route around us or uninstall — which kills adoption. Allow and adoption is smooth, but you have left a hole. Our current leaning is a quarantine blueprint — auto-allow an unregistered agent at minimum privilege, alert, and prompt registration, turning a security event into a registration path. This is our current thinking, not a shipped feature, and it still needs validation with real customers.

Why classic PAM does not carry over

Three variables PAM never had to face

PAM has done session recording and time-boxed checkout for twenty years. It does not carry over to AI agents — not because it was done badly, but because three things are missing from its threat model.

Non-determinism

The next action is decided by inference

CI jobs and microservices can be enumerated and allowlisted ahead of time. An AI agent's next action is decided by the LLM at runtime. Policy cannot just say “may call X” — it has to be able to judge intent at runtime.

Prompt injection = confused deputy

The agent is a hijackable deputy

Anything the agent reads — a web page, an issue, a log, the return value of the previous tool — may be attacker-authored instructions. So the agent's authorization cannot equal the authorization of the credential it holds. Classic PAM has no such case.

The missing middle of delegation

There is no attenuated persona

An agent acts on someone's behalf, but is not that person. Classic PAM has only “user” and “service account” — there is no attenuated, scoped, time-boxed persona in between.

How we put itAn AI agent is not a new identity type. It is a new shape of authorization chain. A human is chain length 1 with self-evident intent; a machine is chain length 1 with intent known at compile time; AI is chain length ≥ 2 with an autonomous middle node whose intent is only known at runtime. The job is to make every hop of human → delegates to → agent instance → brokered to → workload credential verifiable, attenuable, revocable, and auditable.

Identity model

Three object layers: type, instance, session

“Short-lived tokens” and “durable agent identity” are not an either/or — they live at different layers. The instance persists to carry policy, sponsor, and audit history; the session is minted per task to carry on-behalf-of and task scope.

AgentBlueprint

Durable · type/template

What this kind of agent is and the most it may ever request. Credentials hang off the blueprint, not off the instance.

  • publisher / verified_publisher
  • model {provider, name, version}
  • declared_capabilities [] — capability ceiling
  • credential_ref — the credential lives here

AgentIdentity

Durable · authorization subject

A stable, addressable registered instance. The sponsor is mandatory and must be a human, so orphan agents cannot exist by construction.

  • sponsor → HumanIdentity (mandatory)
  • owner → HumanIdentity (optional)
  • granted_capabilities ⊆ declared
  • state active | disabled | soft_deleted

AgentSession

Ephemeral · minted per task

Never persisted as an identity object. The human binding is a claim on the session, not an attribute of the identity — the same instance may run autonomously, or act for different people at different moments.

  • on_behalf_of → Human | null
  • task {id, purpose, sensitivity}
  • delegation_chain [] — monotonically narrowing
  • binding {dpop | mtls, jkt}
  • lifecycle_binding {task_id, …}
How we relate to the NHI (Non-Human Identity) categoryWe belong in the NHI category. Agent instances, blueprints, lifecycle, orphan governance, ownership attribution — all of it is NHI vocabulary and methodology, and we inherit it directly. But the crux is that what we do is a composite of NHI and human, not pure non-human. The accurate self-description is “NHI done as a delegation chain”: human (sub)agent instance (act)upstream credential — mandatory sponsor, strict subset, never landing on the agent. The word “non-human” must not crowd out the fact that the human is still in the chain — the entire force of the SOC 2 CC6.1 / CC6.6 attribution argument comes from being able to trace back to a person.
Why the human binding must live on the sessionBinding “on whose behalf” to the identity layer is semantically wrong, and it fails both ways: either you clone an instance per person (combinatorial explosion) or you lose the on-behalf-of relationship entirely (a broken audit chain). We also distinguish subject types explicitly from day one — an agent and a human must never present as the same idtyp in a token.

Where we sit

Your gateway is the Resource Server. We are the Authorization Server.

The MCP authorization spec already split Resource Server from Authorization Server. We are natively that AS — this is not a wedge, it is the integration point the spec defines.

deployment.txtscrolls horizontally
  Human ---- SSO / OIDC ----> Your IdP  (Okta / Entra / Google)
    |                              |
    | launches                     |  Tu   id_token, TTL ~1h  (your policy, not ours)
    v                              |
  +-----------------------------+  |
  | Agent host process          |  |
  |  Claude Code / Cursor /     |  |
  |  Codex / in-house framework |  |
  +--------------+--------------+  |
                 | MCP (stdio | HTTP)
                 v                 |
  +-----------------------------+  |
  | AgentPAM Local Attestor     |<-+   V2 . user-space only . heuristic
  |  process + device signals   |
  |  Secure Enclave device key  |
  |  DPoP per-request signature |
  |  strips creds from the env  |
  +--------------+--------------+
                 v
  +-----------------------------+
  | YOUR MCP Gateway            |   Resource Server -- yours. We do not build one.
  +--------------+--------------+
                 | RFC 9728 AS delegation | RFC 8693 token exchange | ext_authz
                 v
  +=========================================================+
  |  AgentPAM control plane   (your Linux, air-gap capable)   |
  |    Identity registry   Blueprint / Identity / Session   |
  |    PDP                 AuthZEN + COAZ, per-tool/param   |
  |    Credential broker   RFC 8693 exchange, DPoP-bound    |
  |    Audit spine         OCSF + W3C Trace Context         |
  |    CAEP consumer       revoke inside one token TTL      |
  +=============================+===========================+
                                | Tup  60-300s, header-injected
                                v *** THE AGENT NEVER SEES THIS ***
                 +-----------------------------+
                 | Sensitive API               |
                 |  GitHub / Postgres / AWS /  |
                 |  Snowflake / internal SaaS  |
                 +-----------------------------+
We own only the control plane inside the ==== box. The IdP is yours, the gateway is yours, the upstream APIs are yours. The Local Attestor is an optional pure-userspace component whose attestation signal is heuristic. see the security model
Layer ① confusion

“Chat with your PAM”

Wrapping an existing product in an MCP server. Security value: zero. We have to say up front that we are not this layer, or we get filed under noise.

Layer ②

Agent discovery and governance

Pointing IGA at an agent inventory. Genuinely useful, and it is our V1 wedge — but it counts things; it does not intercept them.

Layer ③ · we are here

Runtime brokering of agent → resource access

On the request path: verify identity per call, evaluate policy, inject the credential, write the audit record, and be able to say no. This is the only position that can enforce per tool call.

Integration

Configuration, not engineering

RFC 9728 requires the gateway to publish authorization_servers, and the spec permits that AS to be external — so on gateways that support pointing it outward, adopting us is a configuration change. To be clear though: the spec does not require that AS to be external, and a gateway may be its own AS, so this path is not universal. Of 12 gateways tested, 4 support it cleanly.

  1. Publish /.well-known/oauth-protected-resource with authorization_servers pointing at your AgentPAM instance.Required by RFC 9728
  2. Return a WWW-Authenticate header pointing to it on 401. ⚠️ As of the 2025-11-25 spec (SEP-985) this step is optional — clients may fall back to .well-known discovery.
  3. Validate the tokens we issue (JWKS + audience).Required by RFC 9728
  4. Point the gateway's backendAuth.oauthTokenExchange.path at our token endpoint. This is the only genuinely new piece of configuration. (The local YAML key is path; tokenEndpointPath is the xDS/proto field name and will fail to load in a config file.)
Fallback A

Gateway has authorization hooks but no AS delegation

We implement the AuthZEN / COAZ-MCP PDP interface and register as an external authorizer (gRPC guardrails or Envoy ext_authz), injecting credentials via header mutation on allow. Cost: we see the request but do not own token issuance.

Fallback B

Opaque gateway with no hooks at all

We sit as an upstream MCP server proxied by your gateway, becoming the policy enforcement proxy in front of the real tools. Cost: an extra hop, and we only see traffic routed to us. Benefit: zero requirements on your gateway.

The compatibility matrix and per-gateway test status are on the architecture page — most rows are still marked “not yet tested,” and we will not write an untested row up as verified. See the compatibility matrix →

Enforcement tiers

Tiered enforcement, starting from credential custody

We do not ship every enforcement layer at once. The practical reason: OS-level enforcement needs kernel extensions, MDM push, and security-team sign-off, and developers will not self-install that — and developers are the first users. The deeper reason: Tier 0 already absorbs most bypass scenarios in principle.

TIER 0

Credential custody — the credential never reaches the agent

The decisive control point. If the agent holds no credential, going around us and calling curl directly gets it nothing. In principle this absorbs most of Tier 3's value.

V1
TIER 1

Per-tool-call authorization + audit for MCP

The main control surface. Deny by default: any tool call not explicitly permitted by policy is refused, and fail-open is prohibited. Granularity at server level, tool level, and parameter level.

V1
TIER 2

Egress backstop (loopback proxy + CA injection)

Catches residual credentials and the engineer's pre-existing credentials~/.aws/credentials, kubeconfig, the things already on the machine that never go through MCP.

V1.5
TIER 3

OS-level enforcement (eBPF / Endpoint Security Framework)

Answers the “non-MCP actions fall outside policy” competitive attack. That is an enterprise-stage problem, not a V1 problem.

V2 Enterprise

Deployment posture

The whole control plane runs in your data centre and never calls home

This is not a deployment option, it is a hard constraint. Credential custody means this control plane holds the keys to all of your sensitive APIs — those keys should not leave your network boundary.

C-13

Fully private, air-gap capable

The control plane runs in your own Linux environment and requires no outbound cloud access. Any feature that would only work via our SaaS does not get built.

C-14

Containerized delivery

OCI images + Compose / Helm. Minimal base image, runs non-root, read-only root filesystem, explicit capability set and network policy — because your security team will audit the image.

C-15

No telemetry, no phoning home

No telemetry, no online licence checks, no auto-update callbacks. Licences are offline signed files; updates are images you pull deliberately. Any “calling home” behaviour is an incident at an air-gapped customer.

The consequences that follow — listed here because they are real costs

Single tenant, therefore simpler
No multi-tenant isolation, no cross-tenant leakage defenses, no per-tenant quotas. The architecture gets materially simpler and the attack surface smaller.
Root keys can live in your own KMS / HSM
The broker holds the keys to all your sensitive APIs, so it must support holding root keys in your KMS / HSM over PKCS#11. A software-key mode is explicitly labelled as a lower assurance tier.
We cannot see your logs
Supportability lives or dies on a one-command redacted diagnostic bundle (configuration, versions, health metrics, redacted error logs) that you review before sending. We will never ask you to open inbound access.
Process attestation is weaker when air-gapped
The Local Attestor depends on code signing and notarization identity, and Apple's online notarization check is unavailable without outbound access. The offline path is local static signature verification (Team ID, signing chain, hardened runtime) plus stapled-ticket validation. We label which tier the attestation is in rather than pretending there is no difference.
60-second TTLs collide with clock drift
Air-gapped environments often lack external NTP, and tens of seconds of drift between hosts is normal — enough for a credential to expire on issue. The control plane checks cluster clock skew at startup and warns, defines an explicit tolerance window, and fails closed with an explicit error when skew exceeds the threshold — never silently allowing.
No cloud threat intelligence
Malicious MCP server reputation and tool-description poisoning signatures cannot be updated live when air-gapped. They become signed offline policy bundles you import deliberately, with the intel version and date shown in the interface — you have to know how stale you are.

One structural consequence is worth saying plainly: any approach that presupposes a public-cloud bundle simply does not exist as an option in an air-gapped environment. That is not a claim about who is better; it follows from the deployment shape.

What ships

Four deliverables

Customer-side endpoints open source, control plane commercial. Discovery and attribution first, enforcement second — because nobody buys enforcement for a population they cannot count.

① V1 wedge · open source

Collector

Read-only CLI / lightweight daemon. One docker run, connected to nothing, producing: how many agents exist, what credentials each holds, what they touched last week, and which are unattributable under SOC 2 CC6. Zero blast radius.

② V1 · commercial · runs in your data centre

Portal + control plane

An OCI container group deployed on your own Linux — not SaaS. Identity registry, policy editing, audit views, auditor-ready reports, and approval-fatigue metrics — an approval rate approaching 100% is a rubber-stamp signal.

③ V1.5 · adapter layer open source

PDP / Credential Broker

A service inside the same container group. Per-call policy decisions and RFC 8693 token exchange; credentials are held here and injected per request. Target P99 latency < 200ms.

④ V2 moat · partially open source

Local Attestor

A code-signed daemon. It cannot be an SDK — an SDK runs inside the process being attested, so it would be attesting itself, which is logically void; and the credential has to be held outside the agent process.

Pricing principleNot priced per agent. Agents are ephemeral and get spawned by the thousand; per-agent pricing pushes customers to merge agents to lower the bill, which is a security anti-pattern. We price by protected resource / policied integration, with unlimited agents.

Boundaries

What we are not

This section is here because it is more useful to you than to us. If we were vague about any line below, your team would catch it in the second meeting.

Not an MCP Gateway
You already have one, and that layer is already commoditized. We plug into your gateway; we do not replace it. Any design that asks you to swap out your gateway is our failure.
Not an IdP
You already have SSO. Human authentication is always delegated to Okta / Entra / Google — we only consume their assertions. We do not store human passwords and we do not do MFA.
We did not invent agent identity
Mainstream IdPs already ship an agent object model, sponsors, conditional access, risk detection, and an audit schema. We do not fight those head-on — we work the seam between them: nobody owns the cross-IdP, cross-cloud stretch, and structurally nobody is incentivized to.
We cannot prevent prompt injection
We cannot stop an authorized call. We can do exactly three things: degrade its impact (narrow scope, short lifetime), record it (attributable to human + agent + task), and make it revocable (invalid within one token TTL). Any product claiming to “prevent prompt injection” is over-promising.
Local process attestation is not hardware remote attestation
There is no usable root of trust on a laptop: macOS has essentially no TPM, Apple App Attest is an iOS-family API that does not support arbitrary macOS CLI processes, and SPIFFE collapses here into UID plus binary path. Our attestation is a composite heuristic and defense in depth. We will publish its bypass cost; we will not describe it as hardware attestation.
We do not use the EU AI Act as a sales argument
“The EU AI Act mandates logging of AI agent privileged actions” is a misreading of the regulation — Article 12 binds providers of high-risk systems, and the high-risk obligations have been deferred. Our compliance argument rests on things that hold today: the attribution requirements of SOC 2 CC6.1 / CC6.6, and ICT risk-management obligations under DORA for financial entities.
We are ourselves a new high-value target
AgentPAM holds the keys to every sensitive API. One compromised intermediary equals every downstream system compromised — exactly the shape of the Salesloft Drift incident. We put this first in the threat model, not last.