← Back to context

Comment by skipants

7 days ago

A couple small things:

1. as many have harped about, the LLM writing is so fluffed up it's borderline unreadable. Please just write in your own voice. It's more interesting and would probably be easier to grok

2. that repo is obviously vibe-coded, but I suppose it gets the point across. It doesn't give me much confidence in the code itself, however.

And a big thing:

Unless I'm misunderstanding, I feel like you are re-inventing the wheel when it comes to Authorization via MCP, as well as trying to get away with not having extra logic at the app layer, which is impossible here.

MCP servers can use OIDC to connect to your auth server right now: https://modelcontextprotocol.io/docs/tutorials/security/auth...

You give the following abstractions, which I think are interesting thought experiments but unconventional and won't work at all:

    Ring 0 (Constitutional): System-level constraints. Never overridable.
        Example: "Never self-replicate" "Never exfiltrate credentials"

    Ring 1 (Organizational): Policy-level constraints. Requires admin authority to change.
        Example: "No PII in outputs" "Read-only database access"
    
    Ring 2 (Session): User preferences. Freely changeable by user.
        Example: "Explain like I'm five" "Focus on Python examples"

In Ring 0 and 1 you're still asking for the LLM to determine if the security is blocked, which opens it up to jailbreaking. Literally what your whole article is about. This won't work:

    # Generate (Pass filtered tools to LLM)
    response_text, security_blocked = self._call_llm(
        query, history, system_prompt, allowed_tools, tools
    )

Ring 0 and 1 MUST be done via Authorization and logic at the application layer. MCP Authorization helps with that, somewhat. Ring 2 can simply be part of your system prompt.

     Standard RBAC acts as a firewall: it catches the model’s illegal action after the model attempts it.

That's the point. It's the same reason you will have mirroring implementations of RBAC on a client and server: you can't trust the client. LLM can't do RBAC. It can pretend it does, but it can't.

The best you can do is inject the user's roles and permissions in the prompt to help with this, if you'd like. But it's kind of a waste of time -- just feed the response back into the LLM so it sees "401 Unauthorized" and either tries something else or lets the user know they aren't allowed.

I'm sorry, but as a resident of Ontario and a developer this whole posting just enrages me. I don't want to discourage OP but you should know there's a lot just incorrect here. I'd be much more relaxed about that if it all wasn't just one-shotted by AI.

I appreciate the feedback. Let me address the key technical point:

On enforcement mechanism: You've misunderstood what the system does. It's not asking the LLM to determine security.

The Capacity Gate physically removes tools before the LLM sees them:

    user_permissions = ledger.get_effective_permissions()
    allowed_tools = [t for t in tools if (user_permissions & t['x-rosetta-capacity']) == t['x-rosetta-capacity']]

If READ_ONLY is active, sql_execute gets filtered out. The LLM can't see or call tools that don't make it into allowed_tools.

    response = client.messages.create(tools=allowed_tools)

This isn't RBAC checking after the fact. It's capability control before reasoning begins. The LLM doesn't decide permissions—the system decides what verbs exist in the LLM's vocabulary.

On Ring 0/1: These are enforced at the application layer via the Capacity Gate. The rings define who can change constraints, not how they're enforced.

On MCP: MCP handles who you are. This pattern handles what you can do based on persistent organizational policies. They're complementary.

The contribution isn't "LLMs can do RBAC" (they can't). It's "here's a pattern for making authority constraints persistent and mechanically enforceable through tool filtering."

Does this clarify the enforcement mechanism?

  • Really? Even with your AI generated article I took my own time to read and reply sans AI and you can't even respond to my comment without it? Thanks.