@nullsquare/agent-authority 0.4.0 → 0.4.2
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 +15 -3
- package/ROADMAP.md +19 -11
- package/docs/announcement-draft.md +7 -1
- package/docs/assets/agent-authority-cover-editorial-v2.png +0 -0
- package/docs/evidence.md +154 -2
- package/docs/live-google-validation.md +100 -0
- package/docs/npm-release.md +13 -1
- package/docs/task-leases.md +95 -28
- package/examples/live-google-cross-provider.js +261 -0
- package/package.json +6 -3
- package/src/authority-evidence.js +146 -0
- package/src/guard.js +8 -1
- package/src/providers/google.js +238 -0
- package/src/task-lease.js +77 -0
- package/docs/assets/agent-authority-cover.svg +0 -41
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
# Agent Authority
|
|
6
6
|
|
|
@@ -8,12 +8,20 @@
|
|
|
8
8
|
|
|
9
9
|
**Agent Authority turns a human-approved task into temporary execution authority, then keeps that authority bounded as the agent discovers resources, crosses tools, and performs side effects.**
|
|
10
10
|
|
|
11
|
-
[Task Leases](docs/task-leases.md) · [Validate](docs/validation.md) · [Integration contract](docs/integration-contract.md) · [CLI](docs/cli.md) · [Architecture](docs/architecture.md) · [Roadmap](ROADMAP.md) · [Contributing](CONTRIBUTING.md)
|
|
11
|
+
[Task Leases](docs/task-leases.md) · [Validate](docs/validation.md) · [Google proof](docs/live-google-validation.md) · [Integration contract](docs/integration-contract.md) · [CLI](docs/cli.md) · [Architecture](docs/architecture.md) · [Roadmap](ROADMAP.md) · [Contributing](CONTRIBUTING.md)
|
|
12
12
|
|
|
13
|
-
> **Status: public pre-alpha / v0.4
|
|
13
|
+
> **Status: public pre-alpha / v0.4.1 Developer Preview.** Published on npm as `@nullsquare/agent-authority`. The repository has a working policy runtime, protocol-neutral guard, Task Lease prototype with provenance-bound derived facts, approvals, revocation, idempotency, credential isolation, MCP v2 gateway, GitHub and Google provider integrations, CI and CodeQL. It is not production-ready yet.
|
|
14
14
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
Requires Node.js 20+.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @nullsquare/agent-authority
|
|
23
|
+
```
|
|
24
|
+
|
|
17
25
|
## The problem
|
|
18
26
|
|
|
19
27
|
AI agents increasingly receive broad provider permissions so they can complete narrow human tasks.
|
|
@@ -144,6 +152,8 @@ The demo performs this flow without provider credentials:
|
|
|
144
152
|
|
|
145
153
|
The side-effect callbacks for blocked actions never run.
|
|
146
154
|
|
|
155
|
+
The repository also includes a real Gmail → Calendar validation path and a reusable Google provider adapter. See [Live Gmail → Calendar validation](docs/live-google-validation.md).
|
|
156
|
+
|
|
147
157
|
## Minimal developer API
|
|
148
158
|
|
|
149
159
|
```js
|
|
@@ -261,6 +271,7 @@ The long-term validation target is the **same Task Lease and authority lineage a
|
|
|
261
271
|
- AES-256-GCM local encrypted secret store
|
|
262
272
|
- safe reconnect cleanup
|
|
263
273
|
- GitHub brokered execution without returning the token to the agent
|
|
274
|
+
- Google REST provider mappings for Gmail thread reads and Calendar event mutations
|
|
264
275
|
- short-lived signed local agent-instance tokens
|
|
265
276
|
- local CLI/daemon
|
|
266
277
|
|
|
@@ -270,6 +281,7 @@ The long-term validation target is the **same Task Lease and authority lineage a
|
|
|
270
281
|
- Node 20 and Node 22 CI
|
|
271
282
|
- coverage run
|
|
272
283
|
- package checks
|
|
284
|
+
- clean-consumer npm registry verification
|
|
273
285
|
- CodeQL
|
|
274
286
|
|
|
275
287
|
## What is different from OAuth, IAM and MCP authorization?
|
package/ROADMAP.md
CHANGED
|
@@ -55,10 +55,15 @@ never silently grow
|
|
|
55
55
|
- [x] independent task-lease expiry
|
|
56
56
|
- [x] task-lease ID/hash in receipts
|
|
57
57
|
- [x] self-contained cross-system demo: Gmail-thread fact -> Calendar attendee
|
|
58
|
-
- [
|
|
58
|
+
- [x] reusable Google REST adapter for Gmail thread reads and Calendar event mutations
|
|
59
|
+
- [x] adversarial Gmail -> Calendar test proving unrelated and post-completion effects never invoke provider callbacks
|
|
60
|
+
- [x] real connected-account smoke: Gmail self-test fixture -> exact attendee -> temporary Calendar event -> cleanup
|
|
61
|
+
- [ ] rerun the same proof as a public GitHub Actions job after repository Google OAuth secrets are configured
|
|
59
62
|
|
|
60
63
|
**Success criterion:** a real multi-step agent workflow discovers a resource during an authorized read and can use exactly that resource in a later side effect, while an unrelated resource is technically blocked without requiring approval for every normal task step.
|
|
61
64
|
|
|
65
|
+
The core cross-provider behavior is now implemented and exercised against connected Gmail and Calendar accounts. Public Actions reproducibility remains the final M1 evidence gate because GitHub cannot reuse an interactive ChatGPT connector credential; the manual workflow is committed and expects a refresh token stored only as repository secrets.
|
|
66
|
+
|
|
62
67
|
## M2 — Durable task execution
|
|
63
68
|
|
|
64
69
|
Build only what the real M1 workflow proves necessary.
|
|
@@ -72,19 +77,22 @@ Build only what the real M1 workflow proves necessary.
|
|
|
72
77
|
|
|
73
78
|
**Success criterion:** a Task Lease survives daemon/process restarts without gaining authority or losing its provenance lineage.
|
|
74
79
|
|
|
75
|
-
## M3 — Trustworthy derived facts
|
|
80
|
+
## M3 — Trustworthy derived facts — first slice in progress
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
The first real Gmail -> Calendar integration showed that recording a host-supplied value plus selector was too weak for the strongest derived-authority claim. The compatibility `derive()` path remains host-trusted; new provider work should prefer execution-bound evidence and reviewed adapter extractors.
|
|
78
83
|
|
|
79
|
-
- [
|
|
80
|
-
- [
|
|
81
|
-
- [
|
|
82
|
-
- [
|
|
83
|
-
- [
|
|
84
|
+
- [x] define a small trusted-adapter extractor contract for authority-relevant normalized provider fields
|
|
85
|
+
- [x] bind successful guarded outputs to the exact ALLOW receipt, request and output hash
|
|
86
|
+
- [x] add `TaskLease.deriveFromEvidence()` so the caller cannot provide the authority value
|
|
87
|
+
- [x] migrate Gmail sender -> Calendar attendee derivation to the evidence-verified path
|
|
88
|
+
- [x] adversarial tests for value substitution, output/evidence tampering, receipt replay, cross-lease reuse, wrong-operation extraction and dangerous selectors
|
|
89
|
+
- [ ] define provider/result attestation stronger than a trusted host output hash where practical
|
|
90
|
+
- [ ] conformance fixtures for reviewed operation -> authority-field mappings across multiple providers
|
|
91
|
+
- [ ] define freshness/invalidation rules when a source resource changes
|
|
84
92
|
|
|
85
93
|
Do **not** build a general semantic policy language unless real integrations require it.
|
|
86
94
|
|
|
87
|
-
**Success criterion:**
|
|
95
|
+
**Success criterion:** provider-derived authority cannot be established through the strict path unless the exact guarded output, ALLOW receipt and reviewed extractor contract agree on the selected value. Stronger provider attestation and source invalidation remain separate follow-on problems.
|
|
88
96
|
|
|
89
97
|
## M4 — Same task, multiple transports
|
|
90
98
|
|
|
@@ -117,7 +125,7 @@ Only after the task-bound enforcement model is validated.
|
|
|
117
125
|
- [ ] framework integration examples
|
|
118
126
|
- [ ] `good first issue` tasks based on real mappings/tests
|
|
119
127
|
- [ ] independent contributor implementation of one adapter
|
|
120
|
-
- [
|
|
128
|
+
- [x] release packaging and npm publication
|
|
121
129
|
- [ ] documentation site only when README/docs become too large
|
|
122
130
|
|
|
123
131
|
## M7 — Standards interoperability
|
|
@@ -142,7 +150,7 @@ Only after operational evidence.
|
|
|
142
150
|
|
|
143
151
|
## Research questions
|
|
144
152
|
|
|
145
|
-
1. What
|
|
153
|
+
1. What provider-side or transport-side evidence can strengthen output integrity without turning Agent Authority into an attestation protocol?
|
|
146
154
|
2. How should an approved authority delta update a running task without opening a broader wildcard permission?
|
|
147
155
|
3. How should source-data changes invalidate downstream derived authority?
|
|
148
156
|
4. What provider/tool metadata is required to map operations to resource context reliably?
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Announcement draft —
|
|
1
|
+
# Announcement draft — v0.4.0 Developer Preview
|
|
2
2
|
|
|
3
3
|
NullSquare is open-sourcing **Agent Authority**, an experimental runtime for task-bounded AI agent side effects.
|
|
4
4
|
|
|
@@ -8,6 +8,12 @@ A Task Lease can follow resources discovered through authorized execution withou
|
|
|
8
8
|
|
|
9
9
|
The developer preview also includes a Vercel AI SDK integration that wraps ordinary `ToolLoopAgent` tools at their existing `execute` boundary.
|
|
10
10
|
|
|
11
|
+
Install the published developer preview with:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @nullsquare/agent-authority@0.4.0
|
|
15
|
+
```
|
|
16
|
+
|
|
11
17
|
**Give your agent a task, not your account.**
|
|
12
18
|
|
|
13
19
|
This is a developer preview, not a claim that NullSquare invented task-scoped authorization and not a production-ready security control. The repository documents the current trust assumptions and bypass boundaries explicitly.
|
|
Binary file
|
package/docs/evidence.md
CHANGED
|
@@ -10,6 +10,154 @@ This page records the strongest properties the repository currently demonstrates
|
|
|
10
10
|
|
|
11
11
|
The guarantee applies to effects that actually pass through the Agent Authority enforcement boundary. A separate unguarded provider path is outside this guarantee.
|
|
12
12
|
|
|
13
|
+
## Execution-bound derived authority
|
|
14
|
+
|
|
15
|
+
The strict derived-authority path now binds provider-derived authority to the exact output returned by an authorized `guard.run()` effect.
|
|
16
|
+
|
|
17
|
+
A successful guarded effect returns three relevant records:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
ALLOW receipt
|
|
21
|
+
+
|
|
22
|
+
exact effect output
|
|
23
|
+
|
|
|
24
|
+
v
|
|
25
|
+
execution evidence
|
|
26
|
+
(receipt + request + output hash)
|
|
27
|
+
|
|
|
28
|
+
v
|
|
29
|
+
reviewed adapter extractor
|
|
30
|
+
(selector only, no value)
|
|
31
|
+
|
|
|
32
|
+
v
|
|
33
|
+
TaskLease.deriveFromEvidence()
|
|
34
|
+
|
|
|
35
|
+
v
|
|
36
|
+
derived authority fact
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`deriveFromEvidence()` does not accept the derived authority value. The trusted adapter extractor chooses a reviewed selector, and Task Lease resolves that selector itself only after verifying the execution evidence.
|
|
40
|
+
|
|
41
|
+
`test/authority-evidence.test.js` attacks this boundary directly and proves that:
|
|
42
|
+
|
|
43
|
+
- caller-supplied value substitution does not control the resulting fact;
|
|
44
|
+
- modified provider output is rejected with `evidence_output_mismatch`;
|
|
45
|
+
- modified execution-evidence contents are rejected;
|
|
46
|
+
- evidence cannot be replayed under a second ALLOW receipt;
|
|
47
|
+
- a receipt/evidence chain from another Task Lease is rejected;
|
|
48
|
+
- the Gmail sender extractor rejects the wrong provider operation;
|
|
49
|
+
- dangerous selector paths such as `__proto__` fail closed.
|
|
50
|
+
|
|
51
|
+
The legacy `TaskLease.derive()` API remains for compatibility and records `derivation_mode: host-trusted`. New provider-derived authority should prefer `deriveFromEvidence()`, which records `derivation_mode: execution-evidence-v1`, extractor ID, source output hash, and execution-evidence hash.
|
|
52
|
+
|
|
53
|
+
### Boundary of this claim
|
|
54
|
+
|
|
55
|
+
Execution evidence is an integrity mechanism inside the trusted host/runtime boundary. It proves that the value selected for strict derivation came from the exact output object bound to that Agent Authority receipt.
|
|
56
|
+
|
|
57
|
+
It does **not** prove that Gmail, GitHub, or another provider cryptographically signed that output, and it does not protect a malicious host that bypasses or replaces the Agent Authority enforcement path. Stronger provider/transport attestation remains open M3 work.
|
|
58
|
+
|
|
59
|
+
## Cross-provider derived authority — Gmail → Calendar
|
|
60
|
+
|
|
61
|
+
Agent Authority includes a real Google provider mapping, an adversarial cross-provider test, a live validation script, and an opt-in GitHub Actions workflow.
|
|
62
|
+
|
|
63
|
+
The task shape is:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
Task root
|
|
67
|
+
one Gmail thread
|
|
68
|
+
|
|
|
69
|
+
v
|
|
70
|
+
ALLOW Gmail thread.read
|
|
71
|
+
|
|
|
72
|
+
+--> output-bound execution evidence
|
|
73
|
+
|
|
|
74
|
+
v
|
|
75
|
+
trusted Gmail sender extractor
|
|
76
|
+
|
|
|
77
|
+
v
|
|
78
|
+
derive fact: sender_email
|
|
79
|
+
|
|
|
80
|
+
v
|
|
81
|
+
ALLOW Calendar event.create
|
|
82
|
+
attendee == derived sender
|
|
83
|
+
|
|
|
84
|
+
+--> different attendee
|
|
85
|
+
| -> authority_delta_required
|
|
86
|
+
| -> Calendar mutation callback does not run
|
|
87
|
+
|
|
|
88
|
+
v
|
|
89
|
+
complete Task Lease
|
|
90
|
+
|
|
|
91
|
+
+--> same attendee again
|
|
92
|
+
-> task_lease_completed
|
|
93
|
+
-> Calendar mutation callback does not run
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Connected-account smoke — 2026-08-22
|
|
97
|
+
|
|
98
|
+
A controlled self-test was exercised against the connected NullSquare Gmail and Google Calendar accounts:
|
|
99
|
+
|
|
100
|
+
1. a temporary validation message was sent from the validation account to itself;
|
|
101
|
+
2. Gmail returned the self-test message with sender `null@nullsquare.net`;
|
|
102
|
+
3. one private, transparent Calendar event was created with exactly `null@nullsquare.net` as attendee;
|
|
103
|
+
4. the temporary Calendar event was deleted immediately after the proof;
|
|
104
|
+
5. the validation email was moved to Trash after cleanup.
|
|
105
|
+
|
|
106
|
+
No unrelated external person was invited. The smoke test establishes that the concrete Gmail and Calendar operations used by the validation are available and compatible with the intended data shape.
|
|
107
|
+
|
|
108
|
+
The live connected-account smoke is not presented as a public CI proof of the repository script. The Task Lease zero-call and execution-evidence assertions are separately executable in `test/google-cross-provider.test.js` and `test/authority-evidence.test.js`, and `.github/workflows/live-google-validation.yml` is provided for a rerunnable provider-backed proof once repository Google OAuth secrets are configured.
|
|
109
|
+
|
|
110
|
+
### Executable local/CI assertions
|
|
111
|
+
|
|
112
|
+
`test/google-cross-provider.test.js` proves deterministically that:
|
|
113
|
+
|
|
114
|
+
- the approved Gmail thread callback runs exactly once;
|
|
115
|
+
- its sender becomes a same-lease `execution-evidence-v1` authority fact;
|
|
116
|
+
- one Calendar mutation for that sender runs exactly once;
|
|
117
|
+
- a different attendee produces `authority_delta_required` and the Calendar callback is not invoked;
|
|
118
|
+
- after lease completion, the previously valid attendee produces `task_lease_completed` and the Calendar callback is not invoked again.
|
|
119
|
+
|
|
120
|
+
`test/google-provider.test.js` validates the Google REST mappings, metadata-only Gmail sender extraction, Calendar attendee body, default `sendUpdates=none`, credential redaction, unsupported-action failure, and mutation classification.
|
|
121
|
+
|
|
122
|
+
`test/google-authority-extractor.test.js` separately verifies that the reviewed Gmail extractor only accepts canonical `gmail:thread.read` sender output and that the Google adapter advertises it only for the supported authority mapping.
|
|
123
|
+
|
|
124
|
+
### Public workflow
|
|
125
|
+
|
|
126
|
+
The manual workflow `Live Google cross-provider validation` mints a short-lived access token from repository secrets and runs `npm run demo:live-google`.
|
|
127
|
+
|
|
128
|
+
It expects:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
AA_GOOGLE_OAUTH_CLIENT_ID
|
|
132
|
+
AA_GOOGLE_OAUTH_CLIENT_SECRET
|
|
133
|
+
AA_GOOGLE_OAUTH_REFRESH_TOKEN
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The refresh token should be restricted to the practical Gmail read-only and Calendar event scopes documented in `docs/live-google-validation.md`.
|
|
137
|
+
|
|
138
|
+
The connected GitHub tool does not expose repository Actions-secret management, so those secrets are intentionally not installed automatically from this development session.
|
|
139
|
+
|
|
140
|
+
### What this proves
|
|
141
|
+
|
|
142
|
+
Taken together, the deterministic Task Lease tests plus the controlled provider smoke show that:
|
|
143
|
+
|
|
144
|
+
- the Gmail → Calendar derived-authority shape is implemented, not just diagrammed;
|
|
145
|
+
- strict derivation binds the sender to the exact guarded Gmail output before it becomes authority;
|
|
146
|
+
- the exact attendee binding is enforced before the Calendar mutation callback;
|
|
147
|
+
- provider operations exist and work against real Gmail and Calendar accounts;
|
|
148
|
+
- cleanup can keep the live proof reversible and self-contained.
|
|
149
|
+
|
|
150
|
+
### What this does not prove yet
|
|
151
|
+
|
|
152
|
+
- a public GitHub Actions run has executed the full repository live script;
|
|
153
|
+
- `sender_email` is cryptographically attested by Gmail rather than integrity-bound to the trusted host's guarded output;
|
|
154
|
+
- the agent cannot bypass Agent Authority if it independently holds a Google credential;
|
|
155
|
+
- Task Lease state is durable across process failure;
|
|
156
|
+
- source-data changes automatically invalidate downstream facts;
|
|
157
|
+
- the refresh-token setup is production credential onboarding.
|
|
158
|
+
|
|
159
|
+
See [Live Gmail → Calendar validation](live-google-validation.md).
|
|
160
|
+
|
|
13
161
|
## Live derived-authority mutation — GitHub
|
|
14
162
|
|
|
15
163
|
Public fixture: [issue #9](https://github.com/Null-Square/agent-authority/issues/9)
|
|
@@ -82,7 +230,7 @@ The temporary validation comment is deleted by test-harness cleanup after the pr
|
|
|
82
230
|
|
|
83
231
|
### What this does not prove
|
|
84
232
|
|
|
85
|
-
- the
|
|
233
|
+
- the current GitHub example has migrated to a reviewed evidence extractor contract;
|
|
86
234
|
- an agent cannot bypass Agent Authority if it independently possesses the provider credential or another unguarded provider path;
|
|
87
235
|
- Task Lease state is durable across process failure;
|
|
88
236
|
- the current prototype is ready for adversarial production use.
|
|
@@ -113,7 +261,8 @@ The test suite also covers:
|
|
|
113
261
|
- receipts from another mission are rejected;
|
|
114
262
|
- receipts from another Task Lease are rejected;
|
|
115
263
|
- parent lineage is required;
|
|
116
|
-
-
|
|
264
|
+
- legacy host-trusted derivation records its extraction selector;
|
|
265
|
+
- strict execution-evidence derivation rejects substitution/replay/tampering cases;
|
|
117
266
|
- explicit mission deny rules remain the ceiling;
|
|
118
267
|
- lease expiry and mission expiry are enforced against a consistent evaluation clock.
|
|
119
268
|
|
|
@@ -129,8 +278,11 @@ Current pull requests run:
|
|
|
129
278
|
- coverage;
|
|
130
279
|
- live GitHub read validation;
|
|
131
280
|
- live derived GitHub mutation validation for trusted in-repository branches;
|
|
281
|
+
- Google provider, extractor, cross-provider and execution-evidence adversarial tests;
|
|
132
282
|
- CodeQL.
|
|
133
283
|
|
|
284
|
+
The live Google provider mutation workflow is manual because it requires repository-owned Google OAuth secrets. It should be added to the public evidence list after its first successful run.
|
|
285
|
+
|
|
134
286
|
## Evidence standard for new claims
|
|
135
287
|
|
|
136
288
|
A new security claim should ideally include all four:
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Live Gmail → Calendar validation
|
|
2
|
+
|
|
3
|
+
This validation turns the README's Gmail → Calendar Task Lease example into a real cross-provider proof.
|
|
4
|
+
|
|
5
|
+
The narrow claim is:
|
|
6
|
+
|
|
7
|
+
> A sender discovered from one authorized Gmail thread can become exact Task Lease authority for one Calendar event attendee, while a different attendee and any post-completion retry are blocked before the Calendar mutation callback runs.
|
|
8
|
+
|
|
9
|
+
It is intentionally not a general Google OAuth product or a production onboarding flow.
|
|
10
|
+
|
|
11
|
+
## Safe fixture
|
|
12
|
+
|
|
13
|
+
Use a one-message thread sent from the validation account to itself. This keeps the proof real without inviting an unrelated person.
|
|
14
|
+
|
|
15
|
+
The live script:
|
|
16
|
+
|
|
17
|
+
1. reads the approved Gmail thread through `users.threads.get` using metadata format and only the `From` header;
|
|
18
|
+
2. derives `fact:sender-email` from the same-lease `ALLOW` receipt;
|
|
19
|
+
3. creates one private, transparent Calendar event whose attendee is exactly that derived sender;
|
|
20
|
+
4. attempts a different attendee and requires `authority_delta_required` before the provider callback;
|
|
21
|
+
5. completes the Task Lease and proves the previously authorized attendee can no longer be used;
|
|
22
|
+
6. deletes the temporary event as harness cleanup outside the agent-authority proof.
|
|
23
|
+
|
|
24
|
+
The event uses `sendUpdates=none` and is deleted after validation. The cleanup call is counted separately from task-side provider mutations.
|
|
25
|
+
|
|
26
|
+
## Required Google OAuth scopes
|
|
27
|
+
|
|
28
|
+
The validation credential needs only the Google permissions required for the two provider operations:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
https://www.googleapis.com/auth/gmail.readonly
|
|
32
|
+
https://www.googleapis.com/auth/calendar.events
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Do not put an access token in the repository or workflow inputs.
|
|
36
|
+
|
|
37
|
+
## GitHub Actions secrets
|
|
38
|
+
|
|
39
|
+
The manual workflow `.github/workflows/live-google-validation.yml` mints a short-lived access token at runtime from these repository secrets:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
AA_GOOGLE_OAUTH_CLIENT_ID
|
|
43
|
+
AA_GOOGLE_OAUTH_CLIENT_SECRET
|
|
44
|
+
AA_GOOGLE_OAUTH_REFRESH_TOKEN
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The refresh token should have been granted the Gmail read-only and Calendar event scopes above. The access token is masked and exists only for the workflow run.
|
|
48
|
+
|
|
49
|
+
## Run from GitHub Actions
|
|
50
|
+
|
|
51
|
+
Open **Actions → Live Google cross-provider validation → Run workflow** and provide:
|
|
52
|
+
|
|
53
|
+
- `gmail_thread_id`: the approved self-test Gmail thread ID;
|
|
54
|
+
- `calendar_id`: normally `primary`;
|
|
55
|
+
- `expected_sender`: optional, but recommended for a deterministic fixture.
|
|
56
|
+
|
|
57
|
+
A successful run should record the following shape:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
ALLOW -> Gmail returned sender <fixture account>
|
|
61
|
+
Derived authority -> Calendar attendee <fixture account>
|
|
62
|
+
ALLOW -> real Calendar event mutation executed
|
|
63
|
+
STEP-UP -> unrelated attendee blocked before Calendar provider mutation
|
|
64
|
+
DENY -> post-completion Calendar mutation blocked
|
|
65
|
+
Provider calls observed before cleanup: gmail_reads=1, calendar_task_mutations=1
|
|
66
|
+
Cleanup -> deleted temporary Calendar event
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Run locally with a short-lived token
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export GOOGLE_ACCESS_TOKEN='...'
|
|
73
|
+
export AA_GOOGLE_GMAIL_THREAD_ID='...'
|
|
74
|
+
export AA_GOOGLE_CALENDAR_ID='primary'
|
|
75
|
+
export AA_GOOGLE_EXPECTED_SENDER='validation@example.com'
|
|
76
|
+
npm run demo:live-google
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Prefer the refresh-token GitHub Actions workflow for repeatable validation. Do not persist the short-lived access token in shell history, source files, screenshots, or issue comments.
|
|
80
|
+
|
|
81
|
+
## What this proves
|
|
82
|
+
|
|
83
|
+
When the real provider calls are placed inside the Task Lease guard callbacks, the validation demonstrates:
|
|
84
|
+
|
|
85
|
+
- cross-provider derived authority from Gmail to Calendar;
|
|
86
|
+
- one exact derived attendee can be used for the real Calendar effect;
|
|
87
|
+
- a different attendee does not silently inherit authority;
|
|
88
|
+
- blocked attempts create zero additional task-side Calendar provider mutations;
|
|
89
|
+
- task completion removes the previously valid derived authority;
|
|
90
|
+
- the Google credential can remain broader than the Task Lease.
|
|
91
|
+
|
|
92
|
+
## What this does not prove
|
|
93
|
+
|
|
94
|
+
- the current host-side extraction of `sender_email` is cryptographically attested by Gmail;
|
|
95
|
+
- Task Lease state survives process failure;
|
|
96
|
+
- an agent holding an independent Google credential cannot bypass the guard;
|
|
97
|
+
- the validation refresh-token setup is a production credential-onboarding design;
|
|
98
|
+
- `sendUpdates=none` is a general invitation-delivery strategy for user-facing calendar workflows.
|
|
99
|
+
|
|
100
|
+
The purpose of this proof is to close the real cross-provider M1 validation gap and expose the next implementation problem with evidence rather than speculation.
|
package/docs/npm-release.md
CHANGED
|
@@ -13,7 +13,19 @@ Before any publication:
|
|
|
13
13
|
After publication, verify from a fresh project with:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npm install @nullsquare/agent-authority@0.4.
|
|
16
|
+
npm install @nullsquare/agent-authority@0.4.1
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Then run the same consumer smoke flow through the registry-installed package. Registry verification is part of the release gate; a successful `npm publish` command alone is not sufficient.
|
|
20
|
+
|
|
21
|
+
The repository also includes `.github/workflows/verify-npm-registry.yml`, which verifies registry visibility and a clean consumer install. For v0.4.1 it additionally verifies the public `@nullsquare/agent-authority/providers/google` export.
|
|
22
|
+
|
|
23
|
+
## npm vs GitHub release surfaces
|
|
24
|
+
|
|
25
|
+
Publishing to the public npm registry does not automatically create either a GitHub Release or a GitHub Packages entry.
|
|
26
|
+
|
|
27
|
+
- **npm registry** — `npm publish --access public` publishes `@nullsquare/agent-authority` to `registry.npmjs.org` / npmjs.com. This is the package users install with `npm install`.
|
|
28
|
+
- **GitHub Releases** — a separate GitHub object, normally backed by a Git tag such as `v0.4.1`. A release must be created explicitly or by release automation.
|
|
29
|
+
- **GitHub Packages** — a separate package registry. It only appears when the package is published to GitHub's npm registry (`npm.pkg.github.com`); publishing to npmjs.com does not populate it.
|
|
30
|
+
|
|
31
|
+
Agent Authority currently uses npmjs.com as its public package registry. Therefore an empty GitHub **Packages** section is expected unless the project intentionally adopts dual publication. A GitHub **Release** is still useful for source-release discoverability and should track published versions, but it is independent from npm publication.
|