secretless-ai 0.3.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.
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * Credential patterns used across all Secretless integrations.
4
+ * Shared between scanner, hooks, and MCP server.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.CONFIG_FILES = exports.SECRET_FILE_PATTERNS = exports.CREDENTIAL_PATTERNS = void 0;
8
+ exports.CREDENTIAL_PATTERNS = [
9
+ { id: 'anthropic', name: 'Anthropic API Key', regex: /sk-ant-api\d{2}-[a-zA-Z0-9_-]{20,}/, envPrefix: 'ANTHROPIC_API_KEY' },
10
+ { id: 'openai-proj', name: 'OpenAI Project Key', regex: /sk-proj-[a-zA-Z0-9]{20,}/, envPrefix: 'OPENAI_API_KEY' },
11
+ { id: 'openai-legacy', name: 'OpenAI Legacy Key', regex: /sk-[a-zA-Z0-9]{48,}/, envPrefix: 'OPENAI_API_KEY' },
12
+ { id: 'aws-access', name: 'AWS Access Key', regex: /AKIA[0-9A-Z]{16}/, envPrefix: 'AWS_ACCESS_KEY_ID' },
13
+ { id: 'github-pat', name: 'GitHub Token', regex: /ghp_[a-zA-Z0-9]{36}/, envPrefix: 'GITHUB_TOKEN' },
14
+ { id: 'github-fine', name: 'GitHub Fine-Grained PAT', regex: /github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}/, envPrefix: 'GITHUB_TOKEN' },
15
+ { id: 'slack', name: 'Slack Token', regex: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}/, envPrefix: 'SLACK_TOKEN' },
16
+ { id: 'google', name: 'Google API Key', regex: /AIza[0-9A-Za-z_-]{35}/, envPrefix: 'GOOGLE_API_KEY' },
17
+ { id: 'stripe', name: 'Stripe Live Key', regex: /sk_live_[0-9a-zA-Z]{24,}/, envPrefix: 'STRIPE_SECRET_KEY' },
18
+ { id: 'sendgrid', name: 'SendGrid Key', regex: /SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}/, envPrefix: 'SENDGRID_API_KEY' },
19
+ { id: 'supabase', name: 'Supabase Service Key', regex: /eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9\.[a-zA-Z0-9_-]{50,}/, envPrefix: 'SUPABASE_SERVICE_ROLE_KEY' },
20
+ { id: 'azure', name: 'Azure Key', regex: /[a-zA-Z0-9+/]{43}=/, envPrefix: 'AZURE_API_KEY' },
21
+ ];
22
+ /** File patterns that should never be read by AI tools */
23
+ exports.SECRET_FILE_PATTERNS = [
24
+ '.env',
25
+ '.env.local',
26
+ '.env.development',
27
+ '.env.production',
28
+ '.env.staging',
29
+ '*.key',
30
+ '*.pem',
31
+ '*.p12',
32
+ '*.pfx',
33
+ '*.crt',
34
+ '.aws/credentials',
35
+ '.ssh/*',
36
+ '.docker/config.json',
37
+ '.git-credentials',
38
+ '.npmrc',
39
+ '.pypirc',
40
+ '*.tfstate',
41
+ '*.tfvars',
42
+ 'secrets/',
43
+ 'credentials/',
44
+ '.opena2a/secretless-ai/',
45
+ ];
46
+ /** Config files that may contain hardcoded secrets */
47
+ exports.CONFIG_FILES = [
48
+ 'config.json', 'config.yaml', 'config.yml',
49
+ '.env', '.env.local',
50
+ 'package.json', 'mcp.json',
51
+ 'CLAUDE.md',
52
+ '.openclaw/config.json', '.moltbot/config.json',
53
+ 'openclaw.json', 'moltbot.json',
54
+ '.curse/mcp.json', '.vscode/mcp.json',
55
+ '.claude/settings.json',
56
+ '.cursor/settings.json',
57
+ '.github/copilot-instructions.md',
58
+ ];
59
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASU,QAAA,mBAAmB,GAAwB;IACtD,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,oCAAoC,EAAE,SAAS,EAAE,mBAAmB,EAAE;IAC3H,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,0BAA0B,EAAE,SAAS,EAAE,gBAAgB,EAAE;IACjH,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,gBAAgB,EAAE;IAC7G,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,mBAAmB,EAAE;IACvG,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,cAAc,EAAE;IACnG,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,4CAA4C,EAAE,SAAS,EAAE,cAAc,EAAE;IACtI,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,sDAAsD,EAAE,SAAS,EAAE,aAAa,EAAE;IAC7H,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,uBAAuB,EAAE,SAAS,EAAE,gBAAgB,EAAE;IACrG,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,0BAA0B,EAAE,SAAS,EAAE,mBAAmB,EAAE;IAC5G,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,0CAA0C,EAAE,SAAS,EAAE,kBAAkB,EAAE;IAC1H,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,0DAA0D,EAAE,SAAS,EAAE,2BAA2B,EAAE;IAC3J,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,eAAe,EAAE;CAC5F,CAAC;AAEF,0DAA0D;AAC7C,QAAA,oBAAoB,GAAa;IAC5C,MAAM;IACN,YAAY;IACZ,kBAAkB;IAClB,iBAAiB;IACjB,cAAc;IACd,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,kBAAkB;IAClB,QAAQ;IACR,qBAAqB;IACrB,kBAAkB;IAClB,QAAQ;IACR,SAAS;IACT,WAAW;IACX,UAAU;IACV,UAAU;IACV,cAAc;IACd,yBAAyB;CAC1B,CAAC;AAEF,sDAAsD;AACzC,QAAA,YAAY,GAAG;IAC1B,aAAa,EAAE,aAAa,EAAE,YAAY;IAC1C,MAAM,EAAE,YAAY;IACpB,cAAc,EAAE,UAAU;IAC1B,WAAW;IACX,uBAAuB,EAAE,sBAAsB;IAC/C,eAAe,EAAE,cAAc;IAC/B,iBAAiB,EAAE,kBAAkB;IACrC,uBAAuB;IACvB,uBAAuB;IACvB,iCAAiC;CAClC,CAAC"}
package/dist/scan.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Scan project files for hardcoded credentials.
3
+ */
4
+ export interface ScanFinding {
5
+ file: string;
6
+ line: number;
7
+ patternId: string;
8
+ patternName: string;
9
+ severity: 'critical' | 'high';
10
+ preview: string;
11
+ }
12
+ export interface ScanOptions {
13
+ /** Scan global config files like ~/.claude/CLAUDE.md (default: true) */
14
+ scanGlobal?: boolean;
15
+ }
16
+ /**
17
+ * Scan project config files for hardcoded credentials.
18
+ * Also scans global AI tool configs (e.g. ~/.claude/CLAUDE.md).
19
+ * Returns findings sorted by severity then file.
20
+ */
21
+ export declare function scan(projectDir: string, options?: ScanOptions): ScanFinding[];
22
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAQD;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,EAAE,CAsF7E"}
package/dist/scan.js ADDED
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ /**
3
+ * Scan project files for hardcoded credentials.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.scan = scan;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const os = __importStar(require("os"));
43
+ const patterns_1 = require("./patterns");
44
+ /** Global config files that may contain secrets (outside project dir) */
45
+ const GLOBAL_CONFIG_FILES = [
46
+ { dir: path.join(os.homedir(), '.claude'), file: 'CLAUDE.md', label: '~/.claude/CLAUDE.md' },
47
+ { dir: path.join(os.homedir(), '.claude'), file: 'settings.json', label: '~/.claude/settings.json' },
48
+ ];
49
+ /**
50
+ * Scan project config files for hardcoded credentials.
51
+ * Also scans global AI tool configs (e.g. ~/.claude/CLAUDE.md).
52
+ * Returns findings sorted by severity then file.
53
+ */
54
+ function scan(projectDir, options) {
55
+ const findings = [];
56
+ const scanGlobal = options?.scanGlobal !== false;
57
+ // Scan global config files (keys in ~/.claude/CLAUDE.md are in every session's context)
58
+ for (const global of (scanGlobal ? GLOBAL_CONFIG_FILES : [])) {
59
+ const fullPath = path.join(global.dir, global.file);
60
+ if (!fs.existsSync(fullPath))
61
+ continue;
62
+ try {
63
+ const stat = fs.statSync(fullPath);
64
+ if (stat.size > 10 * 1024 * 1024 || !stat.isFile())
65
+ continue;
66
+ const content = fs.readFileSync(fullPath, 'utf-8');
67
+ const lines = content.split('\n');
68
+ for (let i = 0; i < lines.length; i++) {
69
+ const line = lines[i];
70
+ if (line.length > 4096)
71
+ continue;
72
+ if (/\$\{[A-Z_]+\}/.test(line) && !/sk-ant|sk-proj|AKIA|ghp_|xox[baprs]/.test(line))
73
+ continue;
74
+ for (const pattern of patterns_1.CREDENTIAL_PATTERNS) {
75
+ if (pattern.regex.test(line)) {
76
+ const masked = line.replace(pattern.regex, `[${pattern.name} REDACTED]`);
77
+ findings.push({
78
+ file: global.label,
79
+ line: i + 1,
80
+ patternId: pattern.id,
81
+ patternName: pattern.name,
82
+ severity: 'critical',
83
+ preview: masked.trim().substring(0, 80),
84
+ });
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ catch { /* skip */ }
91
+ }
92
+ // Scan project-level config files
93
+ for (const configFile of patterns_1.CONFIG_FILES) {
94
+ const fullPath = path.join(projectDir, configFile);
95
+ if (!fs.existsSync(fullPath))
96
+ continue;
97
+ try {
98
+ const stat = fs.statSync(fullPath);
99
+ if (stat.size > 10 * 1024 * 1024)
100
+ continue;
101
+ if (!stat.isFile())
102
+ continue;
103
+ const content = fs.readFileSync(fullPath, 'utf-8');
104
+ const lines = content.split('\n');
105
+ for (let i = 0; i < lines.length; i++) {
106
+ const line = lines[i];
107
+ if (line.length > 4096)
108
+ continue; // ReDoS protection
109
+ // Skip env var references and placeholders
110
+ if (/\$\{[A-Z_]+\}/.test(line) && !/sk-ant|sk-proj|AKIA|ghp_|xox[baprs]/.test(line)) {
111
+ continue;
112
+ }
113
+ for (const pattern of patterns_1.CREDENTIAL_PATTERNS) {
114
+ if (pattern.regex.test(line)) {
115
+ // Mask the actual secret in the preview
116
+ const masked = line.replace(pattern.regex, `[${pattern.name} REDACTED]`);
117
+ findings.push({
118
+ file: configFile,
119
+ line: i + 1,
120
+ patternId: pattern.id,
121
+ patternName: pattern.name,
122
+ severity: 'critical',
123
+ preview: masked.trim().substring(0, 80),
124
+ });
125
+ break; // One finding per line
126
+ }
127
+ }
128
+ }
129
+ }
130
+ catch {
131
+ // Skip unreadable files
132
+ }
133
+ }
134
+ // Sort: critical first, then by file
135
+ findings.sort((a, b) => {
136
+ if (a.severity !== b.severity)
137
+ return a.severity === 'critical' ? -1 : 1;
138
+ return a.file.localeCompare(b.file);
139
+ });
140
+ return findings;
141
+ }
142
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Check Secretless AI protection status for a project.
3
+ */
4
+ import { type AITool } from './detect';
5
+ export interface StatusResult {
6
+ isProtected: boolean;
7
+ configuredTools: AITool[];
8
+ hookInstalled: boolean;
9
+ denyRuleCount: number;
10
+ secretsFound: number;
11
+ }
12
+ /**
13
+ * Check the current protection status of the project.
14
+ */
15
+ export declare function status(projectDir: string): StatusResult;
16
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAGtD,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CA6DvD"}
package/dist/status.js ADDED
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Check Secretless AI protection status for a project.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.status = status;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const detect_1 = require("./detect");
43
+ const scan_1 = require("./scan");
44
+ /**
45
+ * Check the current protection status of the project.
46
+ */
47
+ function status(projectDir) {
48
+ const result = {
49
+ isProtected: false,
50
+ configuredTools: [],
51
+ hookInstalled: false,
52
+ denyRuleCount: 0,
53
+ secretsFound: 0,
54
+ };
55
+ // Check Claude Code hook
56
+ const hookPath = path.join(projectDir, '.claude', 'hooks', 'secretless-guard.sh');
57
+ result.hookInstalled = fs.existsSync(hookPath);
58
+ // Check Claude Code deny rules
59
+ const settingsPath = path.join(projectDir, '.claude', 'settings.json');
60
+ if (fs.existsSync(settingsPath)) {
61
+ try {
62
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
63
+ result.denyRuleCount = settings?.permissions?.deny?.length || 0;
64
+ }
65
+ catch {
66
+ // Invalid JSON
67
+ }
68
+ }
69
+ // Check which tools have Secretless AI instructions
70
+ const detected = (0, detect_1.detectAITools)(projectDir);
71
+ for (const tool of detected) {
72
+ const filePath = path.join(projectDir, tool.settingsFile);
73
+ if (fs.existsSync(filePath)) {
74
+ try {
75
+ const content = fs.readFileSync(filePath, 'utf-8');
76
+ if (content.includes('secretless-ai:managed') || content.includes('Secretless AI')) {
77
+ result.configuredTools.push(tool.tool);
78
+ }
79
+ }
80
+ catch {
81
+ // Skip
82
+ }
83
+ }
84
+ }
85
+ // Also check CLAUDE.md directly
86
+ const claudeMd = path.join(projectDir, 'CLAUDE.md');
87
+ if (fs.existsSync(claudeMd)) {
88
+ try {
89
+ const content = fs.readFileSync(claudeMd, 'utf-8');
90
+ if (content.includes('secretless-ai:managed') && !result.configuredTools.includes('claude-code')) {
91
+ result.configuredTools.push('claude-code');
92
+ }
93
+ }
94
+ catch {
95
+ // Skip
96
+ }
97
+ }
98
+ // Scan for secrets (project-level only for status report)
99
+ const findings = (0, scan_1.scan)(projectDir, { scanGlobal: false });
100
+ result.secretsFound = findings.length;
101
+ // Protected if hook is installed OR instructions are present in at least one tool
102
+ result.isProtected = result.hookInstalled || result.configuredTools.length > 0;
103
+ return result;
104
+ }
105
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Verify that secrets are accessible via env vars but NOT in AI context files.
3
+ * This is the core dogfooding test: can the agent USE keys without SEEING them.
4
+ */
5
+ export interface VerifyResult {
6
+ /** Env var name → whether it's set */
7
+ envVars: Record<string, boolean>;
8
+ /** Credentials found in AI context files (should be empty) */
9
+ exposedInContext: Array<{
10
+ envVar: string;
11
+ patternName: string;
12
+ file: string;
13
+ line: number;
14
+ }>;
15
+ /** Overall pass/fail */
16
+ passed: boolean;
17
+ }
18
+ /**
19
+ * Verify secrets are properly managed: accessible via env vars, absent from context.
20
+ */
21
+ export declare function verify(projectDir: string): VerifyResult;
22
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,8DAA8D;IAC9D,gBAAgB,EAAE,KAAK,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,wBAAwB;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAyBD;;GAEG;AACH,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CA2DvD"}
package/dist/verify.js ADDED
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Verify that secrets are accessible via env vars but NOT in AI context files.
4
+ * This is the core dogfooding test: can the agent USE keys without SEEING them.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.verify = verify;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const patterns_1 = require("./patterns");
45
+ /** Files that are loaded into the AI context window */
46
+ const AI_CONTEXT_FILES = [
47
+ // Global
48
+ path.join(os.homedir(), '.claude', 'CLAUDE.md'),
49
+ path.join(os.homedir(), '.claude', 'settings.json'),
50
+ ];
51
+ /** Project-level files that end up in AI context */
52
+ const PROJECT_CONTEXT_FILES = [
53
+ 'CLAUDE.md',
54
+ '.cursorrules',
55
+ '.windsurfrules',
56
+ '.clinerules',
57
+ '.github/copilot-instructions.md',
58
+ '.claude/settings.json',
59
+ '.cursor/mcp.json',
60
+ '.vscode/mcp.json',
61
+ 'mcp.json',
62
+ '.env',
63
+ '.env.local',
64
+ 'config.json',
65
+ ];
66
+ /**
67
+ * Verify secrets are properly managed: accessible via env vars, absent from context.
68
+ */
69
+ function verify(projectDir) {
70
+ const envVars = {};
71
+ const exposedInContext = [];
72
+ // Deduplicate env var names across patterns
73
+ const uniqueEnvVars = [...new Set(patterns_1.CREDENTIAL_PATTERNS.map((p) => p.envPrefix))];
74
+ // Check which env vars are set
75
+ for (const envVar of uniqueEnvVars) {
76
+ envVars[envVar] = !!process.env[envVar] && process.env[envVar].length > 0;
77
+ }
78
+ // Build list of all files to check
79
+ const filesToCheck = [];
80
+ for (const global of AI_CONTEXT_FILES) {
81
+ filesToCheck.push({ absPath: global, label: global.replace(os.homedir(), '~') });
82
+ }
83
+ for (const rel of PROJECT_CONTEXT_FILES) {
84
+ filesToCheck.push({ absPath: path.join(projectDir, rel), label: rel });
85
+ }
86
+ // Scan each file for credential patterns
87
+ for (const { absPath, label } of filesToCheck) {
88
+ if (!fs.existsSync(absPath))
89
+ continue;
90
+ try {
91
+ const stat = fs.statSync(absPath);
92
+ if (!stat.isFile() || stat.size > 10 * 1024 * 1024)
93
+ continue;
94
+ const content = fs.readFileSync(absPath, 'utf-8');
95
+ const lines = content.split('\n');
96
+ for (let i = 0; i < lines.length; i++) {
97
+ const line = lines[i];
98
+ if (line.length > 4096)
99
+ continue;
100
+ for (const pattern of patterns_1.CREDENTIAL_PATTERNS) {
101
+ if (pattern.regex.test(line)) {
102
+ exposedInContext.push({
103
+ envVar: pattern.envPrefix,
104
+ patternName: pattern.name,
105
+ file: label,
106
+ line: i + 1,
107
+ });
108
+ break;
109
+ }
110
+ }
111
+ }
112
+ }
113
+ catch {
114
+ // Skip unreadable
115
+ }
116
+ }
117
+ // Pass = at least one env var is set AND zero credentials exposed in context
118
+ const anyEnvSet = Object.values(envVars).some((v) => v);
119
+ const passed = anyEnvSet && exposedInContext.length === 0;
120
+ return { envVars, exposedInContext, passed };
121
+ }
122
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "secretless-ai",
3
+ "version": "0.3.0",
4
+ "description": "One command to keep secrets out of AI. Works with Claude Code, Cursor, Copilot, Windsurf, and any AI coding tool.",
5
+ "license": "Apache-2.0",
6
+ "type": "commonjs",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "bin": {
10
+ "secretless-ai": "dist/cli.js"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "test": "vitest run",
18
+ "dev": "tsc --watch",
19
+ "clean": "rm -rf dist",
20
+ "prepublishOnly": "npm run build && npm test"
21
+ },
22
+ "keywords": [
23
+ "ai",
24
+ "secrets",
25
+ "credentials",
26
+ "security",
27
+ "claude",
28
+ "cursor",
29
+ "copilot",
30
+ "windsurf",
31
+ "cline",
32
+ "aider",
33
+ "mcp"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/opena2a-org/secretless"
38
+ },
39
+ "homepage": "https://github.com/opena2a-org/secretless",
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "typescript": "^5.3.0",
45
+ "vitest": "^1.2.0"
46
+ }
47
+ }