@nullsquare/agent-authority 0.4.5 → 0.4.7
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/README.md +296 -295
- package/ROADMAP.md +145 -105
- package/benchmarks/task-utility.mjs +130 -0
- package/docs/connected-execution-api.md +60 -0
- package/docs/connected-github.md +140 -0
- package/docs/npm-release.md +30 -10
- package/docs/product-proof.md +311 -0
- package/docs/quickstart.md +147 -0
- package/docs/release-v0.4.7.md +29 -0
- package/examples/live-github-derived-mutation.js +47 -54
- package/examples/quickstart-github-connected.mjs +77 -0
- package/examples/quickstart-github-live.mjs +84 -0
- package/examples/quickstart.mjs +101 -0
- package/examples/task-first-finance.js +223 -0
- package/examples/task-first-github.js +102 -0
- package/examples/task-first-support.js +127 -0
- package/package.json +9 -4
- package/src/cli.js +3 -3
- package/src/connections.js +19 -4
- package/src/task.js +279 -0
package/README.md
CHANGED
|
@@ -6,64 +6,29 @@
|
|
|
6
6
|
|
|
7
7
|
### Give your agent a task, not your account.
|
|
8
8
|
|
|
9
|
-
**Agent Authority
|
|
9
|
+
**Agent Authority is a small execution layer that lets an agent use existing account permissions only for the task the user actually gave it.**
|
|
10
10
|
|
|
11
|
-
[
|
|
11
|
+
[Quickstart](docs/quickstart.md) · [Task-first API](#task-first-api) · [Product proof gate](docs/product-proof.md) · [Task Leases](docs/task-leases.md) · [Durability](docs/durable-task-leases.md) · [Evidence](docs/evidence.md) · [Transport invariance](docs/transport-invariance.md) · [Roadmap](ROADMAP.md)
|
|
12
12
|
|
|
13
|
-
> **Status: public pre-alpha / v0.4.
|
|
13
|
+
> **Status: public pre-alpha / v0.4.6 Developer Preview on npm.** The task-first API is published as `@nullsquare/agent-authority/task`. Agent Authority is not production-ready yet.
|
|
14
14
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
-
##
|
|
18
|
-
|
|
19
|
-
Requires Node.js 20+.
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install @nullsquare/agent-authority
|
|
23
|
-
```
|
|
17
|
+
## Why this exists
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
A user gives an agent a narrow task:
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
A user says:
|
|
30
|
-
|
|
31
|
-
> **Handle the demo request in this email thread.**
|
|
32
|
-
|
|
33
|
-
The agent may need to:
|
|
34
|
-
|
|
35
|
-
```text
|
|
36
|
-
Gmail -> read one thread
|
|
37
|
-
|
|
|
38
|
-
v
|
|
39
|
-
discover sender
|
|
40
|
-
|
|
|
41
|
-
v
|
|
42
|
-
Calendar -> create one meeting with that sender
|
|
43
|
-
|
|
|
44
|
-
v
|
|
45
|
-
Gmail -> reply in the originating thread
|
|
46
|
-
```
|
|
21
|
+
> **Handle this customer email.**
|
|
47
22
|
|
|
48
|
-
|
|
23
|
+
But the connected account may give the application broad standing permission to read every email, create meetings with anyone, update any CRM record, or send mail to anyone.
|
|
49
24
|
|
|
50
|
-
|
|
25
|
+
OAuth and IAM answer:
|
|
51
26
|
|
|
52
27
|
> Can this application use Calendar?
|
|
53
28
|
|
|
54
|
-
Agent Authority asks
|
|
29
|
+
Agent Authority asks immediately before the effect:
|
|
55
30
|
|
|
56
|
-
> **Is this exact
|
|
57
|
-
|
|
58
|
-
## Task-bounded autonomy
|
|
59
|
-
|
|
60
|
-
Agent Authority is trying to make this trade-off unnecessary:
|
|
61
|
-
|
|
62
|
-
```text
|
|
63
|
-
broad standing permissions
|
|
64
|
-
OR
|
|
65
|
-
approve every tool call
|
|
66
|
-
```
|
|
31
|
+
> **Is this exact Calendar action justified by the task the user authorized?**
|
|
67
32
|
|
|
68
33
|
The target is:
|
|
69
34
|
|
|
@@ -73,355 +38,391 @@ one meaningful task approval
|
|
|
73
38
|
v
|
|
74
39
|
temporary bounded authority
|
|
75
40
|
|
|
|
76
|
-
+-->
|
|
77
|
-
+-->
|
|
78
|
-
+-->
|
|
41
|
+
+--> useful task actions proceed normally
|
|
42
|
+
+--> authority may follow resources discovered through authorized work
|
|
43
|
+
+--> unrelated resources require step-up
|
|
79
44
|
|
|
|
80
45
|
v
|
|
81
|
-
task completes -> authority disappears
|
|
46
|
+
task completes -> task authority disappears
|
|
82
47
|
```
|
|
83
48
|
|
|
84
49
|
The provider credential may continue to exist. The **task authority does not**.
|
|
85
50
|
|
|
86
|
-
##
|
|
87
|
-
|
|
88
|
-
Many resources do not exist in the original prompt. The agent discovers them while working.
|
|
51
|
+
## Install
|
|
89
52
|
|
|
90
|
-
|
|
53
|
+
Requires Node.js 20+.
|
|
91
54
|
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
|
|
|
95
|
-
v
|
|
96
|
-
authority root
|
|
97
|
-
Gmail thread #91
|
|
98
|
-
|
|
|
99
|
-
authorized read
|
|
100
|
-
|
|
|
101
|
-
+--> ALLOW receipt
|
|
102
|
-
+--> exact output hash evidence
|
|
103
|
-
|
|
|
104
|
-
v
|
|
105
|
-
reviewed adapter extractor
|
|
106
|
-
|
|
|
107
|
-
v
|
|
108
|
-
derived fact
|
|
109
|
-
customer@example.com
|
|
110
|
-
|
|
|
111
|
-
v
|
|
112
|
-
exact binding
|
|
113
|
-
Calendar attendee must equal that sender
|
|
55
|
+
```bash
|
|
56
|
+
npm install @nullsquare/agent-authority
|
|
114
57
|
```
|
|
115
58
|
|
|
116
|
-
|
|
59
|
+
## Fresh-install quickstart
|
|
117
60
|
|
|
118
|
-
|
|
61
|
+
You can see the task-authority model without a repository checkout, provider credential, OAuth setup, custom extractor, or Mission JSON.
|
|
119
62
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
63
|
+
```bash
|
|
64
|
+
mkdir agent-authority-quickstart
|
|
65
|
+
cd agent-authority-quickstart
|
|
66
|
+
npm init -y
|
|
67
|
+
npm install @nullsquare/agent-authority
|
|
68
|
+
curl -fsSL https://raw.githubusercontent.com/Null-Square/agent-authority/main/examples/quickstart.mjs -o quickstart.mjs
|
|
69
|
+
node quickstart.mjs
|
|
70
|
+
```
|
|
123
71
|
|
|
124
|
-
|
|
72
|
+
Expected shape:
|
|
125
73
|
|
|
126
74
|
```text
|
|
127
|
-
|
|
75
|
+
ALLOW -> task discovered issue #42 and the exact comment effect ran
|
|
76
|
+
STEP-UP -> The task established authority for 42 but this action requested 7.
|
|
77
|
+
PASS -> useful task work ran; unrelated standing permission did not become task authority
|
|
128
78
|
```
|
|
129
79
|
|
|
130
|
-
The
|
|
80
|
+
The quickstart uses the real published `createTask()` API and reviewed GitHub authority extractor. Only the provider callback is a local provider-shaped fixture so the first run needs no account.
|
|
131
81
|
|
|
132
|
-
|
|
82
|
+
An automated blank-project gate independently installed `@nullsquare/agent-authority@0.4.6` from npm on Node 20 and ran this exact file successfully. That proves the current published package supports the documented path; it does **not** replace the still-open first-time-human under-10-minute adoption test.
|
|
133
83
|
|
|
134
|
-
|
|
84
|
+
### Next: make one real GitHub call, still with no credential
|
|
135
85
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Requirements: Node.js 20+.
|
|
86
|
+
From the same blank project:
|
|
139
87
|
|
|
140
88
|
```bash
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
npm install
|
|
144
|
-
npm test
|
|
145
|
-
npm run demo:task-lease
|
|
89
|
+
curl -fsSL https://raw.githubusercontent.com/Null-Square/agent-authority/main/examples/quickstart-github-live.mjs -o quickstart-github-live.mjs
|
|
90
|
+
node quickstart-github-live.mjs
|
|
146
91
|
```
|
|
147
92
|
|
|
148
|
-
|
|
93
|
+
Expected shape:
|
|
149
94
|
|
|
150
95
|
```text
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
96
|
+
Standing GitHub permission -> repo.read
|
|
97
|
+
Task authority -> Null-Square/agent-authority
|
|
98
|
+
GitHub mode -> public API; no credential required
|
|
99
|
+
ALLOW -> real GitHub returned Null-Square/agent-authority
|
|
100
|
+
STEP-UP -> The task established authority for "Null-Square/agent-authority" but this action requested "octocat/Hello-World".
|
|
101
|
+
PASS -> broader standing repo.read permission could not reach an unrelated repository for this task
|
|
157
102
|
```
|
|
158
103
|
|
|
159
|
-
|
|
104
|
+
This deliberately models the account/app capability as broader than the task. Mission-level `repo.read` can read repositories generally, while the Task authority root allows this task to reach only `Null-Square/agent-authority`. The first request makes one real public GitHub `fetch()`; the unrelated repository is stopped before a second network call.
|
|
105
|
+
|
|
106
|
+
A separate blank-project CI gate has passed this exact live path against npm `0.4.6`. Authenticated/private-repository onboarding remains separate follow-on work.
|
|
160
107
|
|
|
161
|
-
|
|
108
|
+
See [Fresh-install quickstart](docs/quickstart.md).
|
|
162
109
|
|
|
163
|
-
|
|
110
|
+
## Task-first API
|
|
164
111
|
|
|
165
|
-
|
|
112
|
+
The preferred developer surface is intentionally small:
|
|
166
113
|
|
|
167
|
-
|
|
114
|
+
```text
|
|
115
|
+
Task -> Effect -> Authority
|
|
116
|
+
```
|
|
168
117
|
|
|
169
118
|
```js
|
|
170
|
-
import {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
119
|
+
import { createTask } from '@nullsquare/agent-authority/task';
|
|
120
|
+
|
|
121
|
+
const task = createTask({
|
|
122
|
+
principal: 'user:me',
|
|
123
|
+
agent: 'agent:assistant',
|
|
124
|
+
request: 'Find issue #42 and leave one comment only on that issue',
|
|
125
|
+
|
|
126
|
+
permissions: {
|
|
127
|
+
github: {
|
|
128
|
+
allow: ['issue.list', 'issue.comment'],
|
|
129
|
+
deny: ['issue.close', 'repo.delete'],
|
|
130
|
+
constraints: { repository: ['acme/app'] }
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
authority: {
|
|
135
|
+
repository: {
|
|
136
|
+
kind: 'github.repository',
|
|
137
|
+
value: 'acme/app'
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
|
|
181
141
|
bindings: [
|
|
182
142
|
{
|
|
183
|
-
service: '
|
|
184
|
-
action: '
|
|
185
|
-
|
|
186
|
-
|
|
143
|
+
service: 'github',
|
|
144
|
+
action: 'issue.list',
|
|
145
|
+
field: 'repository',
|
|
146
|
+
authority: 'repository'
|
|
187
147
|
}
|
|
188
148
|
]
|
|
189
149
|
});
|
|
190
150
|
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
151
|
+
const discovery = await task.run({
|
|
152
|
+
service: 'github',
|
|
153
|
+
action: 'issue.list',
|
|
154
|
+
context: { repository: 'acme/app' }
|
|
155
|
+
}, () => github.listIssues());
|
|
156
|
+
|
|
157
|
+
const issue = task.authorityFrom(discovery, {
|
|
158
|
+
name: 'issue',
|
|
159
|
+
kind: 'github.issue.number',
|
|
160
|
+
from: 'repository',
|
|
161
|
+
extractor: selectedIssueExtractor
|
|
194
162
|
});
|
|
195
163
|
|
|
196
|
-
|
|
197
|
-
service: '
|
|
198
|
-
action: '
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const senderFact = lease.deriveFromEvidence({
|
|
203
|
-
fact_id: 'fact:sender-email',
|
|
204
|
-
kind: 'email.address',
|
|
205
|
-
from: ['fact:thread'],
|
|
206
|
-
receipt: read.receipt,
|
|
207
|
-
evidence: read.evidence,
|
|
208
|
-
output: read.output,
|
|
209
|
-
extractor: gmailThreadSenderAuthorityExtractor
|
|
164
|
+
task.bind({
|
|
165
|
+
service: 'github',
|
|
166
|
+
action: 'issue.comment',
|
|
167
|
+
field: 'issue_number',
|
|
168
|
+
authority: 'issue'
|
|
210
169
|
});
|
|
211
170
|
|
|
212
|
-
await
|
|
213
|
-
service: '
|
|
214
|
-
action: '
|
|
215
|
-
context: {
|
|
216
|
-
|
|
171
|
+
await task.run({
|
|
172
|
+
service: 'github',
|
|
173
|
+
action: 'issue.comment',
|
|
174
|
+
context: {
|
|
175
|
+
repository: 'acme/app',
|
|
176
|
+
issue_number: issue.value,
|
|
177
|
+
body: 'Handled.'
|
|
178
|
+
}
|
|
179
|
+
}, () => github.comment(issue.value, 'Handled.'));
|
|
217
180
|
```
|
|
218
181
|
|
|
219
|
-
|
|
182
|
+
If the agent changes `issue_number` to an unrelated issue, the callback does not run. Agent Authority returns an authority-delta step-up that can be explained to a human:
|
|
220
183
|
|
|
221
|
-
|
|
184
|
+
```js
|
|
185
|
+
try {
|
|
186
|
+
await task.run(unrelatedRequest, effect);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.log(task.explain(error).summary);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
222
191
|
|
|
223
|
-
|
|
192
|
+
Example output:
|
|
224
193
|
|
|
225
|
-
|
|
194
|
+
```text
|
|
195
|
+
The task established authority for 42 but this action requested 7.
|
|
196
|
+
```
|
|
226
197
|
|
|
227
|
-
|
|
198
|
+
The task-first API is a facade over the existing Mission, Task Lease, execution-evidence and guard primitives. It does not weaken or replace them.
|
|
228
199
|
|
|
229
|
-
|
|
200
|
+
## Run the product demo
|
|
201
|
+
|
|
202
|
+
From a checkout:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm install
|
|
206
|
+
npm run demo:task
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The self-contained GitHub-shaped demo performs:
|
|
230
210
|
|
|
231
211
|
```text
|
|
232
|
-
|
|
212
|
+
1. authorized issue discovery
|
|
213
|
+
2. exact guarded result becomes downstream authority
|
|
214
|
+
3. comment on the discovered issue succeeds
|
|
215
|
+
4. comment on an unrelated issue requires step-up
|
|
216
|
+
5. blocked attempt executes zero provider callbacks
|
|
233
217
|
```
|
|
234
218
|
|
|
235
|
-
|
|
219
|
+
The callback bodies are intentionally replaceable with the SDK/provider calls an application already uses.
|
|
236
220
|
|
|
237
|
-
|
|
221
|
+
## Utility benchmark
|
|
222
|
+
|
|
223
|
+
Security is necessary but not sufficient. Agent Authority also tracks whether normal agent work still succeeds without approval fatigue.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm run benchmark:task
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The first deterministic fixture measures:
|
|
230
|
+
|
|
231
|
+
- normal task completion rate;
|
|
232
|
+
- false approval rate;
|
|
233
|
+
- true authority-delta step-up rate;
|
|
234
|
+
- unauthorized effect rate;
|
|
235
|
+
- provider effects required for completed tasks.
|
|
236
|
+
|
|
237
|
+
Its current regression target is:
|
|
238
238
|
|
|
239
239
|
```text
|
|
240
|
-
|
|
240
|
+
normal task completion rate = 100%
|
|
241
|
+
false approval rate = 0%
|
|
242
|
+
true authority-delta step-up rate = 100%
|
|
243
|
+
unauthorized effect rate = 0%
|
|
241
244
|
```
|
|
242
245
|
|
|
243
|
-
|
|
246
|
+
This is a deterministic product regression fixture, **not a real-world benchmark**. Real provider and harness workloads should replace or supplement it as adoption grows.
|
|
247
|
+
|
|
248
|
+
See [Product proof gate](docs/product-proof.md).
|
|
249
|
+
|
|
250
|
+
## The differentiated mechanism
|
|
244
251
|
|
|
245
|
-
|
|
252
|
+
Many task resources are unknown when the user gives the instruction. They are discovered during execution.
|
|
253
|
+
|
|
254
|
+
Agent Authority lets authority follow those resources only when the value comes from already-authorized work:
|
|
246
255
|
|
|
247
256
|
```text
|
|
248
|
-
|
|
257
|
+
human-approved task
|
|
258
|
+
|
|
|
259
|
+
v
|
|
260
|
+
authority root
|
|
261
|
+
repository = acme/app
|
|
262
|
+
|
|
|
263
|
+
authorized issue discovery
|
|
264
|
+
|
|
|
265
|
+
+--> ALLOW receipt
|
|
266
|
+
+--> exact output evidence
|
|
267
|
+
|
|
|
268
|
+
reviewed extractor
|
|
269
|
+
|
|
|
270
|
+
v
|
|
271
|
+
derived authority
|
|
272
|
+
issue = 42
|
|
273
|
+
|
|
|
274
|
+
v
|
|
275
|
+
later effect may bind issue_number == 42
|
|
249
276
|
```
|
|
250
277
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
- explicit deny precedence
|
|
261
|
-
- resource/context constraints
|
|
262
|
-
- expiry and cumulative budgets
|
|
263
|
-
- delegation attenuation
|
|
264
|
-
- durable mission revocation
|
|
265
|
-
- Task Lease prototype
|
|
266
|
-
- explicit authority roots
|
|
267
|
-
- same-lease provenance-bound derived facts
|
|
268
|
-
- execution evidence binding an allowed receipt, request and exact output hash
|
|
269
|
-
- strict `deriveFromEvidence()` path where the caller cannot provide the authority value
|
|
270
|
-
- reviewed Gmail sender authority extractor bound to `gmail:thread.read`
|
|
271
|
-
- reviewed GitHub selected-issue-number extractor bound to marker-scoped `github:issue.list`
|
|
272
|
-
- shared Google/GitHub authority-extractor conformance suite
|
|
273
|
-
- legacy host-trusted `derive()` compatibility path
|
|
274
|
-
- required parent lineage and extraction selector
|
|
275
|
-
- exact context-field bindings
|
|
276
|
-
- authority-delta step-up signal
|
|
277
|
-
- immediate task completion/expiry enforcement
|
|
278
|
-
- Task Lease IDs/hashes in decision receipts
|
|
279
|
-
|
|
280
|
-
### Enforcement
|
|
281
|
-
|
|
282
|
-
- protocol-neutral `guard.run()` wrapper
|
|
283
|
-
- blocked side effects never invoke their callback
|
|
284
|
-
- successful guarded effects return separate execution evidence
|
|
285
|
-
- Task-Lease-aware MCP gateway/proxy evaluation
|
|
286
|
-
- Task-Lease-aware brokered execution via `ExecutingAuthorityRuntime.executeTaskLease()`
|
|
287
|
-
- brokered execution evidence bound to Task-Lease receipts
|
|
288
|
-
- SDK/MCP/broker transport-invariance conformance test
|
|
289
|
-
- real Vercel AI SDK `ToolLoopAgent` protected-tool harness proof
|
|
290
|
-
- unmapped executable AI SDK tools fail closed before their effect executes
|
|
291
|
-
- one-time human approvals bound to exact request
|
|
292
|
-
- mutation idempotency
|
|
293
|
-
- conservative uncertain-state handling
|
|
294
|
-
- signed harness action grants
|
|
295
|
-
- MCP v2 read-only gateway/proxy
|
|
296
|
-
|
|
297
|
-
### Credentials and runtime
|
|
298
|
-
|
|
299
|
-
- persistent connection metadata
|
|
300
|
-
- AES-256-GCM local encrypted secret store
|
|
301
|
-
- safe reconnect cleanup
|
|
302
|
-
- GitHub brokered execution without returning the token to the agent
|
|
303
|
-
- GitHub REST mappings for repository access plus evidence-derived `issue.list` / `issue.comment`
|
|
304
|
-
- Google REST provider mappings for Gmail thread reads and Calendar event mutations
|
|
305
|
-
- short-lived signed local agent-instance tokens
|
|
306
|
-
- local CLI/daemon
|
|
307
|
-
|
|
308
|
-
### Engineering quality
|
|
309
|
-
|
|
310
|
-
- adversarial authorization tests
|
|
311
|
-
- execution-evidence substitution, tampering, replay, cross-lease and selector tests
|
|
312
|
-
- the same provider-derived-authority conformance attacks against Google and GitHub
|
|
313
|
-
- cross-transport invariance test for direct SDK, MCP and brokered execution
|
|
314
|
-
- real AI SDK agent-loop tests for unauthorized, unmapped and completed-lease tool calls with zero underlying effects
|
|
315
|
-
- Node 20 and Node 22 CI
|
|
316
|
-
- coverage run
|
|
317
|
-
- package checks
|
|
318
|
-
- clean-consumer npm registry verification
|
|
319
|
-
- live GitHub read and evidence-derived mutation proofs
|
|
320
|
-
- CodeQL
|
|
321
|
-
|
|
322
|
-
## What is different from OAuth, IAM and MCP authorization?
|
|
323
|
-
|
|
324
|
-
Agent Authority is **not trying to replace them**.
|
|
325
|
-
|
|
326
|
-
OAuth/IAM answer who or what may access a provider and with which standing scopes. MCP authorization protects an MCP transport. Agent Authority operates at a different boundary:
|
|
278
|
+
A request for issue `42` can proceed.
|
|
279
|
+
|
|
280
|
+
A request for issue `7` does not inherit the same authority simply because the underlying GitHub credential can access it.
|
|
281
|
+
|
|
282
|
+
That is the core contribution we are testing:
|
|
283
|
+
|
|
284
|
+
> **Authority may follow the task's proven execution path without becoming ambient account authority.**
|
|
285
|
+
|
|
286
|
+
## Core invariant
|
|
327
287
|
|
|
328
288
|
```text
|
|
329
|
-
|
|
330
|
-
|
|
|
331
|
-
v
|
|
332
|
-
temporary task authority
|
|
333
|
-
|
|
|
334
|
-
v
|
|
335
|
-
exact agent-originated effect
|
|
336
|
-
|
|
|
337
|
-
+--> existing OAuth / IAM / MCP / SDK / CLI
|
|
289
|
+
Task Lease authority <= Mission authority
|
|
338
290
|
```
|
|
339
291
|
|
|
340
|
-
The
|
|
292
|
+
The Mission remains the ceiling. Task authority may stay the same or shrink as work crosses tools, transports and durable state. It must never silently grow.
|
|
341
293
|
|
|
342
|
-
|
|
294
|
+
## Existing stack, not a replacement stack
|
|
343
295
|
|
|
344
|
-
|
|
296
|
+
Agent Authority is not trying to replace OAuth, IAM, MCP, gateways or agent frameworks.
|
|
345
297
|
|
|
346
|
-
|
|
298
|
+
```text
|
|
299
|
+
agent reasoning
|
|
300
|
+
|
|
|
301
|
+
v
|
|
302
|
+
Agent Authority
|
|
303
|
+
|
|
|
304
|
+
v
|
|
305
|
+
existing SDK / MCP / gateway / OAuth / provider
|
|
306
|
+
```
|
|
347
307
|
|
|
348
|
-
|
|
308
|
+
Three execution modes already share the same Task Lease semantics:
|
|
349
309
|
|
|
350
|
-
|
|
310
|
+
```text
|
|
311
|
+
in-process guard
|
|
312
|
+
MCP gateway
|
|
313
|
+
brokered provider execution
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
A real Vercel AI SDK `ToolLoopAgent` integration also exercises the protected-tool boundary. See [Transport invariance](docs/transport-invariance.md).
|
|
351
317
|
|
|
352
|
-
|
|
318
|
+
## Durability
|
|
353
319
|
|
|
354
|
-
|
|
320
|
+
For local workflows that must survive process restarts, pass a `JsonFileTaskLeaseStore` to the same task-first API:
|
|
355
321
|
|
|
356
|
-
|
|
322
|
+
```js
|
|
323
|
+
import { JsonFileTaskLeaseStore } from '@nullsquare/agent-authority/storage';
|
|
324
|
+
import { createTask } from '@nullsquare/agent-authority/task';
|
|
325
|
+
|
|
326
|
+
const store = new JsonFileTaskLeaseStore({
|
|
327
|
+
dir: config.paths.task_leases,
|
|
328
|
+
keyPath: config.paths.master_key
|
|
329
|
+
});
|
|
357
330
|
|
|
358
|
-
|
|
331
|
+
const task = createTask({
|
|
332
|
+
...taskDefinition,
|
|
333
|
+
store
|
|
334
|
+
});
|
|
335
|
+
```
|
|
359
336
|
|
|
360
|
-
|
|
337
|
+
The task facade then uses the durable Task Lease session internally. Normal task calls do not change.
|
|
361
338
|
|
|
362
|
-
|
|
339
|
+
Durable state currently provides authenticated local recovery, exact Mission binding, atomic whole-state replacement, per-lease local locking, stale-writer compare-and-swap protection, durable completion/expiry, and refresh before authority evaluation.
|
|
363
340
|
|
|
364
|
-
|
|
341
|
+
See [Durable Task Leases](docs/durable-task-leases.md).
|
|
365
342
|
|
|
366
|
-
|
|
343
|
+
## What is already proven
|
|
367
344
|
|
|
368
|
-
|
|
345
|
+
- deterministic allow / deny / require-approval decisions;
|
|
346
|
+
- explicit deny precedence and Mission ceiling;
|
|
347
|
+
- execution evidence bound to exact guarded output;
|
|
348
|
+
- strict evidence-derived authority where callers do not provide the derived value;
|
|
349
|
+
- reviewed Google Gmail-sender and GitHub selected-issue extractors;
|
|
350
|
+
- shared two-provider adversarial conformance tests;
|
|
351
|
+
- live GitHub read and evidence-derived comment mutation proofs;
|
|
352
|
+
- connected Gmail -> Calendar smoke proof;
|
|
353
|
+
- direct SDK / MCP / broker transport invariance;
|
|
354
|
+
- real Vercel AI SDK protected-tool execution proof;
|
|
355
|
+
- authenticated durable Task Lease recovery;
|
|
356
|
+
- stale-writer/CAS and mission-alias protection;
|
|
357
|
+
- automatic durable Task Lease sessions;
|
|
358
|
+
- task-first public facade and deterministic utility regression gate;
|
|
359
|
+
- self-contained support/communications and operations/finance product proofs;
|
|
360
|
+
- blank-project fixture quickstart against the current npm package;
|
|
361
|
+
- blank-project real public GitHub onboarding with broader standing permission and narrower task authority;
|
|
362
|
+
- Node 20/22 CI, coverage, packed-consumer validation and CodeQL;
|
|
363
|
+
- independent npm registry consumer verification.
|
|
369
364
|
|
|
370
|
-
|
|
365
|
+
The lower-level evidence is documented under `docs/` and remains available for security review.
|
|
371
366
|
|
|
372
|
-
|
|
373
|
-
2. **Mission is the ceiling.** Task Leases cannot override explicit denies.
|
|
374
|
-
3. **No side effect before authorization.** Denied and step-up actions never execute.
|
|
375
|
-
4. **Authority lineage matters.** Provider-derived authority should bind the exact allowed receipt and guarded output to a reviewed extractor; legacy host-trusted derivation remains identifiable in provenance.
|
|
376
|
-
5. **No silent resource expansion.** A different concrete resource becomes an authority delta.
|
|
377
|
-
6. **Task authority ends with the task.** Completion and expiry are independent from provider credential lifetime.
|
|
378
|
-
7. **Authority may shrink, never silently grow.** Delegation and transport changes must preserve non-amplification.
|
|
379
|
-
8. **The evaluated request must be the executed request.** Request hashes, grants and idempotency protect the boundary.
|
|
380
|
-
9. **Credentials stay out of model context where Agent Authority owns them.**
|
|
381
|
-
10. **Security gaps are documented, not marketed away.**
|
|
367
|
+
## Product direction
|
|
382
368
|
|
|
383
|
-
|
|
369
|
+
The next product risk is **not lack of another security subsystem**. It is adoption and useful autonomy.
|
|
384
370
|
|
|
385
|
-
|
|
371
|
+
Before deeper distributed/crypto infrastructure becomes a priority, Agent Authority should prove:
|
|
386
372
|
|
|
387
|
-
|
|
373
|
+
1. a new developer can get a meaningful workflow running in under 10 minutes;
|
|
374
|
+
2. coding, support/communications and operations/finance workflows all fit the task-first model;
|
|
375
|
+
3. normal task completion stays high without approval spam;
|
|
376
|
+
4. unrelated-resource effects still execute zero provider callbacks;
|
|
377
|
+
5. at least one external developer adopts the package without project-author assistance.
|
|
388
378
|
|
|
389
|
-
|
|
390
|
-
- Transport and harness proofs cover configured Agent Authority execution boundaries, not a malicious host that exposes a separate unguarded tool, credential, shell or network path.
|
|
391
|
-
- `deriveFromEvidence()` proves consistency with the exact output returned through the trusted Agent Authority guard, but the output is not cryptographically attested by Gmail, GitHub, or another remote provider.
|
|
392
|
-
- The legacy `derive()` API remains host-trusted for compatibility; audit provenance distinguishes it from `execution-evidence-v1` derivation.
|
|
393
|
-
- Source-data changes do not yet automatically invalidate already-derived authority facts.
|
|
394
|
-
- Bindings currently target top-level request context fields.
|
|
395
|
-
- Approved authority deltas are surfaced but not automatically applied back into a live lease.
|
|
396
|
-
- GitHub token-stdin is a developer bridge, not final browser OAuth onboarding.
|
|
397
|
-
- The encrypted local vault is not an OS keychain/KMS/HSM backend.
|
|
398
|
-
- Remote authenticated deployment and a production approval UX are not complete.
|
|
379
|
+
See [Product proof gate](docs/product-proof.md) and [Roadmap](ROADMAP.md).
|
|
399
380
|
|
|
400
|
-
|
|
381
|
+
## Current limitations
|
|
401
382
|
|
|
402
|
-
|
|
383
|
+
This is still a validation implementation.
|
|
403
384
|
|
|
404
|
-
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
- a
|
|
408
|
-
-
|
|
409
|
-
-
|
|
385
|
+
- Durable persistence is a trusted-local-host reference backend, not distributed consensus or hostile-host containment.
|
|
386
|
+
- Another worker can still change durable state after an `ALLOW` decision and before asynchronous remote provider I/O begins. Remote effect + receipt + Task Lease state are not one distributed transaction.
|
|
387
|
+
- A crashed local worker may leave a per-lease lock requiring explicit recovery.
|
|
388
|
+
- Transport/harness proofs do not contain a malicious host that deliberately exposes a separate unguarded tool, shell, network path or credential.
|
|
389
|
+
- Provider outputs are evidence-bound inside the trusted Agent Authority runtime but are not provider-signed remote attestations.
|
|
390
|
+
- Source-data changes do not yet automatically invalidate already-derived authority.
|
|
391
|
+
- Approved authority deltas are surfaced but not automatically applied into a live durable task.
|
|
392
|
+
- Current Task Lease bindings are exact equality. The finance proof therefore steps up for a partial refund as well as an over-refund; a derived numeric ceiling remains an evidence-driven product question rather than a general policy language.
|
|
393
|
+
- Public GitHub onboarding is credential-free for read-only public repositories; authenticated/private-repository onboarding and production OAuth/KMS UX remain incomplete.
|
|
394
|
+
- Remote authenticated deployment and production approval UX remain incomplete.
|
|
395
|
+
|
|
396
|
+
These are real limitations. They are not reasons to build every possible infrastructure layer before product adoption is proven.
|
|
397
|
+
|
|
398
|
+
## What we are deliberately not prioritizing now
|
|
399
|
+
|
|
400
|
+
Unless a real workflow proves otherwise:
|
|
401
|
+
|
|
402
|
+
- another agent harness;
|
|
403
|
+
- a new OAuth/identity/token protocol;
|
|
404
|
+
- an MCP replacement/control plane;
|
|
405
|
+
- a connector marketplace;
|
|
406
|
+
- a proprietary universal policy DSL;
|
|
407
|
+
- distributed Task Lease databases;
|
|
408
|
+
- provider-attestation protocol design;
|
|
409
|
+
- A2A implementation;
|
|
410
|
+
- dashboard-first enterprise product work.
|
|
410
411
|
|
|
411
412
|
## Contributing
|
|
412
413
|
|
|
413
|
-
The
|
|
414
|
+
The most valuable contribution answers:
|
|
414
415
|
|
|
415
|
-
> **Can this agent complete the intended task while being technically unable to use the same
|
|
416
|
+
> **Can this agent complete the intended task while being technically unable to use the same standing account authority for an unrelated effect?**
|
|
416
417
|
|
|
417
|
-
|
|
418
|
+
Especially useful:
|
|
418
419
|
|
|
419
|
-
-
|
|
420
|
-
- trustworthy operation -> resource
|
|
421
|
-
-
|
|
420
|
+
- real task-first workflows;
|
|
421
|
+
- trustworthy operation -> resource mappings;
|
|
422
|
+
- utility-regression cases that cause unnecessary approvals;
|
|
422
423
|
- derived-authority / provenance attacks;
|
|
423
|
-
-
|
|
424
|
-
-
|
|
424
|
+
- transport or multi-worker attacks;
|
|
425
|
+
- feedback from developers trying to integrate the package for the first time.
|
|
425
426
|
|
|
426
427
|
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
427
428
|
|