envpilot — changelog

What's new in Envpilot

All the latest updates, improvements, and fixes. Follow along as we build.

❯ --filter
v1.17.2! fix# security

VS Code extension 1.17.2

A pull that hits a decryption failure or a truncated result now stops and writes nothing. Before, the literal text [DECRYPTION_FAILED] could end up in your .env.

Choosing "Skip" when linking a directory now really skips it: the directory is not stored, so nothing overwrites your existing file later. Removing a directory or losing access deletes only files whose contents still match what Envpilot wrote, and also removes synced secret files. A sync that was already in flight can no longer write secrets back after access was revoked.

Edits to a protected file are reverted immediately instead of waiting for you to dismiss the warning. Synced files are created with owner-only permissions (0600, read-only 0400).

Token refresh reads the stored session first, so two VS Code windows no longer sign each other out. A network blip during refresh is reported as a network error instead of "Session expired". Signing in, switching accounts and signing out all go through one path that clears cached permissions.

The commit guard now works on Windows, no longer blocks .env.example, .env.sample or .env.template, no longer blocks removing an already-committed .env from the index, and only installs into .git/hooks (repos that manage hooks with husky are left alone). Value cloaking covers export KEY= and indented lines.

Removed: the dashboard panel, the envpilot.syncInterval setting (it did nothing) and the Select Environments command (it was a placeholder).

v0.1.9! fix# security

JetBrains plugin 0.1.9

File drift detection now runs. It was registered under an extension point the platform does not have, so edits to synced files were never noticed. Value cloaking, the copy guard and hover now work on Windows.

"Delete unchanged pulled files when the IDE closes" is honored. Plugin updates no longer delete synced files from under a running dev server. Link state moved to the workspace file, so it is no longer written into .idea/ where it could be committed. Existing links migrate automatically.

Requests for a variable no longer fail on submit. Sync no longer runs a full pull on every window focus when auto-sync is off.

The Convex connection sends frames in order, queues calls while offline and sends them on reconnect, re-authenticates before the token expires, and shuts down when the plugin unloads. Sign-in polling can be cancelled, a second click is ignored, and the device code is shown. The plugin update block now applies to syncing, not only to Sign In.

Secret file paths that point at .git, .husky, .idea, .vscode or an env file are rejected on both the plugin and the server.

v0.1.8! fix

JetBrains plugin 0.1.8

The plugin no longer installs a JVM-wide crash handler. Before this release it reported crashes from the IDE and from other plugins (Docker, Gradle, Junie and more) as Envpilot errors, and could get in the way of those plugins' own handlers. Only errors from Envpilot's code are reported now.

Offline, timeout and expired-session failures are logged to idea.log instead of being sent as errors. A failed server query now carries the server's reason in the log.

v1.0.1! fix# security

Docker image 1.0.1

The image now ships a CA bundle, so pulls over HTTPS work from scratch and from base images without one (node:22-slim, debian:bookworm-slim).

The floating tag is now ghcr.io/rafay99-epic/envpilot:1, matching the docs. :v1 is not updated further.

Transient failures (502, 503, 504, connection errors) are retried with backoff; rate limits honor Retry-After as before.

pull --out never inherits an existing file's mode; the file is recreated at 0600.

Secret files with an unsupported mode or a size that does not match their metadata are refused instead of written.

v1.70.0+ feature

Share One Variable Across Projects

A variable can now be shared with other projects. One row, one vault object, every picked project reads it, so rotating a credential is one edit instead of six.

On a project's variables page, a row whose key also exists elsewhere shows "same key in N projects". Share it from there: projects holding the same value are preselected and their copies are adopted into the shared row, projects with a different value are listed but held back. Shared rows sit pinned above the table in every project that reads them, editable in place, with the number of affected projects on every confirm button. Stop sharing in one project and the current values are copied back so its next pull is unchanged.

Safety follows the projects, not the group. You can edit a shared row only if you could edit variables in every project it reaches. If any of those projects protects an environment, the edit, and the share itself, becomes a change request for a second person to apply. Each project gets its own audit entry and notification.

Sharing is off until an owner turns it on in Organization settings, and turning it off never breaks a pull. The same settings tab lists every key that is identical across projects and merges them in one click: development and staging on the spot, production through approval, anything with a different value held back with the reason. Identity is decided by a per-organization hash written at save time, so no vault reads are needed to find duplicates. Run the backfill-value-hashes migration once for variables saved before this release.

The CLI, the VS Code and JetBrains extensions, the REST API, the MCP server, the GitHub Action and the Docker image receive shared rows without an update. Groups are managed under Organization settings. Shared variables are a Pro feature.

v1.68.1! fix

Quieter Error Reporting Across Every Client

A pass over the Sentry inbox. The VS Code extension no longer reports crashes that belong to other extensions in the same host, and its live subscriptions recover from an expired token without logging an error on every re-run. The commit guard installs its hook in worktrees and submodules, where .git is a file. On the web, the sign-in links do a full page load again so the WorkOS redirect can follow, and the marketing pages run through the auth middleware so the session check no longer throws on them. The CLI reports an expired session as a plain message instead of an error, and the JetBrains plugin registers its copy guard through the editor action API, which fixes a startup exception on 2025.x IDEs.

v1.68.0+ feature~ improvement! fix

Review Changes From Your Phone

A Slack, Discord, or email notification about a change request now links straight to that request. Open it on a phone and the review drawer is already up, with Approve and Reject pinned to the bottom of the screen instead of buried under the diff. The requests inbox stacks into cards below tablet width, and the tab and open request live in the URL, so a link you paste to a colleague lands where you were.

The dashboard is installable. Add it to your home screen from Safari or Chrome and it opens on the inbox in its own window. There is no offline cache on purpose.

Two fixes rode along. Slack and Discord messages for change requests and protection changes had no title, so a channel saw a bare change.requested; they now name the change and its environments. Variable request emails linked to the project page rather than the inbox, and outcome emails had no link at all.

v1.67.0+ feature# security

Protected Environments

Mark production (or any environment) as protected and every write into it becomes a change request that a second person applies. The new value is encrypted the moment it is proposed, the reviewer never sees plaintext, and approve applies the write in the same transaction. Requester and approver must be different people. Owners hold a break-glass override that is audited as critical and sent to the security channel.

Protection covers variables, shared accounts, and secret files, on every surface: the dashboard proposes instead of saving, envpilot push refuses a protected environment unless you pass --request, and MCP and the IDE plugins were request-only already. Turning protection off needs only the manage capability, so a plan downgrade never silently unprotects production.

Roles now carry a default environment scope. Developers see development, editors see development and staging, leads see everything. The variable, account, and file forms offer only the environments you can write to, so a scoped developer never sees production as a choice. Admins edit the defaults per role in the admin panel; a member's scope can narrow the role default but not widen it. Existing members keep the scope they had: run the enable-role-environment-defaults migration once from the admin panel on an existing deployment (it backfills members first, then turns the defaults on).

Two fixes rode along. The admin kill switch on a feature now applies even while tier enforcement is off, and the "Request Variables" drawer files a request instead of failing for users without the create capability.

v0.1.6! fix# security

JetBrains Plugin Hardening

A full read of the JetBrains plugin turned up forty findings; this release closes them. The one that mattered most: pulled values were written to .env files unquoted, so a value with a newline, a # or a quote corrupted the file and the editor cloak only hid its first line. Values are now quoted the same way the CLI and the VS Code extension quote them, and the pull path (abort on truncation, abort on a decrypt failure, roll back on a failed write) has tests.

The rest is lifecycle and consistency work. Every coroutine scope and global editor hook now dies with the plugin, so a dynamic unload no longer leaks the copy guard or a reconnecting socket. The tool window refreshes on sign-in, sign-out and every sync instead of waiting for Refresh. The organization tier gate applies to reveal and request actions, not only to link and sync. Sync status and the sync lock are per project, so a stalled project no longer blocks or hides another. Sign-out, token refresh and account switch are serialized, and a version manifest that drops its minimum no longer leaves the plugin latched as outdated.

v0.1.5! fix

JetBrains Plugin Respects the Tier Gate

The JetBrains plugin shipped without a tier gate, so turning the plugin off for an organization did nothing. jetbrains_access is now a feature-registry key like extension_access and cli_access: toggle it from the admin panel and the plugin stops linking and syncing, with a message saying why.

98 entries