{"slug": "use-vs-code-and-claude-code-on-a-lens-agents-sandbox", "title": "Use VS Code and Claude Code on a Lens Agents sandbox", "summary": "Lens Agents 0.34.0 added SSH access to its sandboxes, letting developers run VS Code Remote-SSH and the Claude Code extension inside a sandbox with default-deny egress instead of on their laptops. The setup uses `nexusctl sandbox ssh-proxy` as an OpenSSH ProxyCommand, so each SSH session becomes one exec in the sandbox authenticated with the user's Lens Agents login, with no sshd in the image and no open port; the sandbox requires the ADMIN role on the project and a fine-grained GitHub token scoped to the agent's repositories. The VS Code server, extensions, repositories and Claude Code login persist on a 30Gi home volume, and the sample policy allows only GitHub, Anthropic and Visual Studio Marketplace domains before a catch-all allow rule.", "body_md": "**TL;DR**\n\n- VS Code Remote-SSH runs the editor UI on your laptop and the rest, including the terminal and most extensions, on the remote host.\n- A Lens Agents sandbox speaks SSH through `nexusctl` , so it can be that remote. No sshd in the image, no open port.\n- The result: the Claude Code extension works as usual, but it runs in a sandbox with default-deny egress, not on your laptop.\n\nA coding agent in your editor is convenient. It also runs with everything your editor can reach: your files, your SSH keys, your cloud credentials, and an open network.\n\nVS Code already knows how to put the work somewhere else. This post puts it in a Lens Agents sandbox.\n\n## How the pieces fit\n\nWith Remote-SSH, VS Code installs a small server on the remote host. The window on your laptop draws the UI. The terminal, the file system, language servers, and most extensions run in that server. The Claude Code extension is one of them, so the agent, its tools, and its commands all run on the remote side.\n\nRemote-SSH uses plain OpenSSH, and a Lens Agents sandbox doesn't run an SSH server. Instead, `nexusctl sandbox ssh-proxy` acts as one on your machine, as an OpenSSH `ProxyCommand`. Each SSH session becomes one exec in the sandbox, authenticated with your Lens Agents login. Remote-SSH also needs a local port forward to its server, and the proxy supports that too.\n\n## What you need\n\n- Lens Agents 0.34.0 or later. SSH access to sandboxes arrived in that release. If you don't have a platform yet, follow the [getting started guide](https://docs.lenshq.io/lens-agents/getting-started/) .\n- `nexusctl` , installed from your Lens Agents platform and logged in with`nexusctl auth login` .\n- The ADMIN role on the project where the sandbox lives. SSH access requires it.\n- VS Code with the [Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) extension.\n- A [fine-grained GitHub token](https://github.com/settings/personal-access-tokens/new) with access to only the repositories the agent works on.\n\n## Step 1: Define the sandbox\n\nThe sandbox is a home directory on a persistent volume. The VS Code server and its extensions install into `$HOME`, so they survive a restart, and so do your repositories and the Claude Code login.\n\n```\nname: VS Code Box\nimage: ubuntu:24.04\ncommand: sleep infinity\ncpu: \"4\"\nmemory: 16Gi\n\nuser: ubuntu\nworkdir: /home/ubuntu/work\n\nvolumes:\n  - mountPath: /home/ubuntu\n    size: 30Gi\n\nscripts:\n  - when: pre-start\n    description: install base packages\n    user: root\n    run: |\n      apt-get update -qq\n      DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \\\n        curl git ca-certificates unzip xz-utils less >/dev/null\n  - when: pre-start\n    description: give the home volume to the agent user\n    user: root\n    run: chown ubuntu:ubuntu /home/ubuntu\n  - when: pre-start\n    description: set up the shell\n    run: \"[ -f ~/.bashrc ] || cp -rT /etc/skel ~\"\n\npolicy:\n  name: VS Code Box\n  networkDefaultVerdict: deny\n  allowedDomains:\n    - { pattern: github.com, verdict: allow, transport: direct }\n    - { pattern: \"*.github.com\", verdict: allow, transport: direct }\n    - { pattern: \"*.githubusercontent.com\", verdict: allow, transport: direct }\n    - { pattern: api.anthropic.com, verdict: allow, transport: direct }\n    - { pattern: console.anthropic.com, verdict: allow, transport: direct }\n    - { pattern: claude.ai, verdict: allow, transport: direct }\n    - { pattern: platform.claude.com, verdict: allow, transport: direct }\n    - { pattern: mcp-proxy.anthropic.com, verdict: allow, transport: direct }\n    - { pattern: update.code.visualstudio.com, verdict: allow, transport: direct }\n    - { pattern: \"*.vscode-cdn.net\", verdict: allow, transport: direct }\n    - { pattern: marketplace.visualstudio.com, verdict: allow, transport: direct }\n    - { pattern: \"*.vsassets.io\", verdict: allow, transport: direct }\n    - pattern: \"*\"\n      verdict: allow\n      transport: direct\n      description: Read-only internet\n      rules:\n        - { method: GET }\n        - { method: HEAD }\n  credentials:\n    - { credentialName: gh-token, envVarKey: GH_TOKEN }\n\ncredentials:\n  gh-token:\n    value: ${GH_TOKEN}\n    injections:\n      - domain: api.github.com\n        headerName: Authorization\n        headerFormat: \"Bearer {value}\"\n      - domain: github.com\n        headerName: Authorization\n        headerFormat: \"Basic {base64:x-access-token:{value}}\"\n```\n\nA few things to note:\n\n- **`command: sleep infinity`** keeps the sandbox up. VS Code starts its own server the first time you connect.\n- **`ubuntu:24.04`** is the official image. It has no curl or git, so the first script installs them as root. The agent user must exist in the image, and`ubuntu` does.\n- **The VS Code domains** let the server download itself and let you install extensions from the Marketplace. The Claude Code extension brings its own copy of Claude Code, so the image needs nothing else.\n- **`mcp-proxy.anthropic.com`** carries the connectors of your Claude account, such as Slack or Google Drive. Without it, Claude Code works, but those connectors fail. With it, the agent in the sandbox can use those connectors with your access, so add it only if you want that.\n- **The policy denies by default.** For the rest of the internet, only`GET` and`HEAD` pass, which cuts off the obvious upload paths. You will see VS Code and extension telemetry denied in the sandbox log. That's expected, and nothing breaks.\n- **The GitHub token never enters the sandbox.**`$GH_TOKEN` inside the sandbox holds a placeholder. The real token is added to requests to GitHub at the platform boundary.\n\n## Step 2: Create the sandbox\n\n```\nread -rs GH_TOKEN && export GH_TOKEN\nnexusctl sandbox create --project <org>/<project> -f sandbox.yaml\n```\n\nPaste the token at the prompt. `read -s` keeps it off the screen and out of your shell history, and `create` expands `${GH_TOKEN}` from your environment.\n\n## Step 3: Make the sandbox an SSH host\n\nLet `nexusctl` write the SSH config entry for every sandbox in the project:\n\n```\nnexusctl sandbox ssh-config --project <org>/<project> >> ~/.ssh/config\n```\n\nThe entry matches `*.<project>.<org>.nexus` and routes through `ssh-proxy`:\n\n```\nHost *.<project>.<org>.nexus\n  User sandbox\n  ProxyCommand nexusctl sandbox ssh-proxy %n --project <org>/<project> --server <url>\n  StrictHostKeyChecking no\n  UserKnownHostsFile /dev/null\n  LogLevel ERROR\n```\n\nHost key checking is off because the proxy is a local process with a throwaway key. Trust comes from your Lens Agents login and TLS to the platform, not from the SSH host key.\n\n**Use the full path to `nexusctl`.** VS Code runs the `ProxyCommand`, and an app started from the Dock or the Start menu may not have your shell's `PATH`. If the connection fails with `command not found: nexusctl`, replace `nexusctl` in the entry with the output of `command -v nexusctl`.\n\nCheck that plain SSH works first:\n\n```\nssh <sandbox>.<project>.<org>.nexus 'uname -a'\n```\n\n## Step 4: Connect VS Code\n\nIn VS Code, run **Remote-SSH: Connect to Host…** from the Command Palette and type `<sandbox>.<project>.<org>.nexus`. Pick **Linux** if VS Code asks for the platform. The first connection installs the VS Code server in the sandbox, so give it a minute.\n\nThen open the Extensions view and install Claude Code. VS Code installs it in the sandbox, not on your laptop. Sign in once. The login is stored on the volume, so it stays after a restart.\n\nOpen a folder under `/home/ubuntu/work`, clone a repository, and start a Claude Code session. The agent edits files, runs commands, and pushes to GitHub, all inside the sandbox.\n\n### Keep the token out of the sandbox\n\nVS Code can also give Git your GitHub login from your laptop. If the sandbox has no GitHub credential, a clone or push asks VS Code, and VS Code sends your own token into the sandbox. That works, but the real token is then in the sandbox, with all the access your GitHub login has, and the agent can ask VS Code for it too.\n\nWith the credential in the spec, the platform adds the token to every request to GitHub, so Git never needs to ask VS Code. VS Code still offers your login to the sandbox, though, so turn that off in your VS Code settings:\n\n```\n{\n  \"git.terminalAuthentication\": false,\n  \"github.gitAuthentication\": false\n}\n```\n\n## What the sandbox adds\n\nVS Code gives you the editor you already use. The sandbox decides what the agent in it can do:\n\n- **Off your laptop.** The agent runs in the sandbox, so it can't read your files, SSH keys, or cloud credentials.\n- **Default-deny egress** with per-domain, per-method rules, enforced outside the agent.\n- **No secrets in the sandbox.** Secrets that you store in Lens Agents, such as the GitHub token, reach the agent only as placeholders. The real values are added at the boundary. Your Claude login is different: it is stored on the sandbox volume, as on any machine where you log in.\n- **Audit.** Every request the sandbox proxy handles is recorded, with the policy decision.\n\nYour workflow stays the same: the same editor, the same extension, the same keybindings. Only the place the agent runs changes.\n\nWhen the connection drops, for example when you close the laptop, the agent keeps working for 3 hours by default. To change that, set `remote.SSH.reconnectionGraceTime` (in seconds) in your VS Code settings. The new value applies the next time the VS Code server starts in the sandbox.\n\nIf you prefer to work in terminals, see [how to run coding agents in herdr on a Lens Agents sandbox](https://lenshq.io/blog/herdr-on-lens-agents/).\n\n## Run your coding agents governed\n\nRun Claude Code, Codex and other compatible agents with identity, policy, and audit built in.\n\n## FAQ\n\n**Does the sandbox need an SSH server?**\n\nNo. `nexusctl sandbox ssh-proxy` acts as the SSH server on your machine and turns each SSH session into an exec in the sandbox.\n\n**Do other VS Code extensions work?**\n\nExtensions that run on the remote side install in the sandbox and follow its policy. If an extension needs a service the policy doesn't allow, the request is denied and shows in the sandbox log. Add the domain to `allowedDomains` if you trust it.\n\n**Can I use SSH agent forwarding for Git inside the sandbox?**\n\nNo. The proxy refuses agent forwarding. Use a token credential instead, as in the example: the sandbox sees a placeholder and the platform adds the real token to requests to GitHub.\n\n**What happens to my work when the sandbox restarts?**\n\nThe home volume stays, so repositories, the VS Code server, extensions, and the Claude Code login stay too. Connect again, and VS Code picks up where it was.", "url": "https://wpnews.pro/news/use-vs-code-and-claude-code-on-a-lens-agents-sandbox", "canonical_source": "https://lenshq.io/blog/vscode-on-lens-agents/", "published_at": "2026-10-29 00:00:00+00:00", "updated_at": "2026-10-29 11:48:32.464314+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-safety"], "entities": ["Lens Agents", "nexusctl", "Visual Studio Code", "Claude Code", "Anthropic", "GitHub", "Microsoft", "Ubuntu 24.04"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/use-vs-code-and-claude-code-on-a-lens-agents-sandbox", "markdown": "https://wpnews.pro/news/use-vs-code-and-claude-code-on-a-lens-agents-sandbox.md", "text": "https://wpnews.pro/news/use-vs-code-and-claude-code-on-a-lens-agents-sandbox.txt", "jsonld": "https://wpnews.pro/news/use-vs-code-and-claude-code-on-a-lens-agents-sandbox.jsonld"}}