Control agent access to tools, APIs, and data

See every action your agents take. Know exactly who authorized it.

and ask: "Who accessed prod last night"
AGENT
api.ts
retry.ts
+2 files

Fix the rate limit bug in production. Check Datadog for the errors, file a Linear issue, and push the fix to GitHub.

S

On it. I'll need access to three services:

Fetch error logs from Datadog
VIA KEYCARD

Found 847 rate limit errors (last hour)

Read customer PII from prod DB
BLOCKED BY KEYCARD

Blocked: PII requires elevated approval

Create issue in Linear
VIA KEYCARD
Push fix to GitHub
VIA KEYCARD
KYC-847 [email protected] 2m ago
Running
Keycard
Request

datadog:logs:read

"Fetch error logs"

Identity
Devicembp-m3-001mTLS cert
Agentclaude-codeworkload ID
Taskfix rate limit bugruntime
Policy

"When fixing bugs: allow logs:read"

task:bug-fix + logs:read

ACCESS GRANTED
Scopedatadog/logs : read-only
ContextSarah → Claude → KYC-847
Expires15m (auto refresh on)
Request

prod-db:customers:read (PII)

"Read customer PII from prod DB"

Identity
Devicembp-m3-001mTLS cert
Agentclaude-codeworkload ID
Taskfix rate limit bugruntime
Policy

forbid when resource.tags.sensitivity == "pii"

resource:pii + trust:blocked

Access Denied
Scopeprod-db/customers — blocked
Contextflagged to security team
Loggedstreamed to SIEM
Request

linear:issues:write

"Create issue in Linear"

Identity
Devicembp-m3-001mTLS cert
Agentclaude-codeworkload ID
Taskfix rate limit bugruntime
Policy

"When fixing bugs: allow issues:write"

task:bug-fix + issues:write

Access Granted
Scopelinear/KYC — issues:write
ContextSarah → Claude → KYC-847
Expirestask completion
Request

github:contents:write

"Push fix to GitHub"

Identity
Devicembp-m3-001mTLS cert
Agentclaude-codeworkload ID
Taskfix rate limit bugruntime
Policy

"When fixing bugs: allow logs:read

Access Granted
Scopeacme/payments — contents:write
ContextSarah → Claude → KYC-847
Expirestask completion

Anatomy of an insecure agent Anatomy of a secure agent

What's at risk? What's possible

Intent Data access + Actions
1 No IdentityIdentity
Agents + Users
2 PII ExposedScoped
Agent Process
Workers
Memory
3 No Policy GatePolicy Foundational Model
4 Unvetted AccessTokens
Tools + Services
MCP Servers
APIs
Data Stores
5 No TrailAudited
How it works

The path from intent to action

Keycard resolves identity, enforces policy, and issues scoped access.

The agent makes the call.

Composite identity graph

Identity resolves first. Keycard builds a composite identity from the full execution context.

Everything that follows is scoped to that resolution.

  • Federated across your existing identity infra
  • Identity = user + device + agent + task
  • Every action maps to a human/machine identity
Identity Resolution
Task
fix rate limit bug
runtime
Agent
claude-code
workload ID
Who
Okta SSO
Device
mbp-m3-001
mTLS cert
Composite Identity Resolved

Enforcement at the gate

Policy evaluates at the edge, the moment an agent requests access. No credential is issued unless policy allows it.

Author rules visually, test against live traffic in observe-only mode, and roll back instantly.

  • Every request evaluated. Every denial explained.
  • Observe-only mode for testing against live traffic
  • Instant rollback to any previous policy set
Policy Evaluation
acme-prod — v3 Active
permit Application
  when resource.tags.sensitivity != "pii"
  unless application.tags.trust == "shared"
acme-prod — v4 Observe
forbid Application
  when resource.tags.department == "hr"
  and application.tags.trust == "shared"
v3: Allow v4: Would Deny

Task-scoped credentials

Keycard issues short-lived, least-privilege credentials bound to the task at hand. No long-lived secrets, no over-permissioned service accounts.

Every credential expires when the task completes.

  • Identity-bound, resource-scoped
  • Minted on demand. No long-lived tokens.
  • Immediately revocable
Credential Issuance
Active
scopeacme/payments — contents:write
identity[email protected] → claude-code
taskfix-rate-limit
ttl23m remaining
issued14:32:07 UTC
Revoked
scopeacme/payments — contents:read
reasontask completed

Centralized telemetry

A real-time event stream of every agent action, tool call, and policy decision. Tamper-resistant, streaming to your SIEM.

Developer-first, compliance-ready.

  • Real-time streaming to Splunk, Datadog, etc.
  • Structured event stream - filter, query, alert
  • Full attribution on every action
Live Event Stream
14:32:07sarah@github.contents.writeAllow
14:31:58sarah@linear.issue.createAllow
14:31:42sarah@datadog.logs.readAllow
14:31:15mike@aws.s3.deleteBucketDeny
14:30:51dev-botpostgres.query.readAllow
14:30:33mike@github.repo.settingsEscalate

3 ways to start using Keycard

Whether you're building agents, securing the ones you already use, or adopting agentic tools across the org.

Build agents that can access anything

MCP servers need auth but the spec keeps changing. Agents need downstream APIs but sharing credentials is a dead end. The SDK handles both.

Experience Works with every MCP client
Flow Auth that absorbs change
Code One import for full context
Experience Users see exactly what they're granting
Exchange One token in, one token out
Code Keycard never touches the data

The agent you build is instantly accessible to any MCP client.
Users authenticate through the organization IdP.

MCP SERVERS / INSTALLED
✓ connected
Your MCP Server [email protected] · Okta SSO
✓ connected
GitHub repo:read, issues:write
✓ connected
Linear issues:read, projects:read
S pending
Slack awaiting admin approval
N
Notion
D
Datadog

The SDK handles the handshake. OAuth today, whatever comes next.

You write
KeycardAuth({
  issuer: process.env.KEYCARD_ISSUER
})
One function call. That's the integration.
SDK handles
OAuth 2.1 + PKCE
Agent identity binding
Credential caching
Task-scoped tokens
Automatic refresh

Every handler receives the full picture. One import, zero config.

authInfo live
agentclaude-code
taskdeployment-review-42
devicemacbook-pro-14
environmentproduction
permissions read write deploy
tokeneyJhbG...xkQ · 3600s

The agent shows intent. The user sees exactly what they're granting.

S
Schedule a standup with the team for tomorrow at 10am
I'll need access to Google Calendar to create that event…
Requesting consent…

One Keycard token. Exchange it for scoped access to anything.

Keycard JWT sarah · claude-code · task-42
STS exchange ↓
Google Calendar calendar.readonly
3600s
GitHub repo:read, issues:write
1800s
AWS S3 s3:GetObject
900s
Keycard issues the credential. Never proxies the data.

Token goes straight to the API. Keycard issues credentials, never proxies data.

Token Exchange
// Agent needs Google Calendar.
// Exchange the Keycard JWT for a scoped token.

const sts = new STSClient(config.keycardStsIssuerUrl)

const { access_token } = await sts.exchange(
  authInfo,
  "https://www.googleapis.com/calendar/v3",
  ["https://www.googleapis.com/auth/calendar"]
)

// Use it directly. Keycard never sees the data.
const resp = await fetch(calendarUrl, {
  headers: { Authorization: `Bearer ${access_token}` }
})

Govern any coding agent with a single CLI

Coding agents touch shell, scripts, and MCP tools, but nothing governs those paths today. keycard run virtualizes .env and mcp.json so credentials never hit disk, and every execution path is audited.

Shell Credentials without .env
Automation Agent-written code, governed
MCP Tool Calls One audit trail, every path

Secrets injected in-memory. Never on disk. Gone when the session ends.

$ keycard run --agent cursor
Authenticating... [email protected]
.env takeover... 4 secrets injected (in-memory)
mcp.json takeover... 3 allowed, 2 purged
Hooks verified... checksum match
Cursor running under Keycard governance
Scoped: memory, skills, tools
MCP: github, linear, datadog
Purged: slack-mcp, aws-infra

Agent-generated code gets scoped, short-lived credentials. Not static keys from 1Password.

agent-generated · deploy.py
import os, boto3

# Agent writes this at runtime.
# .env doesn't exist on disk —
# Keycard injects creds in-memory.

key = os.environ["AWS_ACCESS_KEY_ID"]
secret = os.environ["AWS_SECRET_KEY"]

s3 = boto3.client("s3",
  aws_access_key_id=key,
  aws_secret_access_key=secret)

s3.upload_file("build.zip", "deploys", "v2.3.1.zip")
AWS_SECRET_ACCESS_KEY resolved from Keycard session. Short-lived, scoped to s3:PutObject. Never written to disk.

Shell, MCP, and credential events. One audit stream for everything the agent did.

Session Audit · sarah@ Live
mcp github.search_code token exchanged
mcp linear.create_issue token exchanged
shell python deploy.py env injected
mcp slack.post_message server purged
shell curl $GITHUB_TOKEN ... env injected
Works with

Every team gets access to agents
No agent gets access to everything

Salesforce for Sales. GitHub for Engineering. Notion for Marketing. Keycard scopes agent access by department, identity, and policy. Adoption scales independent of risk.

Discover Agents find tools through identity, not guesswork.
Manage One catalog, department-scoped, always current.
Govern Every install, block, and denial. In real time.

Claude using Keycard to do sales?

CLAUDE-SALES-03
::: KEYCARD
Resolving identity…
Discovering tools for Sales
Salesforce       Google Drive
Slack            Notion
2 tools ready, 1 pending approval

One catalog. Department-scoped. Always current.

Departments
Marketing 4
Sales 6
Engineering 12
Finance 2
Marketing — Agent Tools
N Notion Docs & knowledge ✓ installed
G Google Drive Documents & files ✓ installed
H HubSpot Marketing automation ⊘ blocked
S Slack Messaging pending

Every install, block, and denial. In real time.

Event Feed Today
2,831allowed
14escalated
3blocked
94%compliance
10:41sf.pipeline.query — sarah@salesallowed
10:42sf.contacts.write — escalatedescalated
10:43sf.contacts.write — approvedapproved
10:44hubspot.contacts — blockedblocked
10:45notion.pages — allowedallowed

This is what governance looks like

The system works autonomously. Escalation only when necessary.

DASHBOARD
Developers
127
Agent Requests
2,847
Success Rate
93.3%
Auto approved User approved Stopped
94%
4%
2%
3 Actions rejected
[email protected] project.delete Destructive action: approval required
[email protected] team.update : billing-api Outside allowed scope
dev-bot aws.s3.deleteBucket Blocked resource class
SESSIONS
Production / Sessions / bce9f…f250
Claude Code
Completed bce9f-449b…1508f250
Time 3m 22s Tool calls 14 Credentials 3 Policies 1
12:34:56
+12ms
github.search_code GitHub API
Token exchanged · 3 results
12:34:56
+15ms
github.get_file_contents GitHub API
Token reused · cached
12:34:56
+63ms
linear.create_issue Linear API OAuth
Token reused · Issue #LIN-482
12:34:56
+63ms
postgres.query
Read-only · No PII detected
12:34:56
+63ms
postgres.execute
Write blocked: requires human approval
12:34:56
+63ms
postgres.executed
Write granted: [email protected] approved (via Slack)
12:35:01
+375ms
slack.post_message S Slack
Token exchanged · Channel #eng-updates
The Loop

Every action enriches the model. Consent fatigue drops. Access becomes adaptive. The system gets smarter every week.

Agents act

2,847 requests today

Signals flow

Calls, denials, escalations → telemetry

Policy adapts

Context graph updates, rules redefine

Autonomy grows

Fewer prompts, broader access

And the cycle repeats
Week 1
72% auto approved
Week 4
86% auto approved
Week 12
94%+ auto approved