Oleander Logooleander

In AI We Trust. Everyone Else Gets Access Control.

MP

Minkyu Park

staff
Tags
iamaccess-controlagentsmcpiceberg

In AI We Trust

It’s the agentic era, and everyone loves agents.

Every other viral post is about an AI agent completing an entire task without human intervention. It opened the browser, queried the database, wrote the code, called three internal APIs, deployed the service, sent the email, summarized the result, and probably scheduled a follow-up meeting with itself.

Amazing.

And the best part is that you didn’t have to do anything.

You don’t even have to think that hard anymore. Thinking is expensive. Thinking takes time. Thinking requires context, judgment, domain knowledge, and occasionally the deeply unpleasant experience of realizing that your first idea was wrong.

Why bother?

Just ask AI.

It is smart. It has reasoning. It has tools. It has memory. It has access to your database, your production environment, your internal APIs, your customer records, and probably a few things nobody quite remembers giving it access to.

But that’s fine.

It knows what it’s doing.

Look at this task, for example. It would have taken me three days to finish manually. The agent did it in four minutes and thirty-seven seconds. It gathered the data, ran the analysis, generated the report, and gave me a beautifully formatted summary with bullet points.

A historic productivity breakthrough.

There is, however, one tiny issue.

It also dropped the table containing our source-of-truth data.

Well.

Nobody is perfect.

And technically, the task was completed. I already have the analytical insight I needed, so who really needs the original data anymore?

You do?

You think deleting the source of truth is a problem?

That sounds unnecessarily negative.

But fine. Fine. We can fix this. This is one of the beautiful things about modern AI engineering: every catastrophic failure is simply an opportunity to add another sentence to the system prompt.

Have you heard of guardrails?

Guardrails are wonderful.

You just tell the agent what not to do.

Very clearly.

Preferably in capital letters.

So we add:

DO NOT DROP THE SOURCE-OF-TRUTH TABLES.

There.

Problem solved.

The agent now understands.

We have successfully aligned a cutting-edge probabilistic reasoning system with the ancient and sophisticated engineering principle of “please don’t delete the important stuff.”

We run the task again.

Success.

The analysis completes. The report looks great. The source-of-truth tables are still there. Nothing appears to be on fire.

See?

I told you.

The system works.

At this point, continuing to worry starts to feel almost irrational. We gave the agent an instruction. It followed the instruction. We observed the desired behavior. What more evidence could anyone possibly need?

Sure, technically it still has permission to drop every table in the database. Sure, technically it can read data it has absolutely no business reading. Sure, technically it can call internal APIs, modify production resources, and perform actions that would normally require three approvals, two tickets, a security review, and one deeply unhappy engineer asking why the service account has admin privileges.

But why focus on technicalities?

The prompt says not to.

And the agent is very smart.

How dare you doubt our powerful, magnificent, highly benchmarked AI agent? It has reasoning. It has tools. It can plan. It can recover from errors. It can reflect on its own output. There are even diagrams showing arrows going in circles, which is how you know the architecture is advanced.

It would never do something stupid.

Unless the context is confusing. Or the prompt is ambiguous. Or the model interprets the instruction differently. Or a tool returns something unexpected. Or another instruction takes precedence. Or a retrieved document contains malicious instructions. Or someone finds a prompt injection. Or the model simply makes a bad decision for reasons that become obvious only after reading six thousand tokens of logs.

But apart from those minor implementation details, it is flawless.

It has to be.

After all, reducing its permissions would hurt flexibility. Adding human approval would make it less autonomous. Restricting which data it can access would limit its ability to “reason across the organization.” Reworking the architecture would take engineering time, and more importantly, it would make the demo considerably less impressive.

We didn’t come all this way to build an autonomous agent just to tell it that it is not authorized to do things.

That would defeat the whole point of autonomy.

So the only reasonable conclusion is obvious: the AI must be trusted, the AI must be powerful, and the AI must have access.

If something goes wrong, we can simply improve the prompt.

Again.

And again.

And again.

Eventually, through the careful accumulation of increasingly specific English sentences, we will construct a perfect security boundary.

Probably.

Until then, the agent has admin access.

In AI we trust.

Everyone else gets access control.

Access Control Is What You Need

The problem is not whether your agent is smart enough to understand what it should or should not do.

The problem is that it should never have been able to do certain things in the first place.

This is why Oleander has an IAM system.

There is nothing particularly novel or AI-native about it. There is no new security framework invented specifically for the agentic era, no LLM sitting in the authorization path deciding whether an action “feels safe,” and no giant system prompt containing several thousand words of increasingly desperate warnings.

It is just the same boring stuff engineers have spent decades learning to rely on: identity, authentication, roles, policies, and access control.

And that is exactly the point.

The Agent Is Just Another User

When an agent uses one of the Oleander MCP tools, that tool eventually calls an Oleander API. The request carries a token in the Authorization header, just like any other authenticated client.

From there, the process is very conventional. Oleander authenticates the token and determines the identity of the requesting user. It looks at the roles assigned to that identity, checks the permissions associated with those roles, and determines whether the user is allowed to perform the requested action on the requested resource.

If the answer is yes, the request continues.

If the answer is no, the API returns 403 Forbidden.

That’s it.

There is no prompt asking the agent to please reconsider its life choices. There is no second model judging whether the first model appears trustworthy. The API simply says: you are not allowed to do that.

The same model applies to Oleander’s Iceberg warehouse. A role can define which actions are allowed on which namespaces in the warehouse. If an identity tries to perform an operation outside those permissions, access is denied. If it tries to access a namespace it does not have permission to access, access is denied.

Again, there is no AI involved in that decision.

Just token-based authentication and role-based access control.

Old-fashioned, deterministic, wonderfully boring access control.

And boring is pretty nice when the alternative is an autonomous agent with production credentials.

We Already Know How to Solve This Problem

This is not actually a new problem created by AI agents.

Long before the agentic era, we already knew that giving every user unrestricted access to every piece of data was a bad idea. We knew that applications could have bugs and accidentally touch resources they were never supposed to touch. We knew that credentials could be misused, that software could behave unexpectedly, and that “the application probably won’t do that” was not a particularly convincing security model.

So we built authentication systems. We created service accounts. We assigned roles. We followed the principle of least privilege. We built audit trails so we could figure out who did what after something inevitably went wrong.

None of those lessons suddenly become obsolete because the software calling the API now has a transformer inside it.

An AI agent may be more flexible than a traditional application. It may decide which tool to call, what order to call them in, and what arguments to pass based on context. That makes its behavior less predictable, not more deserving of unrestricted access.

We do not need to invent a new security model for that.

We can simply extend the one we already have.

Instead of endlessly refining a guardrail prompt in the hope that the agent will always decide to stay within its intended boundaries, we make those boundaries real.

The agent can try.

The API can say no.

That distinction matters.

Human, Application, and Agent Users

Oleander has three user types: human, application, and agent.

At a high level, you could simply think of these as human users and machine users. Both application users and agent users represent software acting without a human directly making each individual request.

We keep application and agent users separate mainly because the distinction is useful operationally. When you look at an audit trail, it is helpful to know whether a request came from a conventional application or from an AI agent choosing actions dynamically.

But from the access-control system’s point of view, they are not fundamentally special.

A human user has an identity.

An application has an identity.

An agent has an identity.

Each identity can have roles assigned to it, and those roles determine what that identity is allowed to do.

The authorization system does not care whether the caller is a person clicking a button, a backend service running deterministic code, or an AI agent that spent 4,000 tokens thinking very deeply before deciding to call DROP TABLE.

Permissions are permissions.

Creating an Agent User

An organization administrator can create an agent user from the Oleander settings page.

Go to:

Settings → Organization → Users → Agent

Then click New to create a new agent identity.

During creation, you can assign one or more roles to the agent. Those roles define what the agent will actually be able to do once it authenticates through MCP.

This is where the security boundary starts—not inside the prompt you give Claude, Codex, or another agent, but in the identity Oleander sees when that agent makes a request.

You could, of course, give the agent a broad administrative role with access to everything.

You could also give everyone the root password.

Both are technically valid configuration choices.

But if this agent only needs to analyze data in a specific warehouse namespace, there is very little reason for it to also manage users, modify unrelated datasets, or delete production resources.

So let’s give it only what it actually needs.

Creating a Role for the Agent

Go to:

Settings → Organization → Roles

Click Create role, give the role a name, and define the permissions it should have.

For example, you might create a role that allows an agent to read tables and perform analytical operations within a particular Iceberg namespace, while leaving everything else ungranted.

That means granting select on the namespace and execute on the compute engine it needs to run queries. Compute permission lets the agent run a query; namespace permission determines which data it can read. It needs both.

The important part is that these are actual permissions enforced by Oleander. They are not suggestions presented to the model in natural language.

Once the role is created, open the three-dot menu on the right and select Assign users. From there, assign the role to the agent user you just created.

Now the agent has an identity, and that identity has a clearly defined set of permissions. Keep its other role assignments in mind, too: permissions from all assigned roles add up.

We have not told the agent:

PLEASE ONLY ACCESS THIS NAMESPACE.

We have made every other namespace inaccessible to it.

That is a much stronger sentence.

Logging In from Your Agent

Now connect Claude, Codex, or whatever agent you use to Oleander MCP and start the login flow.

Sign in to Oleander with your human account. On the MCP authorization screen, choose An agent, select the agent user you created, and approve the connection.

And that’s it.

From this point on, every Oleander API request made through that MCP session is authenticated as that agent user. The agent can call tools, make plans, change its mind halfway through a task, misunderstand your instructions, or become extraordinarily confident about something completely wrong.

It still cannot exceed the permissions attached to its identity.

If its role allows it to read from namespace A but not namespace B, namespace B is unavailable.

If its role allows reads but not deletes, it cannot delete.

If it tries anyway, Oleander returns 403 Forbidden.

The agent does not get a vote.

And this is the kind of guardrail we actually want.

Not a sentence in a prompt that says:

PLEASE DO NOT ACCESS SENSITIVE DATA.

Not another paragraph explaining that production databases are very important and should be treated with respect.

Not a carefully engineered reminder that dropping tables may have undesirable consequences for the organization.

A permission boundary.

Something deterministic, inspectable, auditable, and enforced outside the model.

Guardrail prompts can still be useful. They can guide behavior, reduce unnecessary failures, and make an agent behave more sensibly. But they should not be the thing standing between a probabilistic model and a destructive operation.

We already spent decades learning this lesson with humans and traditional software.

AI agents do not invalidate it.

They just give us another kind of user to apply it to.

So yes, let the agent reason. Let it use tools. Let it automate the tedious work. Let it do things that would have taken you three days in four minutes and thirty-seven seconds.

Just don’t confuse autonomy with authority.

Give it an identity.

Give that identity the minimum roles it needs.

And let the access-control system be the one thing in the room that does not care how intelligent the agent thinks it is.