feat: rewrite pass_mgr with build-time AES key, update pcexec & install
pass_mgr: - Complete rewrite using build-time AES key (injected via ldflags) - New command format: get-secret/get-username --key, set --key --secret - Admin commands: init, handoff, init-from (rejected when AGENT_* env set) - Inline pcguard check for agent commands - Legacy 'get <key>' kept for backward compat - Storage: pc-pass-store/<agent-id>/<key>.gpg with AES-256-GCM - Admin password stored as SHA-256 hash in .pass_mgr/admin.json pcexec.ts: - Support new 'get-secret --key' pattern alongside legacy 'get <key>' - Pass environment to fetchPassword for pcguard validation - Deduplicate matches, sanitize all resolved passwords from output install.mjs: - Generate random 32-byte hex build secret (.build-secret) - Reuse existing secret on rebuilds - Pass to go build via -ldflags -X main.buildSecret=<secret> README.md: - Document new pass_mgr command format - Document admin handoff/init-from workflow - Document security model limitations - Update project structure
This commit is contained in:
24
install.mjs
24
install.mjs
@@ -12,7 +12,8 @@
|
||||
*/
|
||||
|
||||
import { execSync } from 'child_process';
|
||||
import { existsSync, mkdirSync, copyFileSync, chmodSync, readdirSync, rmSync } from 'fs';
|
||||
import { existsSync, mkdirSync, copyFileSync, chmodSync, readdirSync, rmSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { randomBytes } from 'crypto';
|
||||
import { dirname, join, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { homedir, platform } from 'os';
|
||||
@@ -117,14 +118,33 @@ function checkDeps(env) {
|
||||
|
||||
// ── Step 3: Build ───────────────────────────────────────────────────────
|
||||
|
||||
function ensureBuildSecret() {
|
||||
const secretFile = join(__dirname, '.build-secret');
|
||||
if (existsSync(secretFile)) {
|
||||
const existing = readFileSync(secretFile, 'utf8').trim();
|
||||
if (existing.length >= 32) {
|
||||
logOk('Reusing existing build secret');
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
const secret = randomBytes(32).toString('hex');
|
||||
writeFileSync(secretFile, secret + '\n', { mode: 0o600 });
|
||||
logOk('Generated new build secret');
|
||||
return secret;
|
||||
}
|
||||
|
||||
async function build() {
|
||||
logStep(3, 6, 'Building components...');
|
||||
|
||||
// Generate / load build secret for pass_mgr
|
||||
const buildSecret = ensureBuildSecret();
|
||||
|
||||
// pass_mgr (Go)
|
||||
log(' Building pass_mgr...', 'blue');
|
||||
const pmDir = join(__dirname, 'pass_mgr');
|
||||
exec('go mod tidy', { cwd: pmDir, silent: !options.verbose });
|
||||
exec('go build -o dist/pass_mgr src/main.go', { cwd: pmDir, silent: !options.verbose });
|
||||
const ldflags = `-X main.buildSecret=${buildSecret}`;
|
||||
exec(`go build -ldflags "${ldflags}" -o dist/pass_mgr src/main.go`, { cwd: pmDir, silent: !options.verbose });
|
||||
chmodSync(join(pmDir, 'dist', 'pass_mgr'), 0o755);
|
||||
logOk('pass_mgr');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user