@spences10/pi-redact 0.0.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/LICENSE +21 -0
- package/README.md +100 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +177 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Scott Spence
|
|
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
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @spences10/pi-redact
|
|
2
|
+
|
|
3
|
+
[](https://viteplus.dev)
|
|
4
|
+
[](https://vitest.dev)
|
|
5
|
+
|
|
6
|
+
Pi extension that redacts likely secrets from tool output before the
|
|
7
|
+
model sees them.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pi install npm:@spences10/pi-redact
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Local development from this monorepo:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm --filter @spences10/pi-redact run build
|
|
19
|
+
pi install ./packages/pi-redact
|
|
20
|
+
# or for one run only
|
|
21
|
+
pi -e ./packages/pi-redact
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
`@spences10/pi-redact` listens for Pi `tool_result` events and
|
|
27
|
+
rewrites text content before it is added to model context. It is
|
|
28
|
+
intended as a last-mile safety net for accidental secrets in command
|
|
29
|
+
output, file reads, logs, and config files.
|
|
30
|
+
|
|
31
|
+
It currently detects and redacts:
|
|
32
|
+
|
|
33
|
+
- API-key-like fields such as `password`, `secret`, `token`, and
|
|
34
|
+
`api_key`
|
|
35
|
+
- GitHub classic and fine-grained tokens
|
|
36
|
+
- Tavily, Kagi, Brave, and Firecrawl API keys
|
|
37
|
+
- connection strings with embedded credentials
|
|
38
|
+
- SSH config metadata such as `Host`, `HostName`, `User`,
|
|
39
|
+
`IdentityFile`, `ProxyJump`, and forwarding directives
|
|
40
|
+
|
|
41
|
+
Redactions preserve a short prefix where helpful and append a marker
|
|
42
|
+
such as `[REDACTED:GitHub Token]`.
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
### `/redact-stats`
|
|
47
|
+
|
|
48
|
+
Shows how many values were redacted in the current Pi session.
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
/redact-stats
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Example
|
|
55
|
+
|
|
56
|
+
If a tool returns:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
GITHUB_TOKEN=ghp_abcdefghijklmnopqrstuvwxyz1234567890
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The model receives something like:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
GITH********************[REDACTED:GitHub Token]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Using from a custom harness
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import redact from '@spences10/pi-redact';
|
|
72
|
+
|
|
73
|
+
// pass `redact` as an ExtensionFactory to your Pi runtime
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`my-pi` imports this package directly and enables it as the built-in
|
|
77
|
+
`filter-output` extension.
|
|
78
|
+
|
|
79
|
+
## Limitations
|
|
80
|
+
|
|
81
|
+
This extension is defensive, not a guarantee. It can miss novel secret
|
|
82
|
+
formats, and broad patterns can occasionally redact benign values. Use
|
|
83
|
+
proper secret hygiene as the primary control:
|
|
84
|
+
|
|
85
|
+
- do not print secrets unnecessarily
|
|
86
|
+
- avoid reading `.env` files into model context
|
|
87
|
+
- prefer scoped, revocable tokens
|
|
88
|
+
- rotate anything that may have been exposed
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pnpm --filter @spences10/pi-redact run check
|
|
94
|
+
pnpm --filter @spences10/pi-redact run test
|
|
95
|
+
pnpm --filter @spences10/pi-redact run build
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExtensionAPI } from '@mariozechner/pi-coding-agent';
|
|
2
|
+
interface RedactionResult {
|
|
3
|
+
redacted: string;
|
|
4
|
+
count: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function looks_like_ssh_config(text: string): boolean;
|
|
7
|
+
export declare function redact_ssh_config_metadata(text: string): RedactionResult;
|
|
8
|
+
export declare function redact_text(text: string, options?: {
|
|
9
|
+
force_ssh_config?: boolean;
|
|
10
|
+
}): RedactionResult;
|
|
11
|
+
export default function filter_output(pi: ExtensionAPI): Promise<void>;
|
|
12
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// Filter-output extension — redact secrets from tool output
|
|
2
|
+
// Patterns from https://github.com/spences10/nopeek
|
|
3
|
+
const SECRET_PATTERNS = [
|
|
4
|
+
{ name: 'AWS Access Key', pattern: /AKIA[A-Z0-9]{16}/g },
|
|
5
|
+
{ name: 'AWS Temp Access Key', pattern: /ASIA[A-Z0-9]{16}/g },
|
|
6
|
+
{
|
|
7
|
+
name: 'AWS Secret Key',
|
|
8
|
+
pattern: /\b(?:AWS_SECRET_ACCESS_KEY|aws_secret_access_key|secret_access_key|SecretAccessKey)\b\s*[:=]\s*["']?[A-Za-z0-9/+=]{40,}["']?/g,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: 'Bearer Token',
|
|
12
|
+
pattern: /Bearer\s+[a-zA-Z0-9._-]{20,}/g,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'OpenAI/Anthropic API Key',
|
|
16
|
+
pattern: /sk-[a-zA-Z0-9._-]{20,}/g,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'Stripe Live Key',
|
|
20
|
+
pattern: /sk_live_[a-zA-Z0-9]{20,}/g,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Stripe Test Key',
|
|
24
|
+
pattern: /sk_test_[a-zA-Z0-9]{20,}/g,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Hetzner Token',
|
|
28
|
+
pattern: /(?:HCLOUD_TOKEN|hcloud_token|token)\s*[:=]\s*["']?[a-f0-9]{64}\b/g,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'Private Key',
|
|
32
|
+
pattern: /-----BEGIN\s+[\w\s]*PRIVATE\s+KEY-----[\s\S]*?-----END\s+[\w\s]*PRIVATE\s+KEY-----/g,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'Connection String with Password',
|
|
36
|
+
pattern: /:\/\/[^:]+:[^@]+@/g,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Generic Password Field',
|
|
40
|
+
pattern: /\b[\w-]*(?:password|passwd|secret|token|api[_-]?key)\b\s*[:=]\s*["']?[A-Za-z0-9._:/+=@!-]{8,}/gi,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'Generic Secret Phrase',
|
|
44
|
+
pattern: /\b(?:password|passwd|secret|token|api[_-]?key)\b(?:\s+(?:is|was|seen|value|header))?\s*[:=]?\s+[A-Za-z0-9._:/+=@!-]{8,}/gi,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Tavily API Key',
|
|
48
|
+
pattern: /tvly-[a-zA-Z0-9_-]{20,}/g,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'Kagi API Key',
|
|
52
|
+
pattern: /[a-zA-Z0-9_-]{40,}\.[a-zA-Z0-9_-]{40,}/g,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Brave API Key',
|
|
56
|
+
pattern: /BSA[A-Z0-9]{20,}/g,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'Firecrawl API Key',
|
|
60
|
+
pattern: /fc-[a-f0-9]{32}/g,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'GitHub Token',
|
|
64
|
+
pattern: /gh[pousr]_[a-zA-Z0-9]{36,}/g,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'GitHub Fine-grained PAT',
|
|
68
|
+
pattern: /github_pat_[a-zA-Z0-9_]{20,}/g,
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
const SSH_CONFIG_VALUE_DIRECTIVE_PATTERN = /^([ \t]*)(HostName|User|IdentityFile|CertificateFile|ProxyJump|ProxyCommand|LocalForward|RemoteForward|DynamicForward|HostKeyAlias)(\s+)(.+)$/gim;
|
|
72
|
+
const SSH_CONFIG_HOST_PATTERN = /^([ \t]*)(Host)(\s+)(.+)$/gim;
|
|
73
|
+
const SSH_CONFIG_MATCH_PATTERN = /^([ \t]*)(Match)(\s+)(.+)$/gim;
|
|
74
|
+
export function looks_like_ssh_config(text) {
|
|
75
|
+
const has_scope_line = /^\s*(?:Host|Match)\b/m.test(text);
|
|
76
|
+
const has_sensitive_directive = /^\s*(?:HostName|User|IdentityFile|CertificateFile|ProxyJump|ProxyCommand|LocalForward|RemoteForward|DynamicForward|HostKeyAlias)\b/im.test(text);
|
|
77
|
+
return has_scope_line && has_sensitive_directive;
|
|
78
|
+
}
|
|
79
|
+
export function redact_ssh_config_metadata(text) {
|
|
80
|
+
let count = 0;
|
|
81
|
+
const redact_directive_value = (match, indent, directive, spacing, value) => {
|
|
82
|
+
if (value.includes('[REDACTED:'))
|
|
83
|
+
return match;
|
|
84
|
+
count++;
|
|
85
|
+
return `${indent}${directive}${spacing}[REDACTED:SSH ${directive}]`;
|
|
86
|
+
};
|
|
87
|
+
let result = text.replace(SSH_CONFIG_VALUE_DIRECTIVE_PATTERN, redact_directive_value);
|
|
88
|
+
result = result.replace(SSH_CONFIG_HOST_PATTERN, (match, indent, directive, spacing, value) => {
|
|
89
|
+
const trimmed = value.trim();
|
|
90
|
+
if (trimmed === '*' || value.includes('[REDACTED:'))
|
|
91
|
+
return match;
|
|
92
|
+
count++;
|
|
93
|
+
return `${indent}${directive}${spacing}[REDACTED:SSH Host]`;
|
|
94
|
+
});
|
|
95
|
+
result = result.replace(SSH_CONFIG_MATCH_PATTERN, (match, indent, directive, spacing, value) => {
|
|
96
|
+
if (value.trim().toLowerCase() === 'all')
|
|
97
|
+
return match;
|
|
98
|
+
if (value.includes('[REDACTED:'))
|
|
99
|
+
return match;
|
|
100
|
+
count++;
|
|
101
|
+
return `${indent}${directive}${spacing}[REDACTED:SSH Match]`;
|
|
102
|
+
});
|
|
103
|
+
return { redacted: result, count };
|
|
104
|
+
}
|
|
105
|
+
function redact_secret_patterns(text) {
|
|
106
|
+
let count = 0;
|
|
107
|
+
let result = text;
|
|
108
|
+
for (const sp of SECRET_PATTERNS) {
|
|
109
|
+
sp.pattern.lastIndex = 0;
|
|
110
|
+
result = result.replace(sp.pattern, (match) => {
|
|
111
|
+
count++;
|
|
112
|
+
const prefix = match.slice(0, 4);
|
|
113
|
+
return `${prefix}${'*'.repeat(Math.min(match.length - 4, 20))}[REDACTED:${sp.name}]`;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return { redacted: result, count };
|
|
117
|
+
}
|
|
118
|
+
function is_ssh_config_path(path) {
|
|
119
|
+
if (typeof path !== 'string')
|
|
120
|
+
return false;
|
|
121
|
+
const normalized = path.replaceAll('\\', '/').toLowerCase();
|
|
122
|
+
return /(?:^|\/)(?:\.ssh\/(?:config|config\.d\/.+|conf\.d\/.+)|ssh_config)$/.test(normalized);
|
|
123
|
+
}
|
|
124
|
+
function should_force_ssh_config_redaction(event) {
|
|
125
|
+
if (event.toolName !== 'read')
|
|
126
|
+
return false;
|
|
127
|
+
if (!event.input || typeof event.input !== 'object')
|
|
128
|
+
return false;
|
|
129
|
+
return is_ssh_config_path(event.input.path);
|
|
130
|
+
}
|
|
131
|
+
function is_text_content(item) {
|
|
132
|
+
return item.type === 'text';
|
|
133
|
+
}
|
|
134
|
+
export function redact_text(text, options) {
|
|
135
|
+
let count = 0;
|
|
136
|
+
let result = text;
|
|
137
|
+
if (options?.force_ssh_config || looks_like_ssh_config(result)) {
|
|
138
|
+
const ssh_redaction = redact_ssh_config_metadata(result);
|
|
139
|
+
result = ssh_redaction.redacted;
|
|
140
|
+
count += ssh_redaction.count;
|
|
141
|
+
}
|
|
142
|
+
const secret_redaction = redact_secret_patterns(result);
|
|
143
|
+
result = secret_redaction.redacted;
|
|
144
|
+
count += secret_redaction.count;
|
|
145
|
+
return { redacted: result, count };
|
|
146
|
+
}
|
|
147
|
+
export default async function filter_output(pi) {
|
|
148
|
+
let totalRedacted = 0;
|
|
149
|
+
pi.on('tool_result', async (event) => {
|
|
150
|
+
if (!event.content)
|
|
151
|
+
return;
|
|
152
|
+
const force_ssh_config = should_force_ssh_config_redaction(event);
|
|
153
|
+
let modified = false;
|
|
154
|
+
const newContent = event.content.map((item) => {
|
|
155
|
+
if (!is_text_content(item) || !item.text)
|
|
156
|
+
return item;
|
|
157
|
+
const { redacted, count } = redact_text(item.text, {
|
|
158
|
+
force_ssh_config,
|
|
159
|
+
});
|
|
160
|
+
if (count > 0) {
|
|
161
|
+
modified = true;
|
|
162
|
+
totalRedacted += count;
|
|
163
|
+
}
|
|
164
|
+
return { ...item, text: redacted };
|
|
165
|
+
});
|
|
166
|
+
if (modified) {
|
|
167
|
+
return { content: newContent };
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
pi.registerCommand('redact-stats', {
|
|
171
|
+
description: 'Show how many secrets have been redacted',
|
|
172
|
+
handler: async (_args, ctx) => {
|
|
173
|
+
ctx.ui.notify(`Secrets redacted this session: ${totalRedacted}`);
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spences10/pi-redact",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Pi extension that redacts secrets from tool output before the model sees them",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi",
|
|
7
|
+
"pi-package",
|
|
8
|
+
"redaction",
|
|
9
|
+
"secrets"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Scott Spence <me@scottspence.com>",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/spences10/my-pi.git",
|
|
16
|
+
"directory": "packages/pi-redact"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@mariozechner/pi-ai": "^0.70.2",
|
|
36
|
+
"@mariozechner/pi-coding-agent": "^0.70.2"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^25.6.0",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"vitest": "^4.1.5"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=22.0.0"
|
|
45
|
+
},
|
|
46
|
+
"pi": {
|
|
47
|
+
"extensions": [
|
|
48
|
+
"./dist/index.js"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc -p tsconfig.build.json",
|
|
53
|
+
"check": "tsc --noEmit -p tsconfig.json",
|
|
54
|
+
"test": "vitest run"
|
|
55
|
+
}
|
|
56
|
+
}
|