Skip to content

July 2026 Recap

← Back to blog
July 2026 Recap

July 2026 Recap

July was a big one. We shipped a credential proxy that hands AI agents placeholder secrets instead of real ones, code generation for Python, Rust, Go, PHP, Java, and C#, array and record value types, and a new varlock flatten command for monorepo Docker builds. A new Sandboxes docs section covers running agents in ten different sandboxing tools with varlock holding the credentials.

🔧 Core Improvements

Credential proxy for AI agents (preview)

The headline feature: run an agent (or any untrusted tool) through a local MITM proxy so it only ever sees placeholder secrets. Real values are injected at the wire, bound to a verified upstream TLS identity, responses are scrubbed back to placeholders, and every request is policy-checked and audited. Mark a secret with @proxy(domain="api.example.com") and route with host/path/method rules. See the proxy guide and varlock proxy reference.

  • Routing rules and egress control - block and approval rules, per-domain grouping, and @proxyConfig={egress="strict"} to control what the child can reach at all. See proxy routing rules and egress modes.
  • Named substitution targets - Secrets are substituted into request headers only by default (excluding forward and log headers like cookie and x-forwarded-*), and a placeholder may appear at most once per request. Widen with @proxy(substituteIn=[...]) using targets like header:authorization, path, query:api_key, or body:client_secret, and raise the cap with maxOccurrences. See substitution surface.
  • Sandboxing - proxy run --sandbox runs the agent in a sandbox whose only egress is the proxy: a built-in macOS credential and egress jail, or --sandbox=docker (or =podman) to run it in a container while your secrets stay on the host. See the sandboxing guide.
  • Remote sandboxes - proxy start and run gain --expose plus a built-in CONNECT-over-WebSocket tunnel, so a client behind provider HTTP ingress (E2B, Modal, and similar) can route through it. varlock proxy run --url <wss-url> -- <command> runs a command through a broker running elsewhere, self-wiring env and CA certs while holding only placeholders. varlock proxy token prints a session’s data-plane token, and --persist-ca keeps a broker’s CA across restarts. See remote proxy setup.
  • Live policy reload - varlock proxy reload no longer requires the schema to resolve in the requesting shell. The proxy validates the edit in its own context before applying and reports failures back, so a remote broker can be reloaded with a bare provider exec. See editing the schema while a session is running.
  • Client compatibility - Minted MITM certs now include subject and authority key identifiers so strict TLS verifiers (Python 3.13+ urllib and httpx defaults) accept them; the injected env sets NODE_USE_ENV_PROXY=1 so Node’s built-in fetch (Node 24+) routes through the proxy instead of silently bypassing it, and DENO_CERT so Deno trusts the proxy CA. Also fixed a roughly 1-in-512 cert failure from non-minimal DER serial numbers. See client compatibility.
  • Proxying through a proxy - proxy run --url now dials its tunnel through an HTTP proxy (HTTP(S)_PROXY / NO_PROXY), so a sandboxed agent whose only egress is a gateway (for example Docker Sandboxes) can still reach a broker.

Code generation for seven languages

Schema and CLI

  • Array and record types - @type=array(...) and @type=record(...) with per-element validation, native [a, b] and {k=v} literal values, JSON and separator string input, configurable serialization back to process.env, and per-element redaction.
  • --filter and @tag() - Select env vars by key or glob, by @sensitive / @required / @dynamic, or by tag with the new @tag() decorator. @generate* decorators take a matching filter= arg, so one schema can emit multiple generated files scoped to different subsets. Decorator-based filters also scope resolution and validation, so a build-time --filter='!@dynamic' skips runtime-only vars entirely, including their @required checks. See filtering items.
  • Static and dynamic config controls - @dynamic and @static item decorators, @defaultDynamic, and dynamic-plus-public framework and runtime support. See the new static vs dynamic vars guide.
  • varlock flatten - Collapses the @import graph into a self-contained directory, rewriting import paths and pinning plugin versions, so a single package can be deployed without the rest of the monorepo. --vendor-plugins copies plugins into the output for a fully self-contained artifact that resolves with no runtime npm fetch, no shell, and no trust prompt. See varlock flatten and the Docker guide.
  • generateOtp() - Generate TOTP 2FA codes from a stored seed. See generateOtp().
  • Load failure reporting - varlock/auto-load can now throw the load error instead of exiting silently, so a reporter like Sentry can capture it. Opt in with a globalThis._varlockOnLoadError hook or _VARLOCK_THROW_ON_LOAD_ERROR=1. See reporting load failures.
  • Injected env blob reuse - varlock/auto-load and varlock run reuse an injected __VARLOCK_ENV blob instead of re-resolving when it was resolved in the same directory. Pin the behavior with _VARLOCK_USE_INJECTED_ENV, which is useful when handing env into a sandbox with no .env files. See reusing an injected env blob.
  • Better CLI errors - Unknown or misspelled flags are rejected with a did-you-mean suggestion instead of being silently ignored.

Platform, runtime, and OS detection

  • @varlock/ci-env-info - The new 0.1.0 release adds detection for Railway, AWS Amplify, Google Cloud Run, Deno Deploy, Zeabur, and Firebase App Hosting, and detects dev sandboxes (CodeSandbox, StackBlitz, GitHub Codespaces, Gitpod, Replit) with isCI: false.
  • VARLOCK_RUNTIME and VARLOCK_OS - New builtin variables backed by detectRuntime and detectOs. See builtin variables.
  • Detection fixes - An audit against std-env fixed several wrong env var names (GitHub Actions PR number, GitLab MR IID, Netlify build URL, Semaphore and Azure Pipelines PR numbers, Bitbucket repo owner) and made vercel dev / netlify dev report isCI: false.

Security and reliability

  • Compressed response leak scanning - Gzipped responses that fit in a single chunk were never scanned, so browsers could receive leaked sensitive values the scanner should have blocked. Brotli and zstd are now scanned too, and compressed chunks containing a leak fail closed. Note that an app with an existing undetected leak will start seeing those responses blocked after upgrading: look for DETECTED LEAKED SENSITIVE CONFIG in server logs.
  • @internal items excluded from load --format json-full - Framework integrations shell out to this exact command for their injected config, so this closes a leak where an @internal secret-zero credential could reach client or SSR runtime code. Pass --include-internal to opt in for local debugging.
  • Signed and verified release artifacts - The install script verifies the sha256 of the downloaded archive against the release’s published checksums.txt and fails without installing on a mismatch.
  • Windows TPM and WSL - Windows local encryption now uses TPM-sealed keys via NCrypt when available, with existing DPAPI keys auto-upgrading on the next decrypt. install.sh also installs varlock-local-encrypt.exe on WSL so local encryption can use the Windows TPM/Hello backend (--skip-win-exe to opt out). Thanks @cturner8.
  • Encrypted blob injection from the CLI - @encryptInjectedEnv is now honored when varlock run and varlock proxy run inject the env blob, not just on the library auto-load and build-time paths.
  • Cache lock recovery - Locks left behind by an interrupted run are reclaimed immediately instead of stalling later runs for minutes and hiding the real error. varlock cache clear also clears locks.
  • Fixes - varlock audit now honors @auditIgnore; nested varlock run command-local overrides win over the parent’s injected value again; pick and omit filters apply to directory imports; root decorators resolve the full dependency chain of items referenced in their args; refs in @cache values no longer resolve as undefined; forEnv() errors on arguments that resolve to undefined; numeric Infinity is rejected in number coercion; and varlock run no longer OOMs on a bare PATH binary like node.

Breaking changes worth noting: ENV is no longer exported from the package root (import it from varlock/env), the minimum supported Node version is now 22.3, and @disableProcessEnvInjection requires a static true / false value since generated code must not differ per environment.

🔌 Integrations and Plugins

Integrations

  • @varlock/nextjs-integration - Fixed dev-server env reloading on turbopack and Next 16, added pages router and middleware support (webpack builds, edge bundle analysis, encrypted deployments in middleware and edge routes), and made turbopack static ENV.x replacement AST-based so string literals and comments are no longer corrupted. Also preserves all "use ..." directives including stacked ones. Thanks @mhornbacher.
  • @varlock/vite-integration - Fixed Astro plus Cloudflare static and prerendered builds (REQUIRE_TLA errors), and now warns when deploying to Vercel with resolved env injection and no encryption enabled.
  • @varlock/cloudflare-integration - Fixed .dev.vars quoting so secrets with apostrophes, quotes, and backslashes round-trip correctly through Wrangler, and stopped embedding .dev.vars contents in the preview helper’s process argv.
  • @varlock/astro-integration and @varlock/expo-integration - Compatibility updates alongside core releases.
  • FIFO env sources - Non-regular env sources such as 1Password Environments are now detected and skipped for dev-server restart watching across the Next.js, Vite, and Cloudflare integrations, fixing dev-server hangs and endless no-op reload logs.

Plugins

  • @varlock/hashicorp-vault-plugin - New vaultToken() resolver exposes the authenticated Vault client token.
  • @varlock/infisical-plugin - allowMissing flag on infisical() and @initInfisical() for optional secrets.
  • @varlock/1password-plugin - Fixed CLI batch reads failing with “expected data on stdin but none found” on Windows, and one-time password codes are never cached.
  • env-spec-language and @env-spec/parser - Array and record types, autocomplete and hover docs for @tag(), filter=, @internal, and generateOtp(), plus a fix for $(...) truncation on nested parentheses.

🌐 Content Highlights

💬 Community

We’re always looking for feedback and ideas. Join our community:

  • Discord - Chat with us and other users.
  • GitHub Discussions - Suggestions, questions, and feature ideas.
  • GitHub - Star the project and follow updates.
  • X - Follow us on X.
  • Bluesky - Follow us on Bluesky.
← Back to blog