ATALAIA
  1. Home
  2. Resources
  3. Blog
  4. The IDE extension problem
AI & tooling · Deep dive

The IDE extension problem

Editor extensions run as your code, with your files and your tokens. How they work, how to inventory them, and how to build an allowlist people will accept.

4 min readAtalaia team

IDE extensionsDeveloper laptopsAllowlists

Teams that scan every dependency in a lockfile will often let developers install any editor extension they like. Yet an extension sits closer to the crown jewels than most packages: it runs on the laptop that holds the source code, the SSH keys and the cloud credentials, every working day.

This post explains how extensions actually work, what they can reach, and a practical way to get an inventory and an allowlist in place without starting a fight.

How editor extensions run

In most popular editors, extensions are packages of JavaScript, sometimes with native binaries, that the editor loads into an extension host process. That process runs as the logged-in user. There is usually no per-extension permission prompt like a phone app would show.

In practice an extension can:

  • Read and write any file the user can, not only files in the open workspace.
  • Spawn processes, including shells, compilers and package managers.
  • Make outbound network requests to any host.
  • Read environment variables, which often include tokens exported in a shell profile.
  • Access editor-stored secrets and settings, and hook into terminals and source control.

Some editors offer a restricted mode for untrusted workspaces, which limits what runs when you open an unfamiliar folder. That is useful, but it protects against hostile repositories, not against an extension you already installed and trust.

The update path is the real risk

An extension you reviewed last year is not the extension running today. Marketplaces push updates automatically by default, and publisher accounts can change hands or be compromised. The pattern mirrors package registry attacks.

  1. TrustA useful extension gains a large install base over time.
  2. ChangeThe publisher account is sold, phished or handed to a new maintainer.
  3. UpdateA new version ships with extra code. Editors install it silently.
  4. RunOn next launch it executes with the developer's permissions across every machine that has it.
  5. ReachIt reads tokens, keys or source and sends them outward.

Lookalike names are the other route: an extension with a familiar icon and a name one character off from a popular one. Both are reasons why "it came from the marketplace" is not a review.

Inventory extensions across a team

You cannot allowlist what you have not seen. Start by collecting what is installed today. Most editors in the VS Code family expose a CLI for this:

# List installed extensions with versions
code --list-extensions --show-versions

# Extensions also live on disk, one folder per extension@version
ls ~/.vscode/extensions

JetBrains IDEs keep plugins in a per-version folder under the user's config or application support directory, and other editors follow similar patterns. Write a small script that collects the list and the hostname, and ask people to run it, or push it through your device management tool if you have one.

#!/usr/bin/env sh
# collect-extensions.sh: print host, editor and extension@version as CSV
host=$(hostname)
for cli in code codium cursor; do
  command -v "$cli" >/dev/null 2>&1 || continue
  "$cli" --list-extensions --show-versions 2>/dev/null \
    | sed "s/^/$host,$cli,/"
done

Combine the outputs into one sheet and sort by extension ID. You will typically see a long tail: a core set most people share, and many single installs.

Build an allowlist people will accept

An allowlist that blocks half the team on day one will be routed around. Build it from the inventory instead.

BucketWhat goes inAction
CoreLanguage support, linters, formatters used by manyReview once, approve, pin publisher ID
Niche but justifiedTools a few people need for their workQuick review, approve per team
UnknownSingle installs nobody can explainAsk the owner; remove if unused
RiskyUnverified publisher, obfuscated code, broad network use with no clear reasonRemove and suggest an alternative

For each review, check the publisher, the source repository if there is one, install count and age, what it declares it activates on, and whether it bundles native binaries. Record the extension by its full ID, not its display name, so lookalikes do not slip through.

Several editors support policy settings that restrict installs to approved extensions or turn off auto-update. Use them once the list is stable, and consider staging updates for core extensions rather than taking every release the moment it ships.

What to do on Monday

  1. Run code --list-extensions --show-versions on your own machine and read the list. Anything you do not recognise?
  2. Share the collection script with the team and gather results in one place.
  3. Sort into the four buckets above. Approve the core set first; it covers most installs.
  4. Write a one-paragraph process for requesting a new extension, with a named reviewer and a short turnaround.
  5. Repeat the inventory monthly. Drift is the thing to watch, not the first snapshot.

Extensions are tools on the line like any other. Knowing which ones are on each bench, and who approved them, is the whole job.

Where this sits on the line

In the tower (in development):

Talk it through

A 30-minute call. No slides, no price list, and a next step either way.