HackerTrans
TopNewTrendsCommentsPastAskShowJobs

csemple

no profile record

Submissions

Why Ontario Digital Service couldn't procure '98% safe' LLMs (15M Canadians)

rosetta-labs-erb.github.io
40 points·by csemple·6 maanden geleden·48 comments

comments

csemple
·6 maanden geleden·discuss
Yep, I use em dashes all the time—still a human typing this.
csemple
·6 maanden geleden·discuss
If a tool is in the context window, the model assigns a non-zero probability to using it. By filtering it out upstream, you entirely remove that path from the inference tree. Instead of asking the model to ignore an affordance, you remove the affordance entirely.

With granular permissions: It’s nouns vs. verbs, where data-level permissions still happen at the database layer (nouns) along with this pattern constraining the capability to act (verbs.) If it does hallucinate a hidden tool, the kernel mechanically blocks the execution before it reaches the system, breaking a retry loop faster than a permissions error.
csemple
·6 maanden geleden·discuss
I guess working in government has put me ahead of the curve sounding like a robot.
csemple
·6 maanden geleden·discuss
Yes, thanks. That's the one-sentence summary.
csemple
·6 maanden geleden·discuss
You’re totally right—it's ultimately just probabilistic tokens. I’m thinking that by physically removing the tool definition from the context window, we avoid state desynchronization. If the tool exists in the context, the model plans to use it. When it hits a "stub" error, it can enter a retry loop or hallucinate success. By removing the definition entirely, we align the model's World Model with its Permissions. It doesn't try to call a phone that doesn't exist.
csemple
·6 maanden geleden·discuss
Ya, makes sense—if the model is trained just to "be helpful," removing the tool forces it to improvise. I’m thinking this is where the architecture feeds back into the training/RLHF. We train the model to halt reasoning in that action space if the specific tool is missing. This changes the safety problem from training the model to understand complex permission logic to training the model to respect a binary absence of a tool.
csemple
·6 maanden geleden·discuss
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?
csemple
·6 maanden geleden·discuss
Yes, on your first point "layer 1" isn't fundamentally new. It's applying standard systems administration principles, because we're currently trusting prompts to do the work of permissions.

With the pattern I'm describing, you'd: - Filter the tools list before the API call based on user permissions - Pass only allowed tools to the LLM - The model physically can't reason about calling tools that aren't in its context, blocking it at the source.

We remove it at the infrastructure layer, vs. the prompt layer.

On your second point, "layer 2," we're currently asking models to actively inhibit their training to obey the constricted action space. With Tool Reification, we'd be training the models to treat speech acts as tools and leverage that training so the model doesn't have to "obey a no"; it fails to execute a "do."
csemple
·6 maanden geleden·discuss
Yep, you nailed the problem: context drift kills instruction following.

That's why I’m thinking authority state should be external to the model. If we rely on the System Prompt to maintain constraints ("Remember you are read-only"), it fails as the context grows. By keeping the state in an external Ledger, we decouple enforcement from the context window. The model still can't violate the constraint, because the capability is mechanically gone.
csemple
·6 maanden geleden·discuss
You're exactly right—treating the LLM as an untrusted user is the security baseline.

The distinction I'm making is between Execution Control (Firewall) and Cognitive Control (Filter).

Standard RBAC catches the error after the model tries to act (causing 403s, retry loops, or hallucinations). This pattern removes the tool from the context window entirely. The model never considers the action because the "vocabulary" to do it doesn't exist in that session.

Like the difference between showing a user a "Permission Denied" error after they click a button, versus not rendering the button at all.
csemple
·6 maanden geleden·discuss
OP here. *** I'm seeing comments about AI-generated writing. This is my voice—I've been writing in this style for years in government policy docs. Happy to discuss the technical merits rather than the prose style. ***

At Ontario Digital Service, we built COVID-19 tools, digital ID, and services for 15M citizens. We evaluated LLM systems to improve services but could never procure them.

The blocker wasn't capability—it was liability. We couldn't justify "the model probably won't violate privacy regulations" to decision-makers who need to defend "this system cannot do X."

This post demonstrates the "Prescription Pad Pattern": treating authority boundaries as persistent state that mechanically filters tools.

The logic: Don't instruct the model to avoid forbidden actions—physically remove the tools required to execute them. If the model can't see the tool, it can't attempt to call it.

This is a reference implementation. The same pattern works for healthcare (don't give diagnosis tools to unlicensed users), finance (don't give transfer tools to read-only sessions), or any domain where "98% safe" means "0% deployable."

Repo: https://github.com/rosetta-labs-erb/authority-boundary-ledge...