All Posts

Where agent permissions come from

Agent permissions need a trusted source. The org, agent identity, scopes, session, and delegation chain should come from authenticated platform state. They should not come from the same request body that may contain model output or untrusted input.

Trusted permission source

In AgentTrust ID, the org comes from the authenticated API key, token, or runtime credential. Agent identity comes from the registered agent and the credential path. Session scope comes from session creation, token scope, or delegation. The tool call supplies the requested action, but it does not decide the caller's rights.

This gives the authorization check a stable subject: this agent, in this org, in this session, with this scope ceiling.

Request body risk

If the body can name the org, agent, or scope, then a compromised agent can try to grant itself a better story. A prompt injection can ask the model to send agent_id=admin-agent. A bad tool wrapper can pass a tenant from model output. A delegated worker can claim the parent's full scope.

Those values have to be resolved before the model-controlled payload gets a vote.

Platform-derived identity example

This Python flow uses the org API key from the environment, issues an opaque agent token, introspects it, and then checks an action for the agent returned by introspection.

from agenttrustid import AgentTrustClient

client = AgentTrustClient.from_env()

agent = client.agents.create(
    name="reporting-agent",
    framework="custom",
    capabilities=["tickets:read", "reports:write"],
)

token = client.tokens.issue(
    agent_id=agent.id,
    scopes=["tickets:read"],
    ttl_seconds=300,
)

token_info = client.tokens.introspect(
    token.token,
    required_scopes=["tickets:read"],
)

if not token_info.active:
    raise PermissionError("inactive agent token")

decision = client.actions.check(
    agent_id=token_info.agent_id,
    tool_name="tickets:read",
    tool_input_summary="Read ticket counts for the weekly report.",
    action_effect="read",
)

if not decision.allowed:
    raise PermissionError(decision.reason)

The token result identifies the agent. The API key identifies the org. The body does not select a tenant or invent a scope.

Prevention

Resolve identity and scope from credentials and server-side records. Reject cross-agent session reuse. Refuse tools outside the session ceiling. Treat caller-supplied identity fields as request data, not authority.

AgentTrust ID has a session owner check for this. If a session belongs to agent A and a request explicitly claims agent B, the unified checker denies the request and records the reason.

Solving this with AgentTrust ID

AgentTrust ID ties action checks to org-scoped API keys, opaque token introspection, WIMSE workload identity, DPoP-bound runtime requests, sessions, and delegations. Each layer narrows the facts the model can influence.

This is the base layer for the rest of the series. Prompt injection can change what the model asks for. It should not change which org the agent belongs to, which agent identity is authenticated, or which tools the platform recorded.

Try the pattern

AgentTrust ID resolves org, agent, session, and scope from credentials and server-side records. Treat caller-supplied identity fields as request data and let the platform derive authority.