How to be more productive with Claude Code, part 1

How to be more productive with Claude Code: taking advantage of Linux permissions and that media server in your living room to achieve safer AI productivity, 24-7

A personal server, a small grey box with USB ports and Ryzen and Radeon logos

The goal: accomplish what we'd never have time for otherwise

As the CEO of a small, busy company, I don't have time to write code. This is sad, because I love code. I've been writing it for decades.

However, I do have time to serve as software architect. And you can bet I have time to review code. If you don't think you have time to review code, just try not reviewing it.

In other words, I'm ideally suited to code with AI:

  • I understand the need to provide clear guidance and patient correction.
  • I'm well-qualified to judge the result.

So while our team stays focused on new features for ApostropheCMS, I've sought out ways to plug gaps and achieve things that just wouldn't be on our roadmap without AI. I know you're here for the how-to, so I'll keep this brief, just so you know what I'm trying to achieve here:

  • Porting smaller client projects from ApostropheCMS 2.x to ApostropheCMS 4.x. The jump is a big one, because we made the decision to completely rewrite the CMS in version 3.x. Moving forward, the platform's architecture is stable. But, projects created before that time can be tough to transition.
  • Adding support for new databases... even though ApostropheCMS has been closely tied to MongoDB until now.
  • Quick "sales engineering" projects, like variations on our multisite public demo that are tailored for particular audiences.

The problem: Claude Code requires lots of handholding

Out of the box, Claude Code requires a lot of attention.

Hey, can I create this folder? Read this file? Run this script? Kill this process? Delete your entire hard drive? Huh? Can I?

You can say "yes, and allow similar commands," but this doesn't stop all the prompts, nor does it feel particularly safe.

I wanted to move faster, so I went looking for a way to unlock that.

Options I rejected (for me): Claude Code for Web and the sandbox

Two options I didn't go with are worth a closer look. They might be right for others.

Claude Code for Web is a completely web-hosted version of Claude Code. You access it from the regular Claude Code chat and give it access to your code repository in a way that doesn't allow it to interact further with your repository on its own... so it's safe, as far as git goes.

Is it useful? Sure, as long as your task is largely self-contained. Claude Code for Web is designed for simple use cases: here are my tests, here is my mock data, here is my code. Iterate and improve until the tests pass.

But it's not really designed for running services like databases that are also part of your system. And its access to the outside world is intentionally extremely limited. Recent bug reports suggest even the "allow list" functionality has issues at the moment, and when it works, that feature only allows HTTP/HTTPS access. Connecting to MongoDB or Postgres running on another box is just not practical. Running them locally within Claude Code for Web may be possible, but the path forward is unclear.

ApostropheCMS needs a database (at least while creating content), so this didn't feel like the right answer for me.

The Claude Code sandbox


Claude Code also offers a built-in sandbox feature. This sounds more like it: run it on your own machine, but restrict the folders it can write to.

Alas, while it can only write to certain folders, it can read to every folder you don't individually exclude. And of course it can see all those juicy environment variables you might be deliberately exposing in your .bashrc so you can get work done. In terms of risk: exfiltrating your Claude API key is one thing, but exfiltrating your git and npm credentials is another. So from a security standpoint, this also doesn't feel like the answer.

Also, I'd prefer not to run long-running Claude Code jobs on my desktop. I'd rather run it on a machine that stays turned on, rather than a laptop that might be closed.

My solution: good old Unix permissions on my media server

The answer that did it for me: plain old Unix group permissions. Here's the recipe:

  • ssh into that media server you've got in your living room. You know, the one with 16GB of RAM and an AMD Ryzen processor and a 512GB hard drive that cost you, like, $250. Not bad for respectable specs. If you price this as a VPS online, you'll be out $250 in less than three months. Plus it's a lot harder to crack from the outside.
  • Install any services you might need for your work, like postgres, or mongodb community edition. In the case of databases, decide whether these are purely for your AI coding work, in which case you can leave them secured only by restriction to localhost, or whether you need them for other purposes on the box, in which case you'll need to assign passwords to your databases.
  • Now create two accounts. Let's call them human and ai.
  • Add them to a devteam group.
  • Remove ai from the default users group. It's not used for much, but it doesn't hurt to play it safe.
  • Leave each user in its own personal group, though (Linux creates a namesake group for each user, and gives the home directory to that group).
  • In .bashrc, set umask 0007 so that all new files turn out writable by the group that owns them. For files in the home directory, this will be the user's private group, so this is safer than it sounds.
  • Create a folder named /srv/workspace.
  • Use chown human:devteam to give that folder to the devteam group, so that both users can write to it.
  • Use chmod g+s /srv/workspace to make sure new files and folders there are also given to the devteam group.
  • Set up your ssh public key in ~/.ssh/authorized_keys for both accounts. This allows you to ssh into them without a password.
  • ssh into human and set up your github credentials there as you normally would. The AI won't be able to see these.
  • As human, cd to /srv/workspace, and git clone and npm install to your heart's content. It wouldn't hurt to run chmod -R human:devteam . after running npm install, which sometimes makes strange permissions choices.
  • As ai, install Claude Code. Then cd to /srv/workspace/your-project-here and get down to work.
  • To avoid prompts, use: claude --dangerously-skip-permissions
  • ai can't see your git credentials... which is a GOOD thing. So tab over to the human account to review the changes before you commit and push. In order to make a PR for more review. By a coworker. Right? I hope?

"Hey, what about vscode? I'm not a big vim person."

Good question. To use vscode, or your visual editor of choice, just use the "Remote SSH" vscode extension. Press Shift-Command-P, open a connection to human@vcs (because you're an old school Atari nerd like me, so you named your media server that) and you're off to the races, reading and modifying files as the human user. You can use the vscode terminal, the git integration, all the goodies.

"Hey, is this secure?"

There is one important hole. By default, this setup allows the AI to make outgoing connections. The main danger there is that:

  • Someone, somewhere, hacks an everyday npm module we all depend on and it slips by.
  • You install it as the human user, making it available to the ai user.
  • That hack somehow manages to prompt-engineer Claude Code into POSTing your source code, or your Claude API key, to a black hat server somewhere. Such a hack is always at least possible because Claude Code must read the output of your program to do its job.

The rest of your secrets are safe because you don't give the AI more credentials than it needs. But it obviously needs access to Claude itself... and your project code.

The code I allow this tool to work on is often open source. The rest of the time, it is still ultimately intended for paying customers to access. So in my case, most of the value of the code isn't in having a random old exfiltrated copy — there are other ways that could happen anyway. The value is in the support, warranty, and other services we provide to our customers.

Of course, it's vitally important not to store secrets in our repository source code. Use environment variables for that, and don't set them for the ai user.

As for the claude API key, I'm a flat-rate monthly plan user. If my key is somehow compromised, I'll see the spike in usage and lock it down. At worst I'll have to wait... and figure out what module was compromised.

But if this isn't secure enough for your needs, you can consider using ordinary Linux firewall commands. Those are difficult to use for public API services, so a better plan might be to implement Squid Proxy and block all outgoing connections except to the proxy. Then you can restrict destinations through Squid Proxy.

Or... yes, you might be a customer for Claude Code for Web after all.

"If I run it in my house, how do I connect on the road?"

One word: tailscale. I could go on, but really. That's it. Check it out, try it out, weep with joy. And no, they're not paying me to say this.

I've purchased a bluetooth keyboard for my shoulder bag just so I can talk to Claude Code from my Android phone, running the excellent termux app. For long-running Claude Code sessions that need to hop from your work Mac to your personal Linux laptop to your smartphone, I recommend running tmux on your server (no relation to termux).

What's Next

In my next post, I'll dig into the techniques I find most effective in my day-to-day work with Claude Code. A hint: developing web apps and websites with Claude Code can hit a wall unless you give it "hands and eyes" to see and improve upon the work.

 

Pricing