hallpass-browser 1.5.0 โ 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +5 -0
- package/README.md +109 -17
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/src/ab.mjs +5 -2
- package/src/mcp.mjs +1 -1
- package/src/sessions.mjs +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hallpass-browser",
|
|
3
3
|
"displayName": "Hallpass Browser",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"description": "Open any website in a browser your AI agent can drive, and log in safely: credentials the agent can use but never read, with a hand-off to you for CAPTCHA/MFA.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "techgniouss"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hallpass-browser",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Open any website in a browser your AI agent can drive, and log in safely: credentials the agent can use but never read, with a hand-off to you for CAPTCHA/MFA.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "techgniouss"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.1 (fix: opening any site with a dot in its host)
|
|
4
|
+
|
|
5
|
+
Fixed
|
|
6
|
+
- **`hallpass open https://example.com` failed on agent-browser 0.41.x** with `Invalid session name 'hp-site-example.com'`: 0.41 only accepts letters, digits, `-` and `_` in a session name, and hallpass named sessions after the host. Dots are now mapped to `_` when talking to agent-browser (the name the agent sees is unchanged). Found by installing 1.5.0 from the registry into a clean folder; the test suites only used `localhost`, which has no dot. A regression test now covers it. **1.5.0 is affected: upgrade.**
|
|
7
|
+
|
|
3
8
|
## 1.5.0 (activate, temp-folder uploads, click retry)
|
|
4
9
|
|
|
5
10
|
Changed
|
package/README.md
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# ๐ Hallpass Browser
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Let your AI agent log in to anything, without ever being able to read your password.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/hallpass-browser)
|
|
8
|
+
[](https://github.com/techgniouss/hallpass-browser/actions/workflows/ci.yml)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](package.json)
|
|
11
|
+
[](#per-tool-setup)
|
|
12
|
+
|
|
13
|
+
Works with **Claude Code ยท Codex ยท Gemini CLI ยท Antigravity ยท Cursor ยท Windsurf ยท VS Code/Copilot**, or any agent that has a shell or speaks MCP.
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## The problem
|
|
20
|
+
|
|
21
|
+
You want an agent to "go to my Play Console and publish the release", "check the Supabase dashboard", "download last month's invoices". Today you have two bad options:
|
|
22
|
+
|
|
23
|
+
1. **Paste your password into the chat.** It is now in a transcript, a log, and a model's context.
|
|
24
|
+
2. **Do the login yourself and hope the agent reuses it.** It works until the session expires, and then you are the bottleneck again.
|
|
25
|
+
|
|
26
|
+
Hallpass is the third option: the agent gets a **logged-in browser**, and **never sees the secret** that got it there.
|
|
8
27
|
|
|
9
28
|
```
|
|
10
29
|
you (own terminal / private form) agent (any AI tool)
|
|
@@ -18,9 +37,44 @@ Hallpass wraps [agent-browser](https://github.com/vercel-labs/agent-browser) wit
|
|
|
18
37
|
hallpass resume โโโโโโโโโโโโถ agent drives the logged-in page
|
|
19
38
|
```
|
|
20
39
|
|
|
21
|
-
##
|
|
40
|
+
## What it looks like
|
|
41
|
+
|
|
42
|
+
```console
|
|
43
|
+
# output abbreviated
|
|
44
|
+
$ hallpass open https://play.google.com/console
|
|
45
|
+
{"status":"needs_human","reason":"login","name":"play-console", ...}
|
|
46
|
+
|
|
47
|
+
# you log in (2-step prompt, passkey, CAPTCHA, whatever) in that window, then tell the agent
|
|
48
|
+
|
|
49
|
+
$ hallpass resume play-console
|
|
50
|
+
{"status":"logged_in","session":"hp-play-console","via":"human"}
|
|
51
|
+
|
|
52
|
+
# from now on the agent drives the logged-in page; later runs are headless and instant
|
|
53
|
+
$ hallpass do hp-play-console snapshot
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
No credential was ever given to the agent. The browser profile keeps the session, so next time `hallpass open` is usually silent.
|
|
57
|
+
|
|
58
|
+
## Why Hallpass
|
|
59
|
+
|
|
60
|
+
| | |
|
|
61
|
+
|---|---|
|
|
62
|
+
| ๐ **Sealed vault** | Logins are AES-GCM encrypted with a key sealed by your OS (DPAPI / Keychain / libsecret). The agent can *use* a login; it cannot *read* one. |
|
|
63
|
+
| ๐ฏ **Origin pinning** | A password is only ever typed into the exact origin you approved. A look-alike page gets nothing. |
|
|
64
|
+
| ๐ **Human hand-off** | CAPTCHA, push-approval MFA, passkeys and first logins open a **visible window for you**. Hallpass never fights a CAPTCHA and never types for you. |
|
|
65
|
+
| ๐ **Automatic TOTP** | Authenticator codes are generated on the fly, never shown. |
|
|
66
|
+
| ๐ **Irreversible-action gate** | Delete / Publish / Pay / Submit-type clicks need a native confirmation from you, not the model. |
|
|
67
|
+
| ๐งพ **Tamper-evident audit log** | Hash-chained record of what agents did. No secrets in it. `hallpass log --verify` |
|
|
68
|
+
| ๐งน **Output redaction** | Secrets are scrubbed from what flows back to the model; password fields refuse to be read. |
|
|
69
|
+
| ๐ **Works everywhere** | A CLI that prints JSON, an MCP server, and native plugins for Claude Code, Codex and Gemini CLI. |
|
|
70
|
+
|
|
71
|
+
Built on top of [agent-browser](https://github.com/vercel-labs/agent-browser), which drives Chrome.
|
|
22
72
|
|
|
23
|
-
|
|
73
|
+
> **Status: beta.** Read [SECURITY.md](SECURITY.md) (threat model, what is and is not protected) before trusting it with anything important. It has not been independently audited.
|
|
74
|
+
|
|
75
|
+
## Quick start (about two minutes)
|
|
76
|
+
|
|
77
|
+
Requirements: **Node 20+**. Nothing else: agent-browser is a dependency and Chrome (about 150 MB, once) is fetched automatically.
|
|
24
78
|
|
|
25
79
|
```bash
|
|
26
80
|
npm i -g hallpass-browser # gives you the `hallpass` command
|
|
@@ -28,11 +82,22 @@ hallpass doctor # checks Node, agent-browser, keystore
|
|
|
28
82
|
hallpass init --yes # detects your AI tools and installs the instructions
|
|
29
83
|
```
|
|
30
84
|
|
|
31
|
-
|
|
85
|
+
Then ask your agent: *"Open my Supabase dashboard and tell me which projects are paused."* It will run `hallpass open`, hand you a window if a login is needed, and carry on.
|
|
86
|
+
|
|
87
|
+
Just want to try the MCP server without installing? `npx -y hallpass-browser mcp`.
|
|
88
|
+
|
|
89
|
+
<details>
|
|
90
|
+
<summary><b>Install details, plugin installs, and troubleshooting</b></summary>
|
|
91
|
+
|
|
92
|
+
Plugin installs (Claude Code, Codex, Gemini) never run `npm`, so the first `hallpass_open` answers `setting_up` while it installs agent-browser and Chrome in the background, and works a minute later. `hallpass setup` does it by hand; `HALLPASS_NO_AUTO_INSTALL=1` turns all of it off. On a bare Linux box Chrome may need system libraries: `agent-browser install --with-deps` (Hallpass never runs apt for you).
|
|
93
|
+
|
|
94
|
+
From a clone instead: `npm link` in the repository folder.
|
|
95
|
+
|
|
96
|
+
</details>
|
|
32
97
|
|
|
33
98
|
### Per-tool setup
|
|
34
99
|
|
|
35
|
-
Each tool gets a *native* package where one exists. **"Checked"** says how far
|
|
100
|
+
Each tool gets a *native* package where one exists. **"Checked"** says how far it has been verified.
|
|
36
101
|
|
|
37
102
|
| Tool | Install | What you get | Checked |
|
|
38
103
|
|---|---|---|---|
|
|
@@ -44,7 +109,7 @@ Each tool gets a *native* package where one exists. **"Checked"** says how far I
|
|
|
44
109
|
| **Anything else with a shell** | nothing extra: it is a CLI that prints JSON | | tested |
|
|
45
110
|
| **ChatGPT / claude.ai (web)** | not supported | they only reach *remote* connectors, and exposing a local browser controller to the internet is something Hallpass deliberately does not do | |
|
|
46
111
|
|
|
47
|
-
`hallpass install --for <claude|codex|gemini|antigravity|antigravity-project|cursor|windsurf|copilot|agents|all>` writes the instruction files (only inside a marked block or a file Hallpass owns). `hallpass mcp-config --for <tool> [--npx]` **prints** the MCP configuration for a client; it never edits your config files.
|
|
112
|
+
`hallpass install --for <claude|codex|gemini|antigravity|antigravity-project|cursor|windsurf|copilot|agents|all>` writes the instruction files (only inside a marked block or a file Hallpass owns). `hallpass mcp-config --for <tool> [--npx]` **prints** the MCP configuration for a client; it never edits your config files.
|
|
48
113
|
|
|
49
114
|
## Use it
|
|
50
115
|
|
|
@@ -55,17 +120,26 @@ hallpass open https://play.google.com/console # the agent runs this; deep l
|
|
|
55
120
|
| Situation | What happens |
|
|
56
121
|
|---|---|
|
|
57
122
|
| You logged in before (or the page needs no login) | opens headless on that site's saved profile; no credentials involved |
|
|
58
|
-
| Login wall, no stored credential | a visible Chrome window opens; **you** log in (MFA, CAPTCHA, anything); tell the agent; it runs `hallpass resume`. Hallpass never types for you. The profile keeps the session. |
|
|
123
|
+
| Login wall, no stored credential | a visible Chrome window opens; **you** log in (MFA, CAPTCHA, passkey, anything); tell the agent; it runs `hallpass resume`. Hallpass never types for you. The profile keeps the session. |
|
|
59
124
|
| A stored credential matches the site | logs in headless, typing the password without ever showing it (TOTP included) |
|
|
60
125
|
|
|
61
126
|
Flags: `--headed` (you always log in), `--headless` (never open a window), `--as <name>` (pick the account when several match; Hallpass refuses to guess).
|
|
62
127
|
|
|
63
|
-
### Add a credential (optional)
|
|
128
|
+
### Add a credential (optional, for hands-free logins)
|
|
64
129
|
|
|
65
130
|
- **Let the agent ask, you type:** the agent runs `hallpass request <login-url>` (MCP: `hallpass_request_credential`). A one-time form opens in *your* browser; you type the login; the agent never sees it.
|
|
66
131
|
- **Or in your own terminal:** `hallpass add supabase --url https://supabase.com/dashboard/sign-in --origin "https://*.supabase.com" --success-url "https://supabase.com/dashboard/**"`
|
|
67
132
|
- **From a password manager:** `--password-ref op://Vault/Item/password` (also `bw:<id>`, `pass:<path>`): Hallpass stores a pointer and fetches the secret at login.
|
|
68
133
|
|
|
134
|
+
## How it compares
|
|
135
|
+
|
|
136
|
+
| Approach | Agent sees the password? | Survives session expiry? | Handles CAPTCHA / MFA? | Stops "delete account" clicks? |
|
|
137
|
+
|---|---|---|---|---|
|
|
138
|
+
| Paste the password into the prompt | **Yes** | yes | no | no |
|
|
139
|
+
| Export cookies / reuse your own browser profile | No, but it holds a full session | until it expires | no | no |
|
|
140
|
+
| Headless script with env-var credentials | Yes (in the process the agent controls) | yes | no | no |
|
|
141
|
+
| **Hallpass** | **No** | yes (vault) or by profile | **Hands off to you** | **Yes, native confirmation** |
|
|
142
|
+
|
|
69
143
|
## Safety controls
|
|
70
144
|
|
|
71
145
|
| Control | What it does | How to turn it on |
|
|
@@ -87,28 +161,46 @@ Flags: `--headed` (you always log in), `--headless` (never open a window), `--as
|
|
|
87
161
|
|
|
88
162
|
Housekeeping: `hallpass sessions`, `hallpass prune --older-than 30d`, `hallpass init`, `hallpass doctor`. Containers/CI without an OS keyring can opt in to `HALLPASS_KEYSTORE=file` (weaker: protects only against other OS users). Cloud browsers work through agent-browser's own `AGENT_BROWSER_PROVIDER` setting; credentials are still resolved locally.
|
|
89
163
|
|
|
90
|
-
##
|
|
164
|
+
## FAQ
|
|
165
|
+
|
|
166
|
+
**Can the agent just read the password out of the page?** No. Typed values are cleared after entry, and the MCP tool refuses to read password fields. A shell agent can still call `agent-browser` directly, which is why the vault, not the browser, is the trust boundary. See [SECURITY.md](SECURITY.md).
|
|
167
|
+
|
|
168
|
+
**Does it solve CAPTCHAs?** No, on purpose. It hands them to you in a visible window.
|
|
169
|
+
|
|
170
|
+
**Does it send my data anywhere?** No. The vault, profiles and audit log live on your machine. Cloud browsers are opt-in.
|
|
171
|
+
|
|
172
|
+
**Do I have to store credentials?** No. The default is that *you* log in once in a visible window and the profile keeps the session.
|
|
173
|
+
|
|
174
|
+
**Which sites work?** Anything agent-browser can open. Sign-in detection is heuristic (it ships a 28-page corpus in 7 languages), so when it guesses wrong it asks you instead of failing.
|
|
175
|
+
|
|
176
|
+
## Development and tests
|
|
91
177
|
|
|
92
178
|
```bash
|
|
179
|
+
git clone https://github.com/techgniouss/hallpass-browser && cd hallpass-browser
|
|
180
|
+
npm install
|
|
93
181
|
npm test # no browser: crypto/vault, TOTP (RFC 6238), origins, redaction, policy, audit chain, references, credential form, export/import, trust, packaging
|
|
94
182
|
npm run test:browser # real Chrome: logins, hand-offs, MCP server, action gate, 28-page detection corpus (opens a visible window or two)
|
|
95
183
|
npm run test:dialog # Windows: the real native approval dialog, answered by clicks and keypresses
|
|
96
184
|
npm run test:all
|
|
97
185
|
```
|
|
98
186
|
|
|
99
|
-
Everything runs against local mock sites. The detection corpus is structural re-creations of common sign-in pages, not copies of real sites, so it measures regressions, not real-world accuracy.
|
|
187
|
+
Everything runs against local mock sites. The detection corpus is structural re-creations of common sign-in pages, not copies of real sites, so it measures regressions, not real-world accuracy. CI runs the unit and browser suites on Linux, Windows and macOS.
|
|
100
188
|
|
|
101
189
|
## Known limits
|
|
102
190
|
|
|
103
|
-
-
|
|
191
|
+
- **Windows** is the most exercised platform. macOS and Linux pass CI, but CI uses the file keystore there; the real Keychain (macOS) and libsecret (Linux) paths and the zenity/osascript dialogs have not been run by hand.
|
|
104
192
|
- **agent-browser compatibility:** tested against 0.41.x (0.27.x also needs a Chrome older than about 155: its headed window loses the page on newer Chrome). Other releases may change output formats; `hallpass doctor` tells you which version you have.
|
|
105
193
|
- Logins inside **iframes or shadow DOM** are not auto-filled (the page still reads as a login wall, so a person is asked). Sites needing extra fields (e.g. AWS IAM account ID) need a site recipe (not built, see [ROADMAP](ROADMAP.md)).
|
|
106
|
-
- **Passkeys/WebAuthn
|
|
194
|
+
- **Passkeys/WebAuthn** can be used by *you* in the hand-off window, but Hallpass cannot store or replay them. Reading **email/SMS codes** and a **separate-user broker** are not built.
|
|
107
195
|
- The **action gate** is a heuristic on labels: it catches common dangerous buttons, not every one, and a shell agent can bypass it by calling `agent-browser` directly.
|
|
108
196
|
- Vaults are bound to one OS account; move machines with `export` / `import`.
|
|
109
197
|
|
|
110
|
-
## Contributing
|
|
198
|
+
## Contributing
|
|
199
|
+
|
|
200
|
+
Issues and pull requests are welcome, especially: **macOS and Linux testing**, **site recipes**, and **more sign-in detection fixtures**. Start with [CONTRIBUTING.md](CONTRIBUTING.md) and the [ROADMAP](ROADMAP.md); look for issues labelled `good first issue`. Please report vulnerabilities privately as described in [SECURITY.md](SECURITY.md).
|
|
201
|
+
|
|
202
|
+
If Hallpass saves you from pasting a password into a chat, a โญ helps other people find it.
|
|
111
203
|
|
|
112
|
-
[
|
|
204
|
+
[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) ยท [CHANGELOG.md](CHANGELOG.md) ยท MIT licensed ([LICENSE](LICENSE)).
|
|
113
205
|
|
|
114
206
|
Use it only on accounts you own and where automation is permitted by the site's terms. Hallpass does not solve CAPTCHAs or bypass bot protection: it hands them to you.
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hallpass-browser",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Open any website in a browser your AI agent can drive, and log in safely: credentials the agent can use but never read, with a hand-off to you for CAPTCHA/MFA.",
|
|
5
5
|
"mcpServers": {
|
|
6
6
|
"hallpass": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hallpass-browser",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Open any website in a browser your AI agent can drive and log in safely: credentials the agent can use but never read, with a hand-off to you for CAPTCHA/MFA. CLI, MCP server, and plugins for Claude Code, Codex, Gemini CLI and Antigravity.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agent",
|
package/src/ab.mjs
CHANGED
|
@@ -125,13 +125,16 @@ export function signInManually(profile, url, { timeoutMs = 15 * 60_000 } = {}) {
|
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
/** agent-browser 0.41+ only accepts [A-Za-z0-9_-] in a session name, but hallpass names sites after their host ("hp-site-example.com"). Dots become "_" on the way in; hallpass keeps using the dotted name everywhere else. */
|
|
129
|
+
export const abSession = (s) => String(s).replace(/\./g, '_');
|
|
130
|
+
|
|
128
131
|
export class Browser {
|
|
129
132
|
constructor({ session, profile, headed = false, redactor, allowedDomains = null }) {
|
|
130
133
|
Object.assign(this, { session, profile, headed, redactor, allowedDomains });
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
_flags(json = true) {
|
|
134
|
-
const f = ['--session', this.session, '--profile', this.profile];
|
|
137
|
+
const f = ['--session', abSession(this.session), '--profile', this.profile];
|
|
135
138
|
if (json) f.push('--json');
|
|
136
139
|
if (this.headed) f.push('--headed');
|
|
137
140
|
if (this.allowedDomains?.length) f.push('--allowed-domains', this.allowedDomains.join(','));
|
|
@@ -211,6 +214,6 @@ export class Browser {
|
|
|
211
214
|
alive() {
|
|
212
215
|
// bare: no --session flag, because with one the listing marks the current session as "-> name"
|
|
213
216
|
const r = this.run(['session', 'list'], { timeout: 15_000, bare: true });
|
|
214
|
-
return r.ok && Array.isArray(r.json?.data?.sessions) && r.json.data.sessions.includes(this.session);
|
|
217
|
+
return r.ok && Array.isArray(r.json?.data?.sessions) && r.json.data.sessions.includes(abSession(this.session));
|
|
215
218
|
}
|
|
216
219
|
}
|
package/src/mcp.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import { startBackgroundSetup } from './setup.mjs';
|
|
|
17
17
|
export { guardBrowser };
|
|
18
18
|
import { profilesDir } from './paths.mjs';
|
|
19
19
|
|
|
20
|
-
const VERSION = '1.5.
|
|
20
|
+
const VERSION = '1.5.1';
|
|
21
21
|
|
|
22
22
|
export const INSTRUCTIONS = `hallpass opens websites in a browser you can drive, and handles login safely.
|
|
23
23
|
|
package/src/sessions.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import os from 'node:os';
|
|
5
|
-
import { Browser } from './ab.mjs';
|
|
5
|
+
import { Browser, abSession } from './ab.mjs';
|
|
6
6
|
import { Redactor } from './redact.mjs';
|
|
7
7
|
import { profilesDir, stateDir } from './paths.mjs';
|
|
8
8
|
import { audit } from './audit.mjs';
|
|
@@ -40,7 +40,7 @@ export function listSessions() {
|
|
|
40
40
|
return fs.readdirSync(profilesDir(), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => {
|
|
41
41
|
const t = lastUsed(e.name);
|
|
42
42
|
return {
|
|
43
|
-
name: e.name, kind: e.name.startsWith('site-') ? 'saved-login-site' : 'credential-profile', running: running.has('hp-' + e.name),
|
|
43
|
+
name: e.name, kind: e.name.startsWith('site-') ? 'saved-login-site' : 'credential-profile', running: running.has(abSession('hp-' + e.name)),
|
|
44
44
|
last_used: t ? new Date(t).toISOString() : null, age_days: t ? Math.floor((Date.now() - t) / 86400e3) : null,
|
|
45
45
|
size_mb: Math.round(dirSize(path.join(profilesDir(), e.name)) / 1e5) / 10,
|
|
46
46
|
};
|