passclaude 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +194 -2
- package/assets/fonts/BricolageGrotesque-ExtraBold.ttf +0 -0
- package/assets/fonts/DMSans-Bold.ttf +0 -0
- package/assets/fonts/DMSans-Medium.ttf +0 -0
- package/assets/fonts/DMSans-Regular.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Bold.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
- package/assets/fonts/OFL-BricolageGrotesque.txt +93 -0
- package/assets/fonts/OFL-DMSans.txt +93 -0
- package/assets/fonts/OFL-JetBrainsMono.txt +93 -0
- package/assets/passclaude.ico +0 -0
- package/docs/e2e.js +56 -0
- package/hook/guard.cjs +47 -0
- package/package.json +56 -4
- package/src/cli.js +31 -0
- package/src/install-guard.js +80 -0
- package/src/ntfy.js +42 -0
- package/src/phone.js +217 -0
- package/src/ps/brand.xaml +22 -0
- package/src/ps/chromeui.ps1 +55 -0
- package/src/ps/common.ps1 +218 -0
- package/src/ps/cred.ps1 +38 -0
- package/src/ps/focus.ps1 +16 -0
- package/src/ps/prompt-ui.ps1 +156 -0
- package/src/ps/prompt.ps1 +25 -0
- package/src/ps/qr-ui.ps1 +81 -0
- package/src/ps/qr.ps1 +11 -0
- package/src/ps/toast-ui.ps1 +70 -0
- package/src/ps/toast.ps1 +10 -0
- package/src/ps/type.ps1 +22 -0
- package/src/ps/ui-styles.xaml +169 -0
- package/src/ps/ui.ps1 +101 -0
- package/src/qr.js +298 -0
- package/src/redact.js +201 -0
- package/src/runner.js +174 -0
- package/src/server.js +112 -0
- package/src/sitelock.js +38 -0
- package/src/tools.js +186 -0
- package/src/typer.js +39 -0
- package/src/vault.js +109 -0
- package/src/windows.js +47 -0
- package/src/winops.js +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 passClaude contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,195 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/daniardel/passclaude/main/brand/logo/lockup-on-violet.svg">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/daniardel/passclaude/main/brand/logo/lockup.svg" alt="passClaude" width="420">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
<h3 align="center">Claude logs you in. Its eyes stay shut.</h3>
|
|
9
|
+
|
|
10
|
+
<p align="center">Let Claude Code log into websites and use your API keys without ever seeing them.</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/passclaude"><img src="https://img.shields.io/npm/v/passclaude?color=5B2EFF" alt="npm"></a>
|
|
14
|
+
<a href="https://github.com/daniardel/passclaude/actions/workflows/test.yml"><img src="https://github.com/daniardel/passclaude/actions/workflows/test.yml/badge.svg" alt="tests"></a>
|
|
15
|
+
<img src="https://img.shields.io/badge/platform-Windows-17132E" alt="platform: Windows">
|
|
16
|
+
<a href="https://github.com/daniardel/passclaude/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/passclaude?color=FFC92E" alt="license"></a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
You never paste a password into the chat. You type it once, into a popup on your PC or a one-time encrypted link on your phone. After that Claude can *use* it, but passClaude's tools never return the value, so it stays out of the conversation, the transcript and the model. There are a few ways it can still get out: read "Not protected" below.
|
|
20
|
+
|
|
21
|
+
- **Website logins:** Claude clicks the password box and passClaude types the password, but only on the site it belongs to.
|
|
22
|
+
- **API keys in commands:** Claude runs the command, the key goes in as an environment variable or is typed into a login prompt, and it is masked in the output.
|
|
23
|
+
- **Works from your phone** with Claude Code Remote Control, including saving new secrets.
|
|
24
|
+
- **Free and open source.** No password manager, no account. Windows.
|
|
25
|
+
|
|
26
|
+
passClaude is an independent project. It is not made by or affiliated with Anthropic.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
You need Windows 10 or 11, [Node.js](https://nodejs.org) 20 or newer and [Claude Code](https://docs.claude.com/en/docs/claude-code/setup). For website logins you also need Chrome with Claude in Chrome.
|
|
31
|
+
|
|
32
|
+
**One click:** download [install-passclaude.cmd](https://github.com/daniardel/passclaude/releases/latest/download/install-passclaude.cmd) and double-click it. A small window checks that Node.js and Claude Code are there and adds passClaude. Windows may warn that the file comes from the internet: choose "More info", then "Run anyway". It's a plain text file (a few batch lines that start Windows PowerShell on the rest), so you can open it in Notepad to read it first.
|
|
33
|
+
|
|
34
|
+
**One command:**
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
claude mcp add --scope user passclaude -- npx -y passclaude
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Or ask Claude:** paste this into Claude Code: *Install passClaude for me by running `claude mcp add --scope user passclaude -- npx -y passclaude`.*
|
|
41
|
+
|
|
42
|
+
Then restart Claude Code.
|
|
43
|
+
|
|
44
|
+
## What to say to Claude
|
|
45
|
+
|
|
46
|
+
| You say | What happens |
|
|
47
|
+
|---|---|
|
|
48
|
+
| "Save my Netflix password" | A password popup opens on your PC. You type it there. |
|
|
49
|
+
| "Save my GitHub token. I'm on my phone." | Claude shows a one-time link. You open it on your phone and type the token. |
|
|
50
|
+
| "Save my GitHub token, I'll type it on my phone" (while at the PC) | Same link, and a window on your PC shows it as a QR code to scan. It closes once the token arrives. |
|
|
51
|
+
| "Log into Netflix" | Claude opens the login page and clicks the password box. passClaude types the password, and a note in the corner of the screen says so. Claude clicks Sign in. |
|
|
52
|
+
| "List my GitHub repos with my GitHub token" | Claude runs the command with your token in `$env:GITHUB_TOKEN`. The output shows `••••(github)` where the token would be. |
|
|
53
|
+
| "Log the GitHub CLI in with my GitHub token" | Claude runs `gh auth login --with-token` and passClaude types the token into it, the way you would at the prompt. Works for any command that reads a token or password from its input, like `docker login --password-stdin`. |
|
|
54
|
+
| "What passwords do you have?" | Names and sites only. Never values. |
|
|
55
|
+
|
|
56
|
+
Commands run in Windows PowerShell (`powershell.exe`, version 5.1), so Claude writes PowerShell syntax such as `$env:GITHUB_TOKEN`, not `$GITHUB_TOKEN` or `%GITHUB_TOKEN%`.
|
|
57
|
+
|
|
58
|
+
## How it works
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
You ─ type once ─▶ PC popup, or phone link (encrypted on the phone)
|
|
62
|
+
│
|
|
63
|
+
▼
|
|
64
|
+
Windows Credential Manager (entries named passclaude:<name>)
|
|
65
|
+
│
|
|
66
|
+
Claude ─ type_secret ──┼──▶ checks Chrome is on the right site and a password box is focused ──▶ types it
|
|
67
|
+
Claude ─ run_with_secret ─▶ command gets the key as an env var ──▶ output is masked ──▶ Claude
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
passClaude is an MCP server that runs on your PC. Its tools never return a secret, so passClaude never puts one in the chat. It can't stop every other way a secret can leak: see "Not protected" below.
|
|
71
|
+
|
|
72
|
+
| Tool | What it does |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `list_secrets` | Names, kinds and sites of saved secrets |
|
|
75
|
+
| `add_secret` | Opens a password popup on the PC |
|
|
76
|
+
| `add_secret_from_phone` | Gives a one-time link to type the secret on your phone, optionally shown as a QR code on the PC |
|
|
77
|
+
| `check_phone_secret` | Waits up to 50 seconds for the phone to send it |
|
|
78
|
+
| `type_secret` | Types a website password into Chrome, only on its site |
|
|
79
|
+
| `run_with_secret` | Runs a Windows PowerShell command with secrets as environment variables or typed into its input, output masked |
|
|
80
|
+
| `delete_secret` | Deletes a secret |
|
|
81
|
+
|
|
82
|
+
Commands stop after 2 minutes unless Claude asks for longer (10 minutes at most). Output is cut off at 1 MB per stream.
|
|
83
|
+
|
|
84
|
+
Website passwords and command secrets are kept apart: a website password can only be typed, and only on its own site; a command secret can only be used in commands.
|
|
85
|
+
|
|
86
|
+
## Security: what it protects and what it doesn't
|
|
87
|
+
|
|
88
|
+
**Protected**
|
|
89
|
+
- No passClaude tool returns a secret. Secrets don't appear in tool results, so passClaude itself never sends them to the model, your transcripts or Anthropic's servers. The ways a secret can still get out are listed under "Not protected".
|
|
90
|
+
- Website passwords are typed only when Chrome's address bar shows the site they were saved for (subdomains included, lookalikes like `netflix.com.evil.ru` refused) and only into a password box.
|
|
91
|
+
- A saved secret is never replaced without a delete first.
|
|
92
|
+
- Phone links are end-to-end encrypted (ECDH P-256 + AES-256-GCM, done in your phone's browser). The relay ([ntfy.sh](https://ntfy.sh)) only sees scrambled data. Each link saves one secret and expires after 5 minutes (but see the link note below).
|
|
93
|
+
|
|
94
|
+
**Not protected (please read)**
|
|
95
|
+
- Claude Code can run shell commands as you. A Claude that is deliberately trying, or that has been tricked by a malicious web page or file, could read Windows Credential Manager directly. The optional guard (below) blocks the obvious ways. It's a speed bump, not a wall.
|
|
96
|
+
- A tricked Claude could send a command secret somewhere inside the command it runs. Masking protects the output, not network calls. Keep Claude Code's approval prompt on for `run_with_secret` and read the command before you approve it.
|
|
97
|
+
- Masking hides the whole secret in the output, its common encodings (base64, URL-encoded, hex, JSON-escaped), and any piece of 8 or more characters of them, also when Windows PowerShell wraps a long value onto the next line or shortens it with `...`. It can't catch pieces shorter than 8 characters, other encodings, or a value that the command deliberately reshapes, for example by reversing it, splitting it up or re-encoding it. Because it masks pieces, masking can occasionally also hide ordinary text that happens to match part of a secret. Read the command before you approve it.
|
|
98
|
+
- Once typed, a password sits in the page's password box. Scripts on that page can read it, just like when you type it yourself. So can Claude's own browser tools: Claude in Chrome can run JavaScript on the page, or click "show password" and take a screenshot, and that puts the password in the chat. passClaude can't stop this. The site lock only limits where the password is typed. Watch what Claude does on the page after it types.
|
|
99
|
+
- The phone page is served from GitHub Pages ([daniardel/passclaude-phone](https://github.com/daniardel/passclaude-phone)). Whoever controls that repo controls the page's code. You can host your own copy (see Configuration).
|
|
100
|
+
- The site lock reads Chrome's address bar. It is tested with English Chrome. Other languages use a fallback that finds the address bar as the first text box outside the web page, which has not been tested in a non-English Chrome yet.
|
|
101
|
+
- The one-time link appears in the chat. It contains no secret: only a public key, a random relay topic, the secret's name, kind and site, when it expires, and the relay address. But the link works like a key: anyone who sees it before you use it could send their own value to it within its 5 minutes. Open it right away. After you send, your phone page must say "Saved". If Claude says it saved but your phone page didn't, delete the secret and try again.
|
|
102
|
+
- A tricked Claude could show you a fake phone link that sends what you type to someone else. The phone page can't tell a real link from a fake one. Only open a phone link right after you asked Claude to save a secret, and check the name and site it shows.
|
|
103
|
+
- Claude chooses a secret's name and site. Check the site shown in the popup or on the phone page before you type. A password saved for the wrong site is typed on that wrong site.
|
|
104
|
+
- Your phone's browser might offer to save what you typed in its own password manager. Tap Never if you don't want a copy there.
|
|
105
|
+
- Typing needs the PC unlocked, with the login page as the visible tab of a Chrome window that isn't minimized or completely covered (for example by a full-screen game). Claude in Chrome sometimes opens pages in a background tab: if passClaude says Chrome is showing another site, switch to the login tab. Remote Control drives your PC; passClaude types on the PC, not on your phone.
|
|
106
|
+
|
|
107
|
+
### Optional guard
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
npx -y passclaude install-guard
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Shows the exact change, asks first, backs up `~/.claude/settings.json`, then adds a hook that blocks shell commands which try to read saved secrets directly (`cmdkey`, the Windows credential APIs, hidden base64 PowerShell commands and similar).
|
|
114
|
+
|
|
115
|
+
The hook covers Claude Code's Bash and PowerShell tools and also passClaude's own `run_with_secret` tool. `run_with_secret` makes the same check itself, so it refuses these kinds of commands even if you never install the guard. The guard adds the same block for Claude Code's own shell tools.
|
|
116
|
+
|
|
117
|
+
## Configuration
|
|
118
|
+
|
|
119
|
+
| Environment variable | Default | What it's for |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `PASSCLAUDE_NTFY_URL` | `https://ntfy.sh` | Relay for phone links. Point it at your own [ntfy](https://docs.ntfy.sh/install/) server if you like. |
|
|
122
|
+
| `PASSCLAUDE_PAGE_URL` | `https://daniardel.github.io/passclaude-phone/` | Where phone links open. Host the page yourself and point this at it. |
|
|
123
|
+
| `PASSCLAUDE_NOTIFY` | `on` | Set to `off` (or `0`, `false`, `no`) to stop the note in the corner of the screen each time passClaude types a password. |
|
|
124
|
+
|
|
125
|
+
A custom relay must use https and be reachable from your phone. The page URL must be https too, because the page needs a secure connection to encrypt. To host the page yourself, copy `index.html`, `style.css`, `app.js`, `link.js`, `e2e.js` and the `brand` folder from the `docs/` folder of the GitHub repo. The page loads nothing from other sites, fonts included. The npm package only ships `docs/e2e.js`.
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
claude mcp add --env PASSCLAUDE_NTFY_URL=https://ntfy.example.com --scope user passclaude -- npx -y passclaude
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## FAQ
|
|
134
|
+
|
|
135
|
+
**Does Claude really never see my password?**
|
|
136
|
+
No passClaude tool returns it, and command output is masked. The project's tests check that no tool output contains a saved value, including base64 and URL-encoded copies. That is not the same as a promise that it can't leak: see "Not protected" above, for example for Claude's own browser tools and for what masking can't catch.
|
|
137
|
+
|
|
138
|
+
**Where are my secrets stored?**
|
|
139
|
+
In Windows Credential Manager, encrypted by Windows for your user account. You can see them in Control Panel → Credential Manager → Windows Credentials, named `passclaude:<name>`.
|
|
140
|
+
|
|
141
|
+
**How do I change a password?**
|
|
142
|
+
Ask Claude to delete it and save it again.
|
|
143
|
+
|
|
144
|
+
**Does it press Enter after typing?**
|
|
145
|
+
No. Claude clicks the sign-in button itself. That makes the login a separate step that shows up in the chat, so you can see it. With Remote Control you may not be watching the PC while it types.
|
|
146
|
+
|
|
147
|
+
**Does it work on a work PC?**
|
|
148
|
+
Maybe not. passClaude runs bundled PowerShell scripts. It asks PowerShell to skip the execution policy for them, but if your organization's Group Policy forces the execution policy to AllSigned or Restricted, that setting wins, the scripts can't run and passClaude won't work. AppLocker or Windows Defender Application Control (WDAC) rules can also put PowerShell in Constrained Language Mode, which blocks the C# code the scripts compile. And if your organization turns on PowerShell logging or transcription by policy, commands run with `run_with_secret` may be recorded in Windows logs, including what they print, before passClaude masks it.
|
|
149
|
+
|
|
150
|
+
**Can I save a very long secret from my phone?**
|
|
151
|
+
Almost always. A secret can be up to 1,280 characters, and the phone relay limits message size. Ordinary secrets of any allowed length fit. A very long secret made of Chinese, Japanese or Korean characters (over about 950) or emoji (over about 350) can be too big. If it is, the phone page says so. Use the PC popup (`add_secret`) instead.
|
|
152
|
+
|
|
153
|
+
**What if my PC can't reach the phone relay?**
|
|
154
|
+
Before it gives you a link, passClaude checks that your PC can connect to the relay (ntfy.sh, or your own). If it can't within 8 seconds, it says so right away instead of giving you a link whose secret could never reach your PC. Use the PC popup (`add_secret`) instead.
|
|
155
|
+
|
|
156
|
+
**What should I do while it types?**
|
|
157
|
+
Leave the mouse and keyboard alone for a moment. If another window comes to the front, typing stops and the password box may be partly filled: clear it and try again. A click into another box of the same window is not caught.
|
|
158
|
+
|
|
159
|
+
**Mac or Linux?**
|
|
160
|
+
Not yet. Windows first.
|
|
161
|
+
|
|
162
|
+
**Edge or Firefox?**
|
|
163
|
+
Chrome only for now.
|
|
164
|
+
|
|
165
|
+
**Why not a password manager's Claude integration?**
|
|
166
|
+
If you already use one with Claude, that may suit you better. passClaude is for people who want something free, with no account, that works over Remote Control.
|
|
167
|
+
|
|
168
|
+
## Uninstall
|
|
169
|
+
|
|
170
|
+
1. Ask Claude to delete your passClaude secrets, or remove the `passclaude:` entries in Credential Manager.
|
|
171
|
+
2. Run `claude mcp remove passclaude --scope user`.
|
|
172
|
+
3. If you installed the guard: remove the passClaude entry under `hooks.PreToolUse` in `~/.claude/settings.json` (a backup was saved next to it) and delete the `~/.claude/passclaude` folder.
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
git clone https://github.com/daniardel/passclaude.git
|
|
178
|
+
cd passclaude
|
|
179
|
+
npm install
|
|
180
|
+
npm test
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
To try your copy in Claude Code: `claude mcp add --scope user passclaude -- node "<this folder>\src\cli.js"`.
|
|
184
|
+
|
|
185
|
+
The phone page is `docs/index.html`, `docs/style.css`, `docs/app.js`, `docs/link.js`, `docs/e2e.js` and `docs/brand/`. The live copy is in the public [passclaude-phone](https://github.com/daniardel/passclaude-phone) repo. After changing any of these files, copy them there and push, or phone links keep opening the old page. To try it locally: `node scripts/serve.js docs`.
|
|
186
|
+
|
|
187
|
+
The look (colours, fonts, the padlock) lives in [`brand/`](https://github.com/daniardel/passclaude/blob/main/brand/README.md). After changing it, run `npm run brand` and commit what it writes; it also refreshes `docs/brand/`.
|
|
188
|
+
|
|
189
|
+
## Reporting a security problem
|
|
190
|
+
|
|
191
|
+
Please don't open a public issue. See [SECURITY.md](https://github.com/daniardel/passclaude/blob/main/SECURITY.md).
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
MIT
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2022 The Bricolage Grotesque Project Authors (https://github.com/ateliertriay/bricolage)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2014 The DM Sans Project Authors (https://github.com/googlefonts/dm-fonts)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
|
|
5
|
+
This license is copied below, and is also available with a FAQ at: https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
Binary file
|
package/docs/e2e.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// End-to-end encryption shared by the phone page (browser) and the passClaude server (Node 20+).
|
|
2
|
+
// ECDH P-256 -> HKDF-SHA256 -> AES-256-GCM, using only the standard WebCrypto API.
|
|
3
|
+
|
|
4
|
+
const subtle = globalThis.crypto.subtle;
|
|
5
|
+
const enc = new TextEncoder();
|
|
6
|
+
const dec = new TextDecoder();
|
|
7
|
+
|
|
8
|
+
export function toB64u(bytes) {
|
|
9
|
+
let s = '';
|
|
10
|
+
for (const b of new Uint8Array(bytes)) s += String.fromCharCode(b);
|
|
11
|
+
return btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function fromB64u(str) {
|
|
15
|
+
const s = atob(String(str).replace(/-/g, '+').replace(/_/g, '/'));
|
|
16
|
+
return Uint8Array.from(s, (c) => c.charCodeAt(0));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function randomTopic() {
|
|
20
|
+
return `pc-${toB64u(globalThis.crypto.getRandomValues(new Uint8Array(24)))}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function generateKeyPair() {
|
|
24
|
+
const pair = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveBits']);
|
|
25
|
+
const publicKeyRaw = new Uint8Array(await subtle.exportKey('raw', pair.publicKey));
|
|
26
|
+
return { privateKey: pair.privateKey, publicKeyRaw };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function deriveKey(privateKey, peerPublicRaw, topic) {
|
|
30
|
+
const peer = await subtle.importKey('raw', peerPublicRaw, { name: 'ECDH', namedCurve: 'P-256' }, false, []);
|
|
31
|
+
const shared = await subtle.deriveBits({ name: 'ECDH', public: peer }, privateKey, 256);
|
|
32
|
+
const hkdf = await subtle.importKey('raw', shared, 'HKDF', false, ['deriveKey']);
|
|
33
|
+
return subtle.deriveKey(
|
|
34
|
+
{ name: 'HKDF', hash: 'SHA-256', salt: enc.encode(topic), info: enc.encode('passclaude v1') },
|
|
35
|
+
hkdf,
|
|
36
|
+
{ name: 'AES-GCM', length: 256 },
|
|
37
|
+
false,
|
|
38
|
+
['encrypt', 'decrypt'],
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Binds a message to one link and one direction, so it can't be replayed elsewhere. */
|
|
43
|
+
export function aadFor({ topic, name, kind, site }, purpose) {
|
|
44
|
+
return enc.encode(`passclaude v1|${purpose}|${topic}|${name}|${kind}|${site ?? ''}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function seal(key, obj, aad) {
|
|
48
|
+
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
|
|
49
|
+
const ct = await subtle.encrypt({ name: 'AES-GCM', iv, additionalData: aad }, key, enc.encode(JSON.stringify(obj)));
|
|
50
|
+
return { iv: toB64u(iv), ct: toB64u(ct) };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function unseal(key, { iv, ct }, aad) {
|
|
54
|
+
const plain = await subtle.decrypt({ name: 'AES-GCM', iv: fromB64u(iv), additionalData: aad }, key, fromB64u(ct));
|
|
55
|
+
return JSON.parse(dec.decode(plain));
|
|
56
|
+
}
|
package/hook/guard.cjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// passClaude guard: a Claude Code PreToolUse hook for the Bash and PowerShell tools.
|
|
3
|
+
// Blocks shell commands that try to read saved secrets directly instead of using the passClaude tools.
|
|
4
|
+
// A speed bump, not a wall: a determined attacker can find other ways. See the README security section.
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const BLOCKED = [
|
|
8
|
+
/passclaude:/i, // Credential Manager target names
|
|
9
|
+
/cred\.ps1/i, // passClaude's own vault script
|
|
10
|
+
/\bCred(Read|Enumerate)/i, // the Windows credential APIs
|
|
11
|
+
/advapi32/i, // the DLL that holds them
|
|
12
|
+
/\bcmdkey\b/i,
|
|
13
|
+
/Get-StoredCredential/i,
|
|
14
|
+
/CredentialManager/i,
|
|
15
|
+
/PasswordVault/i,
|
|
16
|
+
/\bvaultcmd\b/i,
|
|
17
|
+
/\s-(ec|enc|encodedcommand)\b/i, // PowerShell commands hidden in base64
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
function verdict(input) {
|
|
21
|
+
const command = String(input?.tool_input?.command ?? '');
|
|
22
|
+
if (!BLOCKED.some((re) => re.test(command))) return null;
|
|
23
|
+
return 'Blocked by passClaude guard: this command looks like it reads saved secrets directly or hides what it does. '
|
|
24
|
+
+ 'Use the passClaude tools instead (type_secret, run_with_secret). If this is a mistake, the user can run it themselves.';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = { BLOCKED, verdict };
|
|
28
|
+
|
|
29
|
+
if (require.main === module) {
|
|
30
|
+
let data = '';
|
|
31
|
+
process.stdin.setEncoding('utf8');
|
|
32
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
33
|
+
process.stdin.on('end', () => {
|
|
34
|
+
let input;
|
|
35
|
+
try {
|
|
36
|
+
input = JSON.parse(data);
|
|
37
|
+
} catch {
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
const reason = verdict(input);
|
|
41
|
+
if (reason) {
|
|
42
|
+
process.stderr.write(`${reason}\n`);
|
|
43
|
+
process.exit(2);
|
|
44
|
+
}
|
|
45
|
+
process.exit(0);
|
|
46
|
+
});
|
|
47
|
+
}
|