@tankpkg/cli 0.5.0 → 0.6.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/dist/commands/install.d.ts +1 -16
- package/dist/commands/install.js +330 -363
- package/dist/commands/install.js.map +1 -1
- package/dist/lib/dependency-resolver.d.ts +51 -0
- package/dist/lib/dependency-resolver.js +181 -0
- package/dist/lib/dependency-resolver.js.map +1 -0
- package/dist/lib/install-pipeline.d.ts +23 -0
- package/dist/lib/install-pipeline.js +181 -0
- package/dist/lib/install-pipeline.js.map +1 -0
- package/dist/lib/permission-checker.d.ts +16 -0
- package/dist/lib/permission-checker.js +78 -0
- package/dist/lib/permission-checker.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if a skill's permissions fit within the project's permission budget.
|
|
3
|
+
* Throws if any permission exceeds the budget.
|
|
4
|
+
*/
|
|
5
|
+
export function checkPermissionBudget(budget, skillPerms, skillName) {
|
|
6
|
+
if (!skillPerms)
|
|
7
|
+
return;
|
|
8
|
+
// Check subprocess
|
|
9
|
+
if (skillPerms.subprocess === true && budget.subprocess !== true) {
|
|
10
|
+
throw new Error(`Permission denied: ${skillName} requires subprocess access, but project budget does not allow it`);
|
|
11
|
+
}
|
|
12
|
+
// Check network outbound
|
|
13
|
+
if (skillPerms.network?.outbound && skillPerms.network.outbound.length > 0) {
|
|
14
|
+
const budgetDomains = budget.network?.outbound ?? [];
|
|
15
|
+
for (const domain of skillPerms.network.outbound) {
|
|
16
|
+
if (!isDomainAllowed(domain, budgetDomains)) {
|
|
17
|
+
throw new Error(`Permission denied: ${skillName} requests network access to "${domain}", which is not in the project's permission budget`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// Check filesystem read
|
|
22
|
+
if (skillPerms.filesystem?.read && skillPerms.filesystem.read.length > 0) {
|
|
23
|
+
const budgetPaths = budget.filesystem?.read ?? [];
|
|
24
|
+
for (const p of skillPerms.filesystem.read) {
|
|
25
|
+
if (!isPathAllowed(p, budgetPaths)) {
|
|
26
|
+
throw new Error(`Permission denied: ${skillName} requests filesystem read access to "${p}", which is not in the project's permission budget`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Check filesystem write
|
|
31
|
+
if (skillPerms.filesystem?.write && skillPerms.filesystem.write.length > 0) {
|
|
32
|
+
const budgetPaths = budget.filesystem?.write ?? [];
|
|
33
|
+
for (const p of skillPerms.filesystem.write) {
|
|
34
|
+
if (!isPathAllowed(p, budgetPaths)) {
|
|
35
|
+
throw new Error(`Permission denied: ${skillName} requests filesystem write access to "${p}", which is not in the project's permission budget`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if a domain is allowed by the budget's domain list.
|
|
42
|
+
* Supports wildcard matching: *.example.com matches sub.example.com
|
|
43
|
+
*/
|
|
44
|
+
export function isDomainAllowed(domain, allowedDomains) {
|
|
45
|
+
for (const allowed of allowedDomains) {
|
|
46
|
+
if (allowed === domain)
|
|
47
|
+
return true;
|
|
48
|
+
// Wildcard matching: *.example.com
|
|
49
|
+
if (allowed.startsWith('*.')) {
|
|
50
|
+
const suffix = allowed.slice(1); // .example.com
|
|
51
|
+
if (domain.endsWith(suffix) || domain === allowed.slice(2)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// Also match if the skill requests the same wildcard pattern
|
|
55
|
+
if (domain === allowed)
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if a path is allowed by the budget's path list.
|
|
63
|
+
* Simple subset check: skill path must match one of the budget paths.
|
|
64
|
+
*/
|
|
65
|
+
export function isPathAllowed(requestedPath, allowedPaths) {
|
|
66
|
+
for (const allowed of allowedPaths) {
|
|
67
|
+
if (allowed === requestedPath)
|
|
68
|
+
return true;
|
|
69
|
+
// If budget allows ./src/** and skill requests ./src/foo, it's allowed
|
|
70
|
+
if (allowed.endsWith('/**')) {
|
|
71
|
+
const prefix = allowed.slice(0, -3); // ./src
|
|
72
|
+
if (requestedPath.startsWith(prefix))
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=permission-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-checker.js","sourceRoot":"","sources":["../../src/lib/permission-checker.ts"],"names":[],"mappings":"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"}
|