logoalt Hacker News

Ask HN: How do you safely give LLMs SSH/DB access?

54 pointsby nicoyesterday at 7:06 PM78 commentsview on HN

I have been using Claude Code for DevOps style tasks like SSHing into servers, grepping logs, inspecting files, and querying databases

Overall it's been great. However, I find myself having to review every single command, a lot of which are repetitive. It still saves me a ton of time, but it's quickly becoming a bit tedious

I wish I could give the agent some more autonomy. Like giving it a list of pre-approved commands or actions that it is allowed to run over ssh

For example:

    OK: ls, grep, cat, tail
    Not OK: rm, mv, chmod, etc
    OK: SELECT queries
    Not OK: INSERT, DELETE, DROP, TRUNCATE
Has anyone successfully or satisfactorily solved this?

What setups have actually worked for you, and where do you draw the line between autonomy and risk?


Comments

drewgregoryyesterday at 8:50 PM

I am very passionate about this question - so much so that I happened make a blog post about it yesterday!

I recommend giving LLMs credentials that are extremely fine-grained, where the credentials can only permit the actions you want to allow and not permit the actions you don't want to allow.

Often, it may be hard or impossible to do this with your database settings alone - in that case, you can use proxies to separate the credentials the LLM/agent has from the credentials that are actually made to the DB. The proxy can then enforce what you want to allow or block.

SSH is trickier because commands are mixed in with all the other data going on in the bytestream during your session. I previously wrote another blog post about just how tricky enforcing command allowlists can be as well: https://www.joinformal.com/blog/allowlisting-some-bash-comma.... A lot of developer CLI tools were not designed to be run by potentially malicious users who can add arbitrary flags!

I also have really appreciated simonw's writing on the topic.

Disclaimer: I work at Formal, a company that helps organizations use proxies for least privilege.

show 2 replies
fhubyesterday at 8:53 PM

Our solve is to allow it to work with a local dev database and it's output is a script. Then that script gets checked into version control (auditable and reviewed). Then that script can be run against production. Slower iteration but worth the tradeoff for us.

Giving LLM even read access to PII is a big "no" in my book.

On PII, if you need LLMs to work on production extracted data then https://github.com/microsoft/presidio is a pretty good tool to redact PII. Still needs a bit of an audit but as a first pass does a terrific job.

show 3 replies
JoshTriplettyesterday at 8:24 PM

Don't.

Among the many other reasons why you shouldn't do this, there are regularly reported cases of AIs working around these types of restrictions using the tools they have to substitute for the tools they don't.

Don't be the next headline about AI deleting your database.

show 3 replies
jedbergyesterday at 11:11 PM

Use tool calling. Create a simple tool that can do the calls that are allowed/the queries that are allowed. Then teach the LLM what the tools can do. Allow it to call the tool without human input.

Then it will only stop when it wants to do something the tool can't do. You can then either add that capability to the tool, or allow that one time action.

show 1 reply
simonwyesterday at 8:17 PM

For database stuff most databases like PostgreSQL have robust permissions mechanisms built in.

No need to mess around with regular expressions against SQL queries when you can instead give the agent a PostgreSQL user account that's only allowed read access to specific tables.

show 1 reply
Rover222today at 1:01 AM

It’s scary enough giving access just to my local database. Claude has found inventive ways to twice wipe out my tables this week, despite Claude.md instructions to the contrary.

(Of course I’m also to blame)

show 1 reply
PaulHouleyesterday at 8:33 PM

See https://simonwillison.net/2025/Feb/3/a-computer-can-never-be...

I'll set it loose on a development or staging system but wouldn't let it around a production system.

Don't forget your backups. There was that time I was doing an upgrade of the library management system at my Uni and I was sitting at the sysadmin's computer and did a DROP DATABASE against the wrong db which instantly brought down the production system -- she took down a binder from the shelf behind me that had the restore procedures written down and we had it back up in 30 seconds!

dormentoyesterday at 8:36 PM

> Safely

You cannot. The best you can ever hope for is creating VM environments, and even then it's going to surprise you sometimes. See https://gtfobins.github.io/.

zachmuyesterday at 9:26 PM

We build DoltDB, which is a version-controlled SQL database. Recently we've been working with customers doing exactly this, giving an AI agent access to their database. You give the agent its own branch / clone of the prod DB to work on, then merge their changes back to main after review if everything looks good. This requires running Dolt / Doltgres as your database server instead of MySQL / Postgres, of course. But it's free and open source, give it a shot.

https://github.com/dolthub/dolt

cortesoftyesterday at 8:57 PM

For DB access, use an account with the correct access level you want to grant.

For SSH, you can either use a specific account created for the AI, and limit it's access to what you want it to do, although that is a bit trickier than DB limits. You can also use something like ForceCommand in SSHD config (or command= in your authorized_keys file) to only grant access to a single command (which could be a wrapper around the commands you want it to be able to access).

This does somewhat limit the flexibility of what the AI can deal with.

My actual suggestion is to change the model you are using to control your servers. Ideally, you shouldn't be SSHing to servers to do things; you should be controlling your servers via some automation system, and you can just have your AI modify the automation system. You can then verify the changes it is making before committing the changes to your control system. Logs should be collected in a place that can be queried without giving access to the system (Claude is great at creating queries in something like ElasticSearch or OpenSearch).

Terr_yesterday at 7:22 PM

I imagine your best bet are exactly the same tools for a potentially-malicious human user: Separate user account, file permissions, database user permissions, etc.

show 1 reply
nltoday at 12:02 AM

I wrote my own agent where everything happens over SSH.

The shell is SSH, the read_file and write_file tool calls are over SSH

Then I give it a disposable VM and let it go.

There are lots of other solutions, but it's an interesting problem to work on.

arjieyesterday at 10:09 PM

For the database, I use a read-only user. I also give it full R/W to a staging DB and the local dev DB. Even if it egresses that, nothing can happen.

SSH I just let it roll because it's my personal stuff. Both Claude and Codex will perform unholy modifications to your environment so I do the one bare thing of making `sudo` password-protected.

For the production stuff I use, you can create an appropriate read-only role. I occasionally let it use my role but it inevitably decides to live-create resources like `kubectl create pod << YAML` which I never want. It's fine because they'll still try and fail and prompt me.

show 1 reply
frioyesterday at 10:06 PM

I do wonder if LLMs will see tools like immudb (https://immudb.io/) or Datomic (https://www.datomic.com/) receive a bit more attention. The capacity to easily rollback the state to a previous immutably preserved state has always seemed like a fantastic addition to databases to me, but in the era of LLMs, even more important.

helsinkitoday at 12:02 AM

Jump host with restricted commands / access. Agents SSH into a jump host and execute what they are allowed to execute.

cadamsdotcomyesterday at 9:26 PM

Appropriate fine grained permissions, or a readonly copy.

This is nothing new; it’s the logical thing for any use case which doesn’t need to write.

If there is data to write, convert it to a script and put it through code review, make sure you have a rollback plan, then either get a human or non-AI automation tooling to run it while under supervision/monitoring.

Again nothing new, it’s a sensible way to do any one-off data modification.

show 1 reply
tobyhinloopenyesterday at 10:43 PM

A great start is to have LLMs use special UNIX users that can’t do anything except that you allowed them to do, including accessing the database with a read only user.

throwaway140126yesterday at 10:19 PM

I just want to share my thoughts about this topic:

Personally I think the right approach is to treat the llm like a user.

So if we pretend that you would like to grant a user access to your database then a reasonable approach would be to write a parser (parsing > validating) to parse the sql commands.

You should define the parser such that it only uses a subset of sql which you consider to be safe.

Now if your parser is able to parse the command of the llm (and therefore the command is part of the subset of sql which you consider to be safe) then you execute the command.

e12eyesterday at 9:16 PM

For ssh/shell - set up a regular user, and add capabilities via group membership and/or doas (or sudo).

You want to limit access to files (eg: regular user can't read /etc/shadow or write to /bin/doas or /bin/sh) - and maybe limit some commands (/bin/su).

Curzelyesterday at 8:38 PM

For db just give it credentials of a readonly user, for instructions you can do this. You can give setup a list of approved tools and bash commands https://www.anthropic.com/engineering/claude-code-best-pract...

show 1 reply
stephendauseyesterday at 7:11 PM

There is an example of [dis]allowing certain bash commands here: https://code.claude.com/docs/en/settings

As for queries, you might be able to achieve the same thing with usage of command-line tools if it's a `sqlite` database (I am not sure about other SQL DBs). If you want even more control than the settings.json allows, you can use the claude code SDK.

show 1 reply
al_borlandyesterday at 8:44 PM

You could setup permissions on the user Claude is using to only be able to run those commands. But that may be easier said than done, depending on the size of your environment and the management tools you have.

christophilusyesterday at 7:21 PM

I run my agents in containers, and only put stuff in those containers that I'm happy obliterating.

show 1 reply
lifetimerubyisttoday at 12:33 AM

You run the agent in a rootless container, all files are mounted via read-only filesystem mounts and you give the database user only select privileges.

You secure your LLM the same way you’d secure any other user on your system.

vindex10yesterday at 8:38 PM

for files, possibly sshfs / fuse with readonly mount

https://stackoverflow.com/questions/35830509/sshfs-linux-how...

rcarmoyesterday at 9:08 PM

I build MCP servers that limit the LLM to specific commands.

hiccuphippoyesterday at 9:10 PM

Give them a read-only account.

j45yesterday at 11:20 PM

Asking non-deterministic software to only behave like deterministic software in certain case magically is the thing to reflect on.

If we want it to be 100% safe, you probably don't ever do it with non-deterministic layers alone.

- Creating tools and tool calling helps

- Claude code specifically asks permissions to run certain commands in certain folders and keeps a list of that. Chances are that is an actual hard filter locally when the llm recommends a command.

This would be creating a deterministic layer to keep the non-deterministic layer honest. This is mandatory because ai models don't return the same level of smarts and intelligence all the time.

- Another step that can help is layering the incoming request and the command sent to the CLI between more layers and checks and no direct links to dilute any prompt injection, etc.

bigstrat2003yesterday at 10:28 PM

You don't.

smashahyesterday at 11:08 PM

I think this is a good opportunity for a tool like warpgate. It has an API to create unique ssh sessions for one time use.

I've just rolled an instance but it's quite powerful in terms of control. I imagine it would be fairly simple to implement an MCP user group which is barred from using some commands. If a barred command is run the session disconnects.

almostheretoday at 12:07 AM

have it only write python code and run it, disallow it to ever delete or update data in a database.

QuadmasterXLIIyesterday at 9:02 PM

Tell claude that you have to manually review every single command, and this is very expensive. It will pivot to techniques that achieve tasks with many fewer commands / lines of code. Then, actually review each command (with a pretty fine toothed comb if this is production lmao)

singleshot_yesterday at 10:40 PM

> OK: ls, grep, cat, tail

cat /dev/random > /dev/sda

Uh oh…

show 1 reply
gunalxyesterday at 8:22 PM

Never gibe perms to begin with. Anything the chatbot has access to fuckup it eventually will. So the problem is inherently flawed, but.

Use db permissions with read only, and possibly only a set of prepared statements. Give it a useraccount with read-only acces maybe

jrflowersyesterday at 9:16 PM

Only give LLMs SSH access to a machine that you wouldn’t mind getting randomly thrown into the ocean at any moment. Easy peasy

einpoklumyesterday at 9:08 PM

This is not possible, because systems like "Claude Code" are inherently and fundamentally insecure. Only for models which are open source and with some serious auditing, does the possibility of security even appear.

Also, about those specific commands:

* `cat` can overwrite files. * `SELECT INTO` writes new data.

TZubiriyesterday at 10:01 PM

in posix compatible systems (linux)

adduser llm su llm

There you go. Now you can run commands quite safely. Add or remove permissions with chmod chown and chgrp as needed.

If you need more sophisticated controls try extensions like acl or selinux.

In windows use its builtin use, roles and file permission system.

Nothing new here, we have been treating programs as users for decades now.

cambooyesterday at 8:45 PM

Tl;dr you don’t give your llm ssh access. You give it tools that have individual access to particular executions.

—-

Yes, easily. This isn’t a problem when using a proxy system with built in safeguards and guardrails.

‘An interface for your agents.’

Or, simply, if you have a list of available tools the agent has access to.

Tool not present? Will never execute.

Tool present? Will reason when to use it based on tool instructions.

It’s exceptionally easy to create an agent with access to limited tools.

Lots of advice in this thread, did we forget that ithe age of AI, anything is possible?

Have you taken a look at tools such as Xano?

Your agent will only execute whichever tool you give it access to. Chain of command is factored in.

This is akin to architecting for the Rule of Two, and similarly is the concept of Domain Trusts (fancy way of saying scopes and permissions).

bitbytebaneyesterday at 8:55 PM

[flagged]