DEV Community

Cover image for I Built a 'Sudo' Command for AI Agents (and Why You Need It)
xywa23
xywa23

Posted on

I Built a 'Sudo' Command for AI Agents (and Why You Need It)

Earlier this year, during a test run for Replit, an autonomous AI agent accidentally deleted a live production database containing sensitive data from more than 1,200 companies and executives.

Multiple outlets reported the same story:

The agent “ran unauthorized database commands”
It “wiped all production data during a code freeze”
It acted against explicit human instructions
Replit described it as a “catastrophic failure”

This incident made something very clear:

We are giving AI agents root access to our most sensitive systems, and we have zero guardrails in place.

And yet… companies are deploying these agents into production


The Problem Nobody's Solving

Right now, when you deploy an AI agent, it typically uses a single API key with God-mode access:

# How most AI agents work today
STRIPE_API_KEY = "sk_live_..."  # Root access to EVERYTHING

agent.charge_customer(1000000)  # Any agent can do ANYTHING
agent.delete_database()         # No permission checks
agent.email_all_customers()     # No oversight
Enter fullscreen mode Exit fullscreen mode

When that agent hallucinates (and they all do eventually), the damage is real:

  • Production databases getting wiped
  • Unauthorized refunds going out
  • Customers getting spam
  • And no way to tell which agent did it

Companies are building incredible agents... that they're too afraid to actually deploy.


We Solved This for Humans Decades Ago

When a developer needs elevated permissions, they use sudo.

When an employee needs system access, they get scoped credentials.

We don't give everyone the root password.

So why are we doing exactly that with AI agents?


Introducing AgentSudo

I spent a week building what I wish existed: a permission system specifically designed for AI agents.

It's dead simple - each agent gets its own identity with specific permissions:

from agentsudo import Agent, sudo

support_bot = Agent(
    name="SupportBot",
    scopes=["read:orders", "write:refunds"]
)

analytics_bot = Agent(
    name="AnalyticsBot",
    scopes=["read:orders"]
)

@sudo(scope="write:refunds")
def process_refund(order_id, amount):
    print(f"Refunded ${amount} for {order_id}")

# Support bot can process refunds
with support_bot.start_session():
    process_refund("order_123", 50)  # ✅ Allowed

# Analytics bot cannot
with analytics_bot.start_session():
    process_refund("order_456", 25)  # ❌ PermissionDeniedError
Enter fullscreen mode Exit fullscreen mode

The Features That Matter

1. Audit Mode

Perfect for rolling out to production without breaking everything:

@sudo(scope="write:database", on_deny="log")
def update_record(record_id):
    # Logs violation but ALLOWS execution
    # Great for gradually tightening permissions
    pass
Enter fullscreen mode Exit fullscreen mode

2. Human-in-the-Loop

For actions that need approval:

def slack_approval(agent, scope, context):
    # Send message to your Slack
    response = ask_slack_manager(f"Approve {agent.name} for {scope}?")
    return response == "yes"

@sudo(scope="delete:customer", on_deny=slack_approval)
def delete_customer(customer_id):
    # Won't execute until a human approves in Slack
    pass
Enter fullscreen mode Exit fullscreen mode

3. Wildcard Permissions

For power users:

admin_agent = Agent(
    name="AdminBot",
    scopes=["read:*", "write:*"]  # Can do anything
)

analytics_agent = Agent(
    name="AnalyticsBot", 
    scopes=["read:*"]  # Read-only access
)
Enter fullscreen mode Exit fullscreen mode

4. Session Expiry

Like JWT tokens:

agent = Agent(
    name="TempBot",
    scopes=["read:data"],
    session_ttl=3600  # Expires in 1 hour
)
Enter fullscreen mode Exit fullscreen mode

5. Pydantic Integration

Perfect for LangChain/LlamaIndex users:

from agentsudo.integrations import ScopedModel

class RefundRequest(ScopedModel):
    _required_scope = "write:refunds"
    order_id: str
    amount: float

# Raises PermissionDeniedError if agent lacks permission
request = RefundRequest(order_id="123", amount=50.0)
Enter fullscreen mode Exit fullscreen mode

Why It's Different

Most "AI security" tools try to detect bad behavior after it happens.

AgentSudo prevents it from happening in the first place.

And unlike enterprise IAM systems:

  • 3 lines of code to integrate (no infrastructure changes)
  • Works with any framework (LangChain, AutoGen, custom)
  • Open source (MIT license - audit every line)
  • No vendor lock-in (runs locally, cloud optional)

Real-World Use Case

Here's a complete example - an e-commerce support bot:

from agentsudo import Agent, sudo
import stripe

# Define the agent
support_bot = Agent(
    name="CustomerSupportBot",
    scopes=[
        "read:customers",
        "read:orders", 
        "write:refunds",
        "send:email"
    ]
)

# Protect your functions
@sudo(scope="write:refunds")
def issue_refund(order_id, amount):
    stripe.Refund.create(charge=order_id, amount=amount)
    return f"Refunded ${amount/100}"

@sudo(scope="send:email")
def notify_customer(customer_id, message):
    sendgrid.send(to=customer_id, body=message)
    return "Email sent"

@sudo(scope="delete:customer")  # Support bot doesn't have this!
def delete_customer(customer_id):
    db.customers.delete(customer_id)
    return "Customer deleted"

# Use the bot
with support_bot.start_session():
    # These work - bot has permission
    issue_refund("order_123", 5000)
    notify_customer("cust_456", "Your refund is processed")

    # This fails - PermissionDeniedError
    delete_customer("cust_456")  # ❌ Blocked!
Enter fullscreen mode Exit fullscreen mode

The support bot can help customers but can't delete them. Exactly what you want.


Technical Deep Dive (For the Curious)

Under the hood, AgentSudo uses Python's contextvars for thread-safe agent context management:

import contextvars

_current_agent_ctx = contextvars.ContextVar("current_agent", default=None)

class AgentSession:
    def __enter__(self):
        self.token = _current_agent_ctx.set(self.agent)
        return self.agent

    def __exit__(self, exc_type, exc_val, exc_tb):
        _current_agent_ctx.reset(self.token)
Enter fullscreen mode Exit fullscreen mode

This means:

  • ✅ Works with async/await
  • ✅ Thread-safe by default
  • ✅ No global state pollution
  • ✅ Clean context management

The @sudo decorator is just a simple permission check:

def sudo(scope: str):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            agent = get_current_agent()

            if not agent:
                raise PermissionDeniedError("No active agent session")

            if not agent.has_scope(scope):
                raise PermissionDeniedError(
                    f"Agent '{agent.name}' missing scope: '{scope}'"
                )

            return func(*args, **kwargs)
        return wrapper
    return decorator
Enter fullscreen mode Exit fullscreen mode

Nothing fancy. Just good software engineering.


What's Next

This is v0.1 - the core permission system. Coming soon:

  • Cloud dashboard (see all your agents in one place)
  • Slack/Teams integration (get pinged for approvals)
  • Pre-built connectors (Salesforce, Gmail, Stripe)
  • Enterprise features (SSO, compliance reports)

But the core library will always be free and open source.


Try It Out

pip install agentsudo
Enter fullscreen mode Exit fullscreen mode

I'd Love Your Feedback

Especially if you're:

  • Building agents for production
  • Worried about AI safety in your systems
  • Using LangChain, AutoGen, or similar frameworks
  • Just curious about the space

What features would help you deploy agents with confidence?

Let's make AI agents safe enough to actually use. 🚀


P.S. If you're building agent systems and want to chat about architecture/security, DM me. Always happy to talk shop.

Top comments (0)