Permissions

AgentMesh uses a scope-based permission system inspired by OAuth 2.0, designed specifically for agent-to-agent communication. Scopes define what actions an agent is allowed to perform.

Scope Convention

Scopes follow the pattern:

skill:action[:resource]
SegmentDescriptionExamples
skill Always the literal string skill skill:...
action The operation being performed execute, read, write, admin
resource Optional specific skill or resource translate, summarize, catalog

Examples

skill:execute:translate     → Execute the translate skill
skill:read:catalog          → Read the skill catalog
skill:write:config          → Write configuration data
skill:admin:users           → Administer user settings
skill:execute               → Execute any skill (no resource = all)
skill:read                  → Read any resource

Wildcards

Use * as the resource segment to grant access to all resources within an action:

skill:execute:*    → Execute any skill
skill:read:*       → Read any resource
skill:*:*          → Full access to everything (use carefully)

Wildcards only apply at the resource level. You cannot use wildcards for the action segment — use specific action names.

Delegation Chains

When Agent A asks Agent B to perform work on behalf of a user or another agent, delegation chains track the original requester. This enables audit trails and permission inheritance.

// Agent A requests Agent B to translate on behalf of Agent C
const token = await authority.issueToken({
  subject: "agent:agent-b",
  scopes: ["skill:execute:translate"],
  on_behalf_of: "agent:agent-c",
});

How It Works

  1. Agent C requests Agent A to perform a task.
  2. Agent A needs to delegate to Agent B (a specialist).
  3. Agent A issues a token for Agent B with on_behalf_of: "agent:agent-c".
  4. Agent B can verify the full chain: who originally requested the work.

Token Claims

The resulting JWT includes:

{
  "sub": "agent:agent-b",
  "iss": "https://mesh.coinsenda.ai",
  "aud": "https://api.example.com",
  "scopes": ["skill:execute:translate"],
  "on_behalf_of": "agent:agent-c",
  "iat": 1700000000,
  "exp": 1700003600
}

The on_behalf_of Claim

The on_behalf_of claim is a string identifying the original agent that initiated the request chain. This is useful for:

  • Audit logging: Track who originally requested the work.
  • Permission checks: Verify the original requester has permission.
  • Rate limiting: Apply limits based on the original requester.
  • Billing: Attribute costs to the correct agent/account.

Verifying Delegation

const payload = await verifier.verify(token);

if (payload.on_behalf_of) {
  console.log(`Request from ${payload.sub} on behalf of ${payload.on_behalf_of}`);
  // Check both the direct caller AND the original requester
}

Best Practices

  • Least privilege: Grant the minimum scopes needed. Use specific resources instead of wildcards when possible.
  • Short-lived tokens: Use expiresIn: "15m" for sensitive operations, "1h" for general use.
  • Always verify audience: Set the audience claim to prevent token reuse across different services.
  • Track delegation: Always include on_behalf_of when acting on behalf of another agent, for proper audit trails.
  • Scope naming: Use lowercase, hyphen-separated resource names (e.g. skill:execute:text-to-speech).