@revfleet/hscli 0.5.3 → 0.7.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/CHANGELOG.md +169 -0
- package/README.md +3 -3
- package/dist/cli.js +8 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/audit/index.d.ts +3 -0
- package/dist/commands/audit/index.js +226 -0
- package/dist/commands/audit/index.js.map +1 -0
- package/dist/commands/auth/index.js +2 -2
- package/dist/commands/auth/index.js.map +1 -1
- package/dist/commands/crm/sync.js +1 -1
- package/dist/commands/crm/sync.js.map +1 -1
- package/dist/commands/policy/index.d.ts +3 -0
- package/dist/commands/policy/index.js +217 -0
- package/dist/commands/policy/index.js.map +1 -0
- package/dist/commands/trace/index.d.ts +3 -0
- package/dist/commands/trace/index.js +455 -0
- package/dist/commands/trace/index.js.map +1 -0
- package/dist/core/auth.js +19 -1
- package/dist/core/auth.js.map +1 -1
- package/dist/core/http.js +37 -2
- package/dist/core/http.js.map +1 -1
- package/dist/core/policy.d.ts +75 -0
- package/dist/core/policy.js +124 -6
- package/dist/core/policy.js.map +1 -1
- package/dist/core/vault.js +1 -1
- package/dist/mcp/server.js +17 -1
- package/dist/mcp/server.js.map +1 -1
- package/docs/policy-templates/business-hours.json +21 -0
- package/docs/policy-templates/change-ticket-required.json +35 -0
- package/docs/policy-templates/compliance-strict.json +36 -0
- package/docs/policy-templates/no-deletes.json +17 -0
- package/docs/policy-templates/read-only.json +17 -0
- package/package.json +6 -5
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { CliError, printResult } from "../../core/output.js";
|
|
5
|
+
import { readPolicyFile, findMatchingRule } from "../../core/policy.js";
|
|
6
|
+
function getTemplatesDir() {
|
|
7
|
+
// Templates ship alongside the built dist/. When running via `hscli` binary,
|
|
8
|
+
// we need to walk up from the module's dist location to find the docs/ dir.
|
|
9
|
+
// This only matters for installed npm package — in dev mode tsc outputs
|
|
10
|
+
// into dist/ and the docs/ dir is at the repo root.
|
|
11
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
12
|
+
// dist/commands/policy/index.js → repo root
|
|
13
|
+
const candidates = [
|
|
14
|
+
resolve(dirname(thisFile), "../../../docs/policy-templates"),
|
|
15
|
+
resolve(dirname(thisFile), "../../../../docs/policy-templates"),
|
|
16
|
+
resolve(dirname(thisFile), "../../docs/policy-templates"),
|
|
17
|
+
];
|
|
18
|
+
for (const candidate of candidates) {
|
|
19
|
+
if (existsSync(candidate))
|
|
20
|
+
return candidate;
|
|
21
|
+
}
|
|
22
|
+
// Last resort — this will only fail at runtime if templates are missing
|
|
23
|
+
return resolve(dirname(thisFile), "../../../docs/policy-templates");
|
|
24
|
+
}
|
|
25
|
+
function getPolicyPath(ctx) {
|
|
26
|
+
return ctx.policyFile?.trim() || process.env.HSCLI_POLICY_FILE?.trim();
|
|
27
|
+
}
|
|
28
|
+
export function registerPolicy(program, getCtx) {
|
|
29
|
+
const policy = program.command("policy").description("Manage policy-as-code: audit the active policy, list/extract built-in templates, validate your own files.");
|
|
30
|
+
policy
|
|
31
|
+
.command("list")
|
|
32
|
+
.description("Show the active policy (from --policy-file or HSCLI_POLICY_FILE). Parses + summarizes all rules by profile.")
|
|
33
|
+
.action(async () => {
|
|
34
|
+
const ctx = getCtx();
|
|
35
|
+
const path = getPolicyPath(ctx);
|
|
36
|
+
if (!path) {
|
|
37
|
+
printResult(ctx, {
|
|
38
|
+
active: false,
|
|
39
|
+
message: "No policy file set. Pass --policy-file <path> or set HSCLI_POLICY_FILE env var.",
|
|
40
|
+
suggestions: [
|
|
41
|
+
"hscli policy templates # list built-in templates",
|
|
42
|
+
"hscli policy templates extract read-only --to ./policy.json",
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const config = readPolicyFile(path);
|
|
48
|
+
const summary = {
|
|
49
|
+
active: true,
|
|
50
|
+
file: path,
|
|
51
|
+
version: config.version ?? 1,
|
|
52
|
+
profiles: Object.fromEntries(Object.entries(config.profiles ?? {}).map(([name, cfg]) => [
|
|
53
|
+
name,
|
|
54
|
+
{
|
|
55
|
+
defaultAction: cfg.defaultAction ?? "allow",
|
|
56
|
+
ruleCount: cfg.rules?.length ?? 0,
|
|
57
|
+
ruleNames: (cfg.rules ?? []).map(r => r.name || "(unnamed)"),
|
|
58
|
+
legacyFlags: {
|
|
59
|
+
allowWrite: cfg.allowWrite,
|
|
60
|
+
allowDelete: cfg.allowDelete,
|
|
61
|
+
requireChangeTicket: cfg.requireChangeTicket,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
])),
|
|
65
|
+
hasDefaults: Boolean(config.defaults),
|
|
66
|
+
blockedPrefixes: config.blockedMethodPathPrefixes,
|
|
67
|
+
};
|
|
68
|
+
printResult(ctx, summary);
|
|
69
|
+
});
|
|
70
|
+
policy
|
|
71
|
+
.command("show-matching")
|
|
72
|
+
.description("Print which policy rule (if any) would be applied to a hypothetical request. Useful for verifying rules before shipping.")
|
|
73
|
+
.argument("<method>", "HTTP method: GET, POST, PATCH, PUT, DELETE")
|
|
74
|
+
.argument("<path>", "Request path (e.g. /crm/v3/objects/contacts/123)")
|
|
75
|
+
.option("--profile <name>", "Profile to evaluate against (defaults to the current --profile)")
|
|
76
|
+
.action(async (method, requestPath, opts) => {
|
|
77
|
+
const ctx = getCtx();
|
|
78
|
+
const policyPath = getPolicyPath(ctx);
|
|
79
|
+
if (!policyPath) {
|
|
80
|
+
throw new CliError("NO_POLICY_FILE", "No policy file configured. Pass --policy-file or set HSCLI_POLICY_FILE.");
|
|
81
|
+
}
|
|
82
|
+
const config = readPolicyFile(policyPath);
|
|
83
|
+
const profile = opts.profile || ctx.profile;
|
|
84
|
+
const profileConfig = config.profiles?.[profile] ?? config.defaults ?? {};
|
|
85
|
+
const matched = findMatchingRule(profileConfig, method, requestPath);
|
|
86
|
+
if (matched) {
|
|
87
|
+
printResult(ctx, {
|
|
88
|
+
profile,
|
|
89
|
+
request: { method, path: requestPath },
|
|
90
|
+
matchedRule: matched,
|
|
91
|
+
effectiveAction: matched.action ?? "allow",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
printResult(ctx, {
|
|
96
|
+
profile,
|
|
97
|
+
request: { method, path: requestPath },
|
|
98
|
+
matchedRule: null,
|
|
99
|
+
effectiveAction: profileConfig.defaultAction ?? "allow",
|
|
100
|
+
note: "No rule matched. Falling back to the profile's defaultAction.",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
policy
|
|
105
|
+
.command("validate")
|
|
106
|
+
.description("Parse + semantic-check a policy file without enforcing it.")
|
|
107
|
+
.argument("[file]", "Policy file path (default: the active --policy-file / HSCLI_POLICY_FILE)")
|
|
108
|
+
.action(async (fileArg) => {
|
|
109
|
+
const ctx = getCtx();
|
|
110
|
+
const path = fileArg || getPolicyPath(ctx);
|
|
111
|
+
if (!path) {
|
|
112
|
+
throw new CliError("NO_POLICY_FILE", "No file passed and no active policy configured.");
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const config = readPolicyFile(path);
|
|
116
|
+
const issues = [];
|
|
117
|
+
const warnings = [];
|
|
118
|
+
for (const [profileName, cfg] of Object.entries(config.profiles ?? {})) {
|
|
119
|
+
for (const rule of cfg.rules ?? []) {
|
|
120
|
+
if (!rule.match)
|
|
121
|
+
warnings.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has no match criteria — will match everything`);
|
|
122
|
+
if (rule.action && rule.action !== "allow" && rule.action !== "deny")
|
|
123
|
+
issues.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has invalid action '${rule.action}' (must be 'allow' or 'deny')`);
|
|
124
|
+
if (rule.window?.days && !/^[a-z]{3}(-[a-z]{3}|(,[a-z]{3})*)$/i.test(rule.window.days.trim())) {
|
|
125
|
+
warnings.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has non-standard window.days syntax: '${rule.window.days}'`);
|
|
126
|
+
}
|
|
127
|
+
if (rule.window?.hours && !/^\d{1,2}-\d{1,2}$/.test(rule.window.hours)) {
|
|
128
|
+
issues.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has invalid window.hours: '${rule.window.hours}' (must be 'HH-HH' 24h format)`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
printResult(ctx, {
|
|
133
|
+
valid: issues.length === 0,
|
|
134
|
+
file: path,
|
|
135
|
+
version: config.version ?? 1,
|
|
136
|
+
profileCount: Object.keys(config.profiles ?? {}).length,
|
|
137
|
+
totalRules: Object.values(config.profiles ?? {}).reduce((s, c) => s + (c.rules?.length ?? 0), 0),
|
|
138
|
+
issues,
|
|
139
|
+
warnings,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
if (err instanceof CliError)
|
|
144
|
+
throw err;
|
|
145
|
+
throw new CliError("POLICY_PARSE_ERROR", err instanceof Error ? err.message : String(err));
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
const templates = policy.command("templates").description("Built-in policy templates for common trust scenarios");
|
|
149
|
+
templates
|
|
150
|
+
.command("list")
|
|
151
|
+
.description("List available built-in policy templates")
|
|
152
|
+
.action(async () => {
|
|
153
|
+
const ctx = getCtx();
|
|
154
|
+
const dir = getTemplatesDir();
|
|
155
|
+
if (!existsSync(dir)) {
|
|
156
|
+
throw new CliError("TEMPLATES_DIR_MISSING", `Template directory not found: ${dir}`);
|
|
157
|
+
}
|
|
158
|
+
const files = readdirSync(dir).filter(f => f.endsWith(".json"));
|
|
159
|
+
const templatesWithMeta = files.map(f => {
|
|
160
|
+
try {
|
|
161
|
+
const content = JSON.parse(readFileSync(join(dir, f), "utf8"));
|
|
162
|
+
return { name: f.replace(/\.json$/, ""), version: content.version, description: content.description ?? "(no description)" };
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return { name: f.replace(/\.json$/, ""), version: undefined, description: "(failed to parse)" };
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
printResult(ctx, {
|
|
169
|
+
count: templatesWithMeta.length,
|
|
170
|
+
templates: templatesWithMeta,
|
|
171
|
+
note: "Use `hscli policy templates show <name>` to view; `hscli policy templates extract <name> --to <file>` to copy.",
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
templates
|
|
175
|
+
.command("show")
|
|
176
|
+
.description("Print a template's content")
|
|
177
|
+
.argument("<name>", "Template name (from `hscli policy templates list`)")
|
|
178
|
+
.action(async (name) => {
|
|
179
|
+
const ctx = getCtx();
|
|
180
|
+
const path = join(getTemplatesDir(), `${name}.json`);
|
|
181
|
+
if (!existsSync(path)) {
|
|
182
|
+
throw new CliError("TEMPLATE_NOT_FOUND", `Template '${name}' not found. Available: ${readdirSync(getTemplatesDir()).filter(f => f.endsWith(".json")).map(f => f.replace(/\.json$/, "")).join(", ")}`);
|
|
183
|
+
}
|
|
184
|
+
const content = JSON.parse(readFileSync(path, "utf8"));
|
|
185
|
+
printResult(ctx, content);
|
|
186
|
+
});
|
|
187
|
+
templates
|
|
188
|
+
.command("extract")
|
|
189
|
+
.description("Copy a built-in template to a local file for editing")
|
|
190
|
+
.argument("<name>", "Template name")
|
|
191
|
+
.requiredOption("--to <file>", "Destination file path")
|
|
192
|
+
.action(async (name, opts) => {
|
|
193
|
+
const ctx = getCtx();
|
|
194
|
+
const srcPath = join(getTemplatesDir(), `${name}.json`);
|
|
195
|
+
if (!existsSync(srcPath)) {
|
|
196
|
+
throw new CliError("TEMPLATE_NOT_FOUND", `Template '${name}' not found.`);
|
|
197
|
+
}
|
|
198
|
+
const dest = String(opts.to);
|
|
199
|
+
if (existsSync(dest)) {
|
|
200
|
+
throw new CliError("DEST_FILE_EXISTS", `Destination file already exists: ${dest}. Delete it first or choose another path.`);
|
|
201
|
+
}
|
|
202
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
203
|
+
const content = readFileSync(srcPath, "utf8");
|
|
204
|
+
writeFileSync(dest, content, { encoding: "utf8", mode: 0o644 });
|
|
205
|
+
printResult(ctx, {
|
|
206
|
+
extracted: true,
|
|
207
|
+
from: srcPath,
|
|
208
|
+
to: dest,
|
|
209
|
+
nextSteps: [
|
|
210
|
+
`hscli policy validate ${dest}`,
|
|
211
|
+
`hscli --policy-file ${dest} crm contacts list`,
|
|
212
|
+
`export HSCLI_POLICY_FILE=${dest}`,
|
|
213
|
+
],
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/policy/index.ts"],"names":[],"mappings":"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"}
|