v0.68.3

feder-cr/invisible_dotsv0.68.3Sep 16, 2026by github-actions[bot]

Upgrading?

AI Summary

This release addresses a security exposure where the OpenRouter API key was inadvertently passed to the browser environment. It introduces `runner.forget_key` and `runner.without_key` to ensure the key is removed from the live environment before launching the browser. The update includes comprehensive tests to verify the key is not leaked and fixes minor documentation and environment cleanup issues.

Key Highlights

  • Implemented `runner.forget_key` to remove the API key from the environment.
  • Introduced `runner.without_key` to handle key removal from files, exports, and aliases.
  • Added 22 tests to verify the key is not leaked to the browser server.
  • Fixed module docstring claiming non-existent xfail markers.
  • Fixed test environment cleanup to prevent cross-test variable pollution.

New Features

  • New `runner.forget_key` function for removing keys from live environments.
  • New `runner.without_key` function to handle key removal from various sources.

Full Release Notes

`child_env` strips the OpenRouter key from the environment the interface hands its child, by name and by every alias carrying the value, with twenty-two tests behind it. The child then took it straight back.

The child is `python -m aihawk`, which is this same click group, and the first thing the group does is read `.env` from the directory it inherited. The key is in that file, because the README says to put it there. So the process that launches Firefox held it anyway, and `invisible_playwright._session.build_env` seeds the engine's environment from that process: measured against the published 0.68.2, the key arrives in the environment Firefox is launched with.

The product said so out loud and nobody was reading it. This line appears twice at startup, once per process:

```
env      .env: OPENROUTER_API_KEY
```

and it names only what the file APPLIED, which is only what was not already there. The second copy is the child announcing that it had no key and has just given itself one.

`runner.forget_key` takes the key out of a live environment, and the server path in `cli.main` calls it for itself. Reading the environment rather than filtering the file is deliberate: a browser server has no use for a model key whoever started it, so somebody running `uvx aihawk` in a shell that exports one, or beside a `.env` that holds one, had the same exposure and was never told. One call covers the file, the export and any alias. What counts as the key is now `runner.without_key`, one function with two callers asking it from opposite ends.

Six tests, four of which could not have existed before, because every test in that file stopped at the handover. One spawns the real server as a subprocess and asks what it ended up with, reading its own stderr line rather than anything written for the test. One holds the other direction, that the INTERFACE still gets the key from `.env`: without it, "delete the key everywhere" passes everything else and the product cannot start.

Four known-bad inputs, all killed: the call removed, the call made unconditional, the report taken before the drop, and removal by exact name only.

Two smaller things fixed in passing. The module docstring claimed two xfail markers the file itself records as deleted, and said no test spawns the server. And these tests now restore `os.environ`, which is not tidiness: `load_env_file` sets variables `monkeypatch` never saw, and one left behind made the next test read an environment that already held it, so the file applied nothing and the failure pointed at the product; `forget_key` deletes by value, so a developer running the suite with a real `OPENAI_API_KEY` exported would have lost it.

This is not a leak to the network: Firefox does not send its environment anywhere. It is a defence this repository wrote on purpose, undone half a second after it ran.

Verified locally: 709 passed, ruff clean, `invisible_core.english` clean, `check_content.py` clean, and the version gate green against the real index.

Related Repositories