Skip to main content

Developer Tools

Two open-source packages for integrating WardenAuth RBAC into MCP-based AI agents — a lightweight client library for your agent code, and a deployable gateway proxy for your AWS infrastructure.

@ecarrizo/mcp-agent-guard​

A drop-in TypeScript library for minting downscoped session tokens, filtering RAG retrieval by access, and intercepting MCP tool calls with deny-wins RBAC.

npm install @ecarrizo/mcp-agent-guard

Mint a downscoped session token​

Issues a short-lived st1.* Bearer token scoped to specific permissions. The token physically cannot exceed the listed permission set.

import { guardSession } from '@ecarrizo/mcp-agent-guard'

const gate = await guardSession({
apiUrl: 'https://api.wardenauthz.com',
apiKey: 'bsk_live_...',
permissionIds: ['github-read', 'slack-read'],
ttlSeconds: 300,
})

// gate.token → st1.eyJ... Bearer token
// gate.headers → { Authorization: 'Bearer st1.eyJ...' }
// gate.jti → unique ID for audit correlation and revocation

Filter RAG retrieval by access​

Wrap any vector store to filter results through access control. Each candidate is checked as resource: {resourceType}:{id} with action: read.

import { createGuardedRetriever } from '@ecarrizo/mcp-agent-guard'

const guarded = createGuardedRetriever({
client: { apiUrl: '...', apiKey: '...' },
subjectId: 'agent-1',
scopeId: 'org_acme',
resourceType: 'document',
})

const docs = await vectorStore.search('quarterly revenue')
const allowed = await guarded.filter(docs)
// allowed contains only documents agent-1 has read access to

Intercept MCP tool calls​

Check or bulk-check tool calls against RBAC permissions before execution.

import { createGuardMiddleware } from '@ecarrizo/mcp-agent-guard'

const guard = createGuardMiddleware({
client: { apiUrl: '...', apiKey: '...' },
subjectId: 'agent-1',
scopeId: 'org_acme',
})

const permissionMap = {
github_list_issues: { resource: 'github', action: 'list' },
github_create_issue: { resource: 'github', action: 'write' },
slack_post_message: { resource: 'slack', action: 'write' },
}

const { allowed } = await guard.check('github_create_issue', permissionMap)
if (!allowed) throw new Error('Forbidden')

MCP client config builders​

Generate ready-made configs for Claude Desktop, Cursor IDE, and generic MCP clients using a downscoped token.

import { buildClaudeDesktopConfig, buildCursorConfig } from '@ecarrizo/mcp-agent-guard'

// Claude Desktop
const claudeConfig = buildClaudeDesktopConfig(gate, 'github', 'https://api.githubcopilot.com/mcp/')

// Cursor IDE
const cursorConfig = buildCursorConfig(gate, 'github', 'https://api.githubcopilot.com/mcp/')

Revoke a token​

const client = new WardenAuthClient({ apiUrl: '...', apiKey: '...' })
await client.sessionTokens.revoke(gate.jti)

mcp-gateway-template​

An SST-deployable MCP proxy for your AWS account. Deploy one Lambda per MCP server, each enforcing RBAC on every tool call before it reaches upstream.

npx create-warden-auth-mcp-gateway my-gateway
cd my-gateway
npm install

How it works​

Every tool call passes through enforcement:

  • Authentication — every request requires x-api-key. The gateway resolves agent identity (principalId + scopeId) from the key.
  • Tool permission enforcement — tools/call is intercepted. The gateway looks up the tool permission map, extracts context fields from arguments, and calls access.hasAccess().
  • ABAC — context fields from tool arguments are passed to access checks. Example: allow query on QA database, deny on production.
  • Rate limiting — per-key (default 600 req/min) and per-IP (default 1000 req/min).
  • Intent-bound tokens — when an agent presents a Bearer st1.* token, the gateway verifies the call is within the agent's bound intent.
  • All other MCP methods (tools/list, resources/list, prompts/list) pass through unmodified.

Define your servers in YAML​

# config/mcp-servers.yaml
mcpServers:
- name: postgres-readonly
upstreamUrl: 'https://postgres-mcp.internal.example.com/mcp'
upstreamApiKey: 'sk_postgres_mcp_key'
authMode: static
toolPermissions:
postgres_query:
resource: 'postgres'
action: 'query'
contextFields: ['database', 'table']
postgres_list_tables:
resource: 'postgres'
action: 'list'
defaultPermission:
resource: 'postgres'
action: 'execute'

Bootstrap RBAC​

# Discover which permissions are needed
npm run scaffold

# ═══════════════════════════════════════════════════
# Permission Tools
# ───────────────────────────────────────────────────
# postgres:query postgres_query
# postgres:list postgres_list_tables
# ═══════════════════════════════════════════════════

# Auto-create permissions in WardenAuth (skips existing)
npm run scaffold-create

Deploy​

npx sst deploy --stage production

Auth modes​

ModeBehaviour
staticGateway uses a shared upstreamApiKey from secrets. All agents share the key.
forwardForwards agent's Authorization, x-api-key, and Cookie headers to upstream.

GitHub Actions CI/CD​

The template includes a .github/workflows/deploy.yml that deploys on push to main or manual trigger with stage selection (production/staging/dev).


When to use which​

Use caseUse
Adding RBAC to an existing agent/script@ecarrizo/mcp-agent-guard
Building a secure RAG pipeline@ecarrizo/mcp-agent-guard
Deploying a managed proxy in AWSmcp-gateway-template
Enforcing RBAC at the infrastructure layermcp-gateway-template
GitOps-managed MCP server fleetmcp-gateway-template

Both packages work together — use the gateway template for infrastructure-level enforcement, and the agent guard for per-agent token downscoping and RAG filtering.