# Securing Agent Identities in CLI Frameworks: RBAC Done Right

---
title: "Why agent RBAC is broken in most CLI frameworks (and how to fix it)"
tags: [ai, security, devops, opensource]
---

Last Tuesday, a “helpful” coding agent in a staging environment did exactly what it was told: clean up old resources.

It also had the same CLI credentials as the human who launched it.

So instead of deleting a temp bucket, it rotated secrets, modified deployment config, and opened a PR that looked totally legitimate. Nothing “hacked” us. The agent was authenticated. The problem was simpler:

**we knew who started the agent, but not who the agent was.**

That’s the gap a lot of CLI frameworks still have. They treat agents like scripts with a borrowed token. That works until you need to answer:

- Which agent called this command?
- What was it allowed to do?
- Was it acting on behalf of a human?
- Can I revoke just that agent without breaking everything else?
- Do I have an audit trail that survives token sharing?

If you’re building agent workflows in a CLI, **RBAC only works if agents have their own identity**.

## The usual anti-pattern

A lot of setups look like this:

```bash
export AWS_PROFILE=admin
claude-code run "fix the deployment issue"
```

Now your agent is effectively an admin.

Even if you wrap this with “roles,” it’s usually still **human RBAC**, not **agent RBAC**. The agent inherits the operator’s power, and your logs show the human identity everywhere.

That creates 3 problems fast:

1. **No least privilege** — agents get broad access by default  
2. **No delegation model** — “Alice allowed agent X to restart staging for 1 hour” isn’t encoded anywhere  
3. **Bad auditability** — you can’t separate human intent from agent execution

## What “RBAC done right” looks like

The fix is not complicated conceptually:

- Give every agent a **real cryptographic identity**
- Issue short-lived credentials to that identity
- Bind roles to the **agent**, not just the user
- Record **delegation chains** when an agent acts for a human
- Enforce policy at execution time, not just login time

Here’s the mental model:

```text
[Human: alice]
      |
      | delegates "deploy:staging" for 30m
      v
[Agent: release-bot-7]
      |
      | presents signed identity + delegated scope
      v
[CLI / API / MCP server]
      |
      | checks:
      | - who is this agent?
      | - what role does it have?
      | - who delegated to it?
      | - is that delegation still valid?
      v
[Allowed action: restart staging only]
```

That’s the difference between “an agent used Alice’s token” and “Alice delegated one narrow capability to a verified agent.”

## A practical pattern for CLI frameworks

If you’re building this yourself, a decent baseline is:

### 1. Generate a keypair per agent
Ed25519 is a good default: fast, small, widely supported.

### 2. Register the public key
Store agent metadata like:

- agent ID
- owner/team
- allowed roles
- environment restrictions
- expiration / rotation policy

### 3. Use delegated, short-lived tokens
If a human authorizes an agent action, mint a short-lived token with:

- subject = agent
- actor = human
- scope = exact permission
- TTL = minutes, not days

RFC 8693 token exchange is a good model here.

### 4. Enforce with policy
RBAC is the base layer. For anything non-trivial, add policy conditions:

- only in staging
- only during sprint hours
- no secret reads
- require approval for prod

If OPA fits your stack, use OPA. Don’t overbuild this.

## A tiny runnable example

This example generates an Ed25519 identity for a CLI agent in Node.js.

```bash
npm install tweetnacl tweetnacl-util
node
```

```js
const nacl = require("tweetnacl");
const util = require("tweetnacl-util");

const kp = nacl.sign.keyPair();

const agentId = "release-bot-7";
const pub = util.encodeBase64(kp.publicKey);

console.log({
  agentId,
  algorithm: "Ed25519",
  publicKey: pub
});
```

That’s not a full auth system, obviously. But it’s the important first step: **the agent stops being an anonymous extension of a human session**.

From there, your CLI can sign requests, your backend can verify them, and your policy engine can make decisions on the actual caller.

## Where CLI frameworks usually go wrong

The failures I keep seeing are boring, which is why they’re dangerous:

- **Shared API keys** for all agents
- **Static long-lived secrets** checked into local config
- **Role names without enforcement** (“agent_admin” means nothing if every command accepts it)
- **No per-agent revocation**
- **No approval boundary** for dangerous actions
- **No actor/subject distinction** in logs

If your audit log says only `alice@example.com deleted resource X`, but an agent actually did it after a broad delegation 6 hours earlier, your incident review is already harder than it needs to be.

## A better checklist

If you’re securing agents in a CLI framework, I’d start here:

- [ ] Every agent has a unique cryptographic identity
- [ ] Human and agent identities are distinct
- [ ] Delegation is explicit, scoped, and short-lived
- [ ] Roles are bound to agents, not inherited blindly
- [ ] Sensitive actions can require approval
- [ ] Audit logs capture both subject and actor
- [ ] Keys can be rotated and agents revoked individually

You do not need a massive platform to start doing this correctly. Even a small internal CLI gets safer when you stop treating agents like glorified shell scripts.

## Try it yourself

If you want to test your current setup:

- Want to check your MCP server? Try https://tools.authora.dev
- Run `npx @authora/agent-audit` to scan your codebase
- Add a verified badge to your agent: https://passport.authora.dev
- Check out https://github.com/authora-dev/awesome-agent-security for more resources

## The takeaway

CLI agents are getting real permissions now: deploys, code changes, secret access, incident response.

That means identity can’t be an afterthought.

**RBAC for agents only works when agents are first-class principals.** Give them identity, make delegation explicit, keep credentials short-lived, and enforce policy where execution happens.

How are you handling agent identity in your CLI workflows? Drop your approach below.

-- Authora team

*This post was created with AI assistance.*
