@stratusagent/permissions 0.10.0 → 0.11.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/dist/commands.d.ts +26 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +120 -4
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts +64 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +260 -25
- package/dist/index.js.map +1 -1
- package/dist/origins.d.ts +72 -0
- package/dist/origins.d.ts.map +1 -0
- package/dist/origins.js +73 -0
- package/dist/origins.js.map +1 -0
- package/dist/whitelist.d.ts +39 -8
- package/dist/whitelist.d.ts.map +1 -1
- package/dist/whitelist.js +136 -29
- package/dist/whitelist.js.map +1 -1
- package/package.json +2 -2
package/dist/whitelist.d.ts
CHANGED
|
@@ -1,26 +1,51 @@
|
|
|
1
1
|
import { type CommandScope } from './commands.ts';
|
|
2
|
+
import { type OriginScope } from './origins.ts';
|
|
2
3
|
/**
|
|
3
4
|
* What one agent may run unattended, beyond the built-in safe list.
|
|
4
5
|
*
|
|
5
6
|
* Per agent, because "always allow" is an answer about one identity's work
|
|
6
7
|
* — a scope somebody granted Ava in a repository of theirs is not a scope
|
|
7
|
-
* Juno inherits.
|
|
8
|
+
* Juno inherits, and neither is a site.
|
|
8
9
|
*/
|
|
9
10
|
export interface CommandWhitelistStore {
|
|
10
11
|
scopesFor(agentId: string): Promise<CommandScope[]>;
|
|
11
12
|
remember(agentId: string, scope: CommandScope): Promise<void>;
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Which origins one agent may act on unattended — `commandFor`'s half of
|
|
16
|
+
* the same file, for `originFor`.
|
|
17
|
+
*
|
|
18
|
+
* A separate interface rather than two more methods on the one above,
|
|
19
|
+
* because they are separate answers: a host that judges commands need not
|
|
20
|
+
* judge browser actions, and `createFileCommandWhitelist` returns one
|
|
21
|
+
* object satisfying both because there is one file and an operator should
|
|
22
|
+
* have one place to look.
|
|
23
|
+
*/
|
|
24
|
+
export interface OriginWhitelistStore {
|
|
25
|
+
originsFor(agentId: string): Promise<OriginScope[]>;
|
|
26
|
+
rememberOrigin(agentId: string, scope: OriginScope): Promise<void>;
|
|
27
|
+
}
|
|
13
28
|
/** `<id>.whitelist.json`, beside the agent's soul in ~/.stratus/agents. */
|
|
14
29
|
export declare const whitelistPathFor: (directory: string, agentId: string) => string;
|
|
15
30
|
/**
|
|
16
|
-
*
|
|
31
|
+
* Thrown by `remember` for an agent whose whitelist exists but could not be
|
|
32
|
+
* read. The policy catches it by type: the answer still holds for the
|
|
33
|
+
* session, and the log says why it was not saved.
|
|
34
|
+
*/
|
|
35
|
+
export declare class WhitelistUnreadableError extends Error {
|
|
36
|
+
constructor(file: string, reason: string);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The persistent tier of the scope resolution, on disk — both kinds of
|
|
40
|
+
* grant, in one file per agent.
|
|
17
41
|
*
|
|
18
42
|
* Written `0600` with an explicit `chmod`, like every other file in
|
|
19
|
-
* `~/.stratus` that decides something: this one lists commands that run
|
|
20
|
-
* with nobody watching
|
|
21
|
-
* to it is the whole permission engine
|
|
22
|
-
* applies when it creates the file, so
|
|
23
|
-
* would otherwise keep the old
|
|
43
|
+
* `~/.stratus` that decides something: this one lists commands that run,
|
|
44
|
+
* and sites that get clicked on, with nobody watching — so another account
|
|
45
|
+
* on the machine appending a line to it is the whole permission engine
|
|
46
|
+
* defeated. `writeFile`'s mode only applies when it creates the file, so
|
|
47
|
+
* an upgrade over a looser install would otherwise keep the old
|
|
48
|
+
* permissions.
|
|
24
49
|
*
|
|
25
50
|
* Scopes are cached in memory once read. A daemon therefore does not notice
|
|
26
51
|
* a hand-edited file until it restarts — which is the right way round for a
|
|
@@ -29,5 +54,11 @@ export declare const whitelistPathFor: (directory: string, agentId: string) => s
|
|
|
29
54
|
*/
|
|
30
55
|
export declare const createFileCommandWhitelist: (options: {
|
|
31
56
|
directory: string;
|
|
32
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Where to say that a whitelist exists but could not be read. Once per
|
|
59
|
+
* agent per process; a host that omits it gets the same behavior with
|
|
60
|
+
* no line about it.
|
|
61
|
+
*/
|
|
62
|
+
warn?: (line: string) => void;
|
|
63
|
+
}) => CommandWhitelistStore & OriginWhitelistStore;
|
|
33
64
|
//# sourceMappingURL=whitelist.d.ts.map
|
package/dist/whitelist.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whitelist.d.ts","sourceRoot":"","sources":["../src/whitelist.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"whitelist.d.ts","sourceRoot":"","sources":["../src/whitelist.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAqC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEnF;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAgCD,2EAA2E;AAC3E,eAAO,MAAM,gBAAgB,GAAI,WAAW,MAAM,EAAE,SAAS,MAAM,KAAG,MACnB,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,0BAA0B,GAAI,SAAS;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,KAAG,qBAAqB,GAAG,oBAmJ3B,CAAC"}
|
package/dist/whitelist.js
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { parseCommandScope, sameScope } from "./commands.js";
|
|
4
|
+
import { parseOriginScope, sameOriginScope } from "./origins.js";
|
|
4
5
|
const WHITELIST_VERSION = 1;
|
|
5
6
|
/** `<id>.whitelist.json`, beside the agent's soul in ~/.stratus/agents. */
|
|
6
7
|
export const whitelistPathFor = (directory, agentId) => path.join(directory, `${agentId}.whitelist.json`);
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Thrown by `remember` for an agent whose whitelist exists but could not be
|
|
10
|
+
* read. The policy catches it by type: the answer still holds for the
|
|
11
|
+
* session, and the log says why it was not saved.
|
|
12
|
+
*/
|
|
13
|
+
export class WhitelistUnreadableError extends Error {
|
|
14
|
+
constructor(file, reason) {
|
|
15
|
+
super(`${file} could not be read (${reason}), so nothing is written over it. Fix the file and restart the daemon.`);
|
|
16
|
+
this.name = 'WhitelistUnreadableError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The persistent tier of the scope resolution, on disk — both kinds of
|
|
21
|
+
* grant, in one file per agent.
|
|
9
22
|
*
|
|
10
23
|
* Written `0600` with an explicit `chmod`, like every other file in
|
|
11
|
-
* `~/.stratus` that decides something: this one lists commands that run
|
|
12
|
-
* with nobody watching
|
|
13
|
-
* to it is the whole permission engine
|
|
14
|
-
* applies when it creates the file, so
|
|
15
|
-
* would otherwise keep the old
|
|
24
|
+
* `~/.stratus` that decides something: this one lists commands that run,
|
|
25
|
+
* and sites that get clicked on, with nobody watching — so another account
|
|
26
|
+
* on the machine appending a line to it is the whole permission engine
|
|
27
|
+
* defeated. `writeFile`'s mode only applies when it creates the file, so
|
|
28
|
+
* an upgrade over a looser install would otherwise keep the old
|
|
29
|
+
* permissions.
|
|
16
30
|
*
|
|
17
31
|
* Scopes are cached in memory once read. A daemon therefore does not notice
|
|
18
32
|
* a hand-edited file until it restarts — which is the right way round for a
|
|
@@ -20,49 +34,142 @@ export const whitelistPathFor = (directory, agentId) => path.join(directory, `${
|
|
|
20
34
|
* store makes.
|
|
21
35
|
*/
|
|
22
36
|
export const createFileCommandWhitelist = (options) => {
|
|
37
|
+
/**
|
|
38
|
+
* One read per agent per process, shared by everyone who asks — as a
|
|
39
|
+
* promise, so two sessions asking for the same agent at once share the
|
|
40
|
+
* read in flight rather than each missing an empty cache, each failing,
|
|
41
|
+
* and each warning.
|
|
42
|
+
*
|
|
43
|
+
* Both grant lists come out of one read, because they come out of one
|
|
44
|
+
* file: reading it twice would give a shell call and a browser call
|
|
45
|
+
* different views of a file somebody edited between them.
|
|
46
|
+
*/
|
|
23
47
|
const cache = new Map();
|
|
24
|
-
|
|
48
|
+
/** Files that exist and could not be read, by agent — never written over. */
|
|
49
|
+
const unreadable = new Map();
|
|
50
|
+
const read = (agentId) => {
|
|
25
51
|
const cached = cache.get(agentId);
|
|
26
52
|
if (cached) {
|
|
27
53
|
return cached;
|
|
28
54
|
}
|
|
55
|
+
const reading = readFresh(agentId);
|
|
56
|
+
cache.set(agentId, reading);
|
|
57
|
+
return reading;
|
|
58
|
+
};
|
|
59
|
+
const readFresh = async (agentId) => {
|
|
29
60
|
let scopes = [];
|
|
61
|
+
let origins = [];
|
|
62
|
+
// The agent id is a validated invariant by the time it reaches any
|
|
63
|
+
// path join (see 03) — it is a single path segment or it was refused
|
|
64
|
+
// at the parse boundary, so this does not re-check it.
|
|
65
|
+
const file = whitelistPathFor(options.directory, agentId);
|
|
30
66
|
try {
|
|
31
|
-
|
|
32
|
-
// path join (see 03) — it is a single path segment or it was refused
|
|
33
|
-
// at the parse boundary, so this does not re-check it.
|
|
34
|
-
const raw = await readFile(whitelistPathFor(options.directory, agentId), 'utf8');
|
|
67
|
+
const raw = await readFile(file, 'utf8');
|
|
35
68
|
const parsed = JSON.parse(raw);
|
|
36
69
|
scopes = Array.isArray(parsed.scopes)
|
|
37
70
|
? parsed.scopes.map(parseCommandScope).filter((scope) => scope !== undefined)
|
|
38
71
|
: [];
|
|
72
|
+
origins = Array.isArray(parsed.origins)
|
|
73
|
+
? parsed.origins.map(parseOriginScope).filter((scope) => scope !== undefined)
|
|
74
|
+
: [];
|
|
39
75
|
}
|
|
40
|
-
catch {
|
|
41
|
-
// No whitelist
|
|
42
|
-
// to a caller — no stored scopes — and neither is worth failing a
|
|
76
|
+
catch (error) {
|
|
77
|
+
// No whitelist means no stored scopes, and is not worth failing a
|
|
43
78
|
// turn over: the fallback is asking a human, which is where an agent
|
|
44
|
-
// with no whitelist starts anyway.
|
|
79
|
+
// with no whitelist starts anyway. A whitelist that exists and will
|
|
80
|
+
// not read is the same to this call and not the same to the file:
|
|
81
|
+
// one hand-edited comma made a grant list read as empty with no line
|
|
82
|
+
// about it, and the next "always" wrote a single new scope over
|
|
83
|
+
// every grant it held. So it is said once, and `remember` refuses.
|
|
45
84
|
scopes = [];
|
|
85
|
+
origins = [];
|
|
86
|
+
if (error.code !== 'ENOENT') {
|
|
87
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
88
|
+
unreadable.set(agentId, reason);
|
|
89
|
+
options.warn?.(`${file} could not be read (${reason}); its scopes are ignored and "always" answers for ${agentId} `
|
|
90
|
+
+ 'are not saved over it until it is fixed and the daemon restarted.');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { scopes, origins };
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Both lists, always — a write of one carries the other through
|
|
97
|
+
* untouched. Persisting only the half that changed would drop the other
|
|
98
|
+
* half of a file this daemon had read and understood, which is the same
|
|
99
|
+
* data loss the unreadable-file guard above exists to prevent.
|
|
100
|
+
*/
|
|
101
|
+
const save = async (agentId, grants) => {
|
|
102
|
+
cache.set(agentId, Promise.resolve(grants));
|
|
103
|
+
await mkdir(options.directory, { recursive: true });
|
|
104
|
+
const file = {
|
|
105
|
+
version: WHITELIST_VERSION,
|
|
106
|
+
scopes: grants.scopes,
|
|
107
|
+
...(grants.origins.length > 0 ? { origins: grants.origins } : {}),
|
|
108
|
+
};
|
|
109
|
+
const target = whitelistPathFor(options.directory, agentId);
|
|
110
|
+
await writeFile(target, `${JSON.stringify(file, null, 2)}\n`, { mode: 0o600 });
|
|
111
|
+
await chmod(target, 0o600);
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Read-modify-write runs one at a time per agent.
|
|
115
|
+
*
|
|
116
|
+
* Every grant is "read what is there, add one, write it all back", and
|
|
117
|
+
* the read yields — so two answers settling together both saw the file
|
|
118
|
+
* before either changed it, and the second write drops the first grant.
|
|
119
|
+
* It bites hardest across the two kinds now that one file holds both: a
|
|
120
|
+
* shell "always" and a browser "always" resolved in the same moment, and
|
|
121
|
+
* whichever landed second silently deleted the other agent's site grant.
|
|
122
|
+
* Serializing also means only one `writeFile` is ever open on the file,
|
|
123
|
+
* so two overlapping writes cannot leave a mixed one behind.
|
|
124
|
+
*
|
|
125
|
+
* A queue, like the browser pool's admission: the work is short, and the
|
|
126
|
+
* alternative (reserving and unwinding) is the same serialization with
|
|
127
|
+
* more ways to leak a reservation. The tail swallows failures, so one
|
|
128
|
+
* grant that throws does not reject every grant queued behind it — the
|
|
129
|
+
* caller still sees its own rejection, because that is `queued`.
|
|
130
|
+
*/
|
|
131
|
+
const writes = new Map();
|
|
132
|
+
const serialized = (agentId, work) => {
|
|
133
|
+
const queued = (writes.get(agentId) ?? Promise.resolve()).then(work, work);
|
|
134
|
+
writes.set(agentId, queued.then(() => undefined, () => undefined));
|
|
135
|
+
return queued;
|
|
136
|
+
};
|
|
137
|
+
/** Nothing is written over a grant list nobody could read. */
|
|
138
|
+
const refuseIfUnreadable = (agentId) => {
|
|
139
|
+
const reason = unreadable.get(agentId);
|
|
140
|
+
if (reason !== undefined) {
|
|
141
|
+
throw new WhitelistUnreadableError(whitelistPathFor(options.directory, agentId), reason);
|
|
46
142
|
}
|
|
47
|
-
cache.set(agentId, scopes);
|
|
48
|
-
return scopes;
|
|
49
143
|
};
|
|
50
144
|
return {
|
|
51
145
|
async scopesFor(agentId) {
|
|
52
|
-
return [...(await read(agentId))];
|
|
146
|
+
return [...(await read(agentId)).scopes];
|
|
53
147
|
},
|
|
54
148
|
async remember(agentId, scope) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
149
|
+
// The read is inside the queue, not before it: a grant that started
|
|
150
|
+
// from a snapshot taken before the one ahead of it saved would write
|
|
151
|
+
// that one back out of existence, which is the whole race.
|
|
152
|
+
return serialized(agentId, async () => {
|
|
153
|
+
const grants = await read(agentId);
|
|
154
|
+
refuseIfUnreadable(agentId);
|
|
155
|
+
if (grants.scopes.some((existing) => sameScope(existing, scope))) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
await save(agentId, { ...grants, scopes: [...grants.scopes, scope] });
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
async originsFor(agentId) {
|
|
162
|
+
return [...(await read(agentId)).origins];
|
|
163
|
+
},
|
|
164
|
+
async rememberOrigin(agentId, scope) {
|
|
165
|
+
return serialized(agentId, async () => {
|
|
166
|
+
const grants = await read(agentId);
|
|
167
|
+
refuseIfUnreadable(agentId);
|
|
168
|
+
if (grants.origins.some((existing) => sameOriginScope(existing, scope))) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
await save(agentId, { ...grants, origins: [...grants.origins, scope] });
|
|
172
|
+
});
|
|
66
173
|
},
|
|
67
174
|
};
|
|
68
175
|
};
|
package/dist/whitelist.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whitelist.js","sourceRoot":"","sources":["../src/whitelist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAqB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"whitelist.js","sourceRoot":"","sources":["../src/whitelist.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratusagent/permissions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"node": ">=22.13 <23 || >=23.4"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@stratusagent/core": "0.
|
|
20
|
+
"@stratusagent/core": "0.11.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^24.6.0",
|