@nullsquare/agent-authority 0.4.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.
Files changed (58) hide show
  1. package/CONTRIBUTING.md +93 -0
  2. package/LICENSE +201 -0
  3. package/README.md +390 -0
  4. package/ROADMAP.md +149 -0
  5. package/SECURITY.md +116 -0
  6. package/docs/account-connections.md +173 -0
  7. package/docs/announcement-draft.md +13 -0
  8. package/docs/architecture.md +106 -0
  9. package/docs/assets/agent-authority-cover.svg +41 -0
  10. package/docs/clear-path.md +53 -0
  11. package/docs/cli.md +130 -0
  12. package/docs/evidence.md +143 -0
  13. package/docs/harness-bridge-mode.md +136 -0
  14. package/docs/harness-integration.md +223 -0
  15. package/docs/integration-contract.md +132 -0
  16. package/docs/integrations/vercel-ai-sdk.md +161 -0
  17. package/docs/launch-checklist.md +29 -0
  18. package/docs/npm-release.md +19 -0
  19. package/docs/openclaw-integration.md +97 -0
  20. package/docs/package-consumer-validation.md +18 -0
  21. package/docs/release-candidate-status.md +3 -0
  22. package/docs/release-guardrails.md +8 -0
  23. package/docs/release-notes-v0.4.md +26 -0
  24. package/docs/release-scope.md +3 -0
  25. package/docs/ship-criteria.md +3 -0
  26. package/docs/task-leases.md +253 -0
  27. package/docs/validation.md +124 -0
  28. package/examples/demo.js +19 -0
  29. package/examples/direct-guard.js +50 -0
  30. package/examples/harness-managed-connectors.js +72 -0
  31. package/examples/live-github-derived-mutation.js +208 -0
  32. package/examples/live-github-task-lease.js +80 -0
  33. package/examples/mission.json +20 -0
  34. package/examples/missions/chatgpt-web-validation.json +33 -0
  35. package/examples/openclaw-tool-wrapper.js +49 -0
  36. package/examples/task-lease-demo.js +98 -0
  37. package/examples/validation-mcp-upstream.js +112 -0
  38. package/package.json +80 -0
  39. package/src/agent-auth.js +135 -0
  40. package/src/approvals.js +157 -0
  41. package/src/cli.js +335 -0
  42. package/src/connections.js +203 -0
  43. package/src/execution.js +174 -0
  44. package/src/guard.js +79 -0
  45. package/src/harness-bridge.js +131 -0
  46. package/src/idempotency.js +118 -0
  47. package/src/index.js +291 -0
  48. package/src/integrations/ai-sdk.js +59 -0
  49. package/src/keys.js +15 -0
  50. package/src/mcp-gateway.js +142 -0
  51. package/src/mcp-remote.js +102 -0
  52. package/src/mcp-server.js +102 -0
  53. package/src/providers/github.js +149 -0
  54. package/src/runtime-env.js +53 -0
  55. package/src/sdk.js +75 -0
  56. package/src/server.js +146 -0
  57. package/src/storage.js +213 -0
  58. package/src/task-lease.js +266 -0
package/docs/cli.md ADDED
@@ -0,0 +1,130 @@
1
+ # Agent Authority CLI
2
+
3
+ The CLI is the user-facing control surface for the local Agent Authority runtime.
4
+
5
+ ## Install from source
6
+
7
+ ```bash
8
+ git clone https://github.com/Null-Square/agent-authority.git
9
+ cd agent-authority
10
+ npm install
11
+ npm link
12
+ ```
13
+
14
+ This exposes both `agent-authority` and the short alias `aauth`.
15
+
16
+ ## First-time setup
17
+
18
+ ```bash
19
+ agent-authority setup
20
+ agent-authority doctor
21
+ agent-authority status
22
+ ```
23
+
24
+ By default Agent Authority stores local state under:
25
+
26
+ ```text
27
+ ~/.agent-authority/
28
+ config.json
29
+ missions/
30
+ state/
31
+ connections.json
32
+ revocations.json
33
+ usage.json
34
+ vault/
35
+ master.key
36
+ secrets.enc.json
37
+ receipts/
38
+ ```
39
+
40
+ Override the location with `AGENT_AUTHORITY_HOME` or `--home PATH`.
41
+
42
+ ## Connect GitHub
43
+
44
+ The current native GitHub onboarding path accepts credentials only over stdin so secrets do not appear in shell history:
45
+
46
+ ```bash
47
+ printf %s "$GITHUB_TOKEN" | agent-authority connect github --token-stdin
48
+ ```
49
+
50
+ The CLI verifies the credential against GitHub by default, discovers the account login and stores the credential encrypted in the local vault. Use `--no-verify` only for offline development.
51
+
52
+ Browser/device OAuth is the next onboarding milestone; manual tokens are intentionally an interim developer path rather than the final UX.
53
+
54
+ List safe connection metadata:
55
+
56
+ ```bash
57
+ agent-authority connections
58
+ ```
59
+
60
+ Disconnect and delete the locally stored credential:
61
+
62
+ ```bash
63
+ agent-authority disconnect github --account ACCOUNT_ID
64
+ ```
65
+
66
+ ## Run the authority daemon
67
+
68
+ ```bash
69
+ agent-authority serve
70
+ ```
71
+
72
+ Default bind address:
73
+
74
+ ```text
75
+ 127.0.0.1:8787
76
+ ```
77
+
78
+ Override with:
79
+
80
+ ```bash
81
+ agent-authority serve --host 127.0.0.1 --port 8787
82
+ ```
83
+
84
+ or `AGENT_AUTHORITY_HOST` / `AGENT_AUTHORITY_PORT`.
85
+
86
+ The loopback default is intentional. Do not expose the local daemon publicly without an authenticated transport layer in front of it.
87
+
88
+ ## Mission commands
89
+
90
+ Validate a mission:
91
+
92
+ ```bash
93
+ agent-authority mission validate examples/mission.json
94
+ ```
95
+
96
+ Evaluate an action locally without executing it:
97
+
98
+ ```bash
99
+ agent-authority mission evaluate examples/mission.json \
100
+ --service github \
101
+ --action repo.read \
102
+ --repository Null-Square/agent-authority
103
+ ```
104
+
105
+ The command exits non-zero for denied actions, which makes it useful in scripts and CI.
106
+
107
+ ## Operational commands
108
+
109
+ ```bash
110
+ agent-authority status
111
+ agent-authority doctor
112
+ agent-authority --version
113
+ agent-authority --help
114
+ ```
115
+
116
+ `doctor` checks the config, local encrypted vault, connection state and whether the configured daemon uses the safe loopback default.
117
+
118
+ ## Config principles
119
+
120
+ - no credentials in `config.json`
121
+ - no credentials in mission manifests
122
+ - no credential command-line flags
123
+ - provider credentials remain behind the broker
124
+ - connection metadata is safe to show to agents; secret references are not
125
+ - revocations and cumulative budget usage persist across daemon restarts
126
+ - action receipts are written under `receipts/`
127
+
128
+ ## Current security boundary
129
+
130
+ The local encrypted file vault uses AES-256-GCM and restrictive file permissions. Its master key is local to the same user account, so it protects against accidental plaintext exposure but is **not** a replacement for an OS keychain, hardware-backed key store, KMS/HSM, or remote enterprise vault. Production hardening will add pluggable key-store backends.
@@ -0,0 +1,143 @@
1
+ # Executable Evidence
2
+
3
+ Agent Authority is an experimental security runtime. Claims in this project should be backed by executable evidence, not architecture diagrams alone.
4
+
5
+ This page records the strongest properties the repository currently demonstrates.
6
+
7
+ ## Core claim under test
8
+
9
+ > An effect placed behind an Agent Authority Task Lease cannot use the host's broader provider access for a different concrete resource unless the task authority expands explicitly.
10
+
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
+
13
+ ## Live derived-authority mutation — GitHub
14
+
15
+ Public fixture: [issue #9](https://github.com/Null-Square/agent-authority/issues/9)
16
+
17
+ Validation workflow: CI job `live-derived-github-mutation`
18
+
19
+ Passing run: [CI run 136](https://github.com/Null-Square/agent-authority/actions/runs/32517381668)
20
+
21
+ The job uses a GitHub Actions token with:
22
+
23
+ ```text
24
+ contents: read
25
+ issues: write
26
+ ```
27
+
28
+ The Task Lease itself starts with only the repository as an authority root.
29
+
30
+ ### Executed path
31
+
32
+ ```text
33
+ Task root
34
+ Null-Square/agent-authority
35
+ |
36
+ v
37
+ ALLOW live issue-list request
38
+ |
39
+ v
40
+ discover issue #9 from GitHub response
41
+ |
42
+ v
43
+ derive fact: issue_number = 9
44
+ |
45
+ v
46
+ ALLOW one real comment mutation on #9
47
+ |
48
+ +--> attempt comment on #1
49
+ | -> authority_delta_required
50
+ | -> provider mutation callback does not run
51
+ |
52
+ v
53
+ complete Task Lease
54
+ |
55
+ +--> attempt comment on #9 again
56
+ -> task_lease_completed
57
+ -> provider mutation callback does not run
58
+ ```
59
+
60
+ The passing job recorded:
61
+
62
+ ```text
63
+ ALLOW -> discovered issue #9
64
+ Derived authority -> issue #9
65
+ ALLOW -> real GitHub comment mutation executed
66
+ STEP-UP -> unrelated issue #1 blocked before provider mutation
67
+ DENY -> post-completion mutation blocked for issue #9
68
+ Provider calls observed before cleanup: reads=1, task_mutations=1
69
+ ```
70
+
71
+ The temporary validation comment is deleted by test-harness cleanup after the proof. Cleanup is intentionally outside the agent authority path and counted separately.
72
+
73
+ ### What this proves
74
+
75
+ - a concrete resource can be discovered from a real provider response during authorized execution;
76
+ - that resource can become same-lease derived authority;
77
+ - a real provider mutation can be limited to the derived resource;
78
+ - asking for another resource does not silently inherit the same authority;
79
+ - a blocked resource causes zero additional task-side provider mutation calls;
80
+ - completing the Task Lease prevents reuse of the previously authorized resource;
81
+ - the provider credential can still exist after task authority disappears.
82
+
83
+ ### What this does not prove
84
+
85
+ - the host/adapter's extraction of `output.number` is cryptographically verified;
86
+ - an agent cannot bypass Agent Authority if it independently possesses the provider credential or another unguarded provider path;
87
+ - Task Lease state is durable across process failure;
88
+ - the current prototype is ready for adversarial production use.
89
+
90
+ ## Live provider read boundary — GitHub
91
+
92
+ CI also runs `demo:live-github` against the public GitHub API.
93
+
94
+ It proves that one repository permitted by the Task Lease causes one live `fetch()` while another repository produces `authority_delta_required` before a second fetch occurs.
95
+
96
+ ## Network-boundary integration test
97
+
98
+ `test/guard-network.test.js` uses an ordinary local HTTP provider with a deliberately broad bearer credential.
99
+
100
+ The server itself observes that:
101
+
102
+ - the authorized resource reaches the provider once;
103
+ - an unrelated resource produces no additional request;
104
+ - task completion produces no additional request;
105
+ - the broad provider credential remains present throughout the test.
106
+
107
+ ## Adversarial Task Lease tests
108
+
109
+ The test suite also covers:
110
+
111
+ - unresolved derived facts fail closed;
112
+ - derived authority requires an `ALLOW` receipt;
113
+ - receipts from another mission are rejected;
114
+ - receipts from another Task Lease are rejected;
115
+ - parent lineage is required;
116
+ - a trusted extraction selector must be recorded;
117
+ - explicit mission deny rules remain the ceiling;
118
+ - lease expiry and mission expiry are enforced against a consistent evaluation clock.
119
+
120
+ ## Continuous checks
121
+
122
+ Current pull requests run:
123
+
124
+ - Node.js 20 tests;
125
+ - Node.js 22 tests;
126
+ - Task Lease runnable demo;
127
+ - syntax checks;
128
+ - package checks;
129
+ - coverage;
130
+ - live GitHub read validation;
131
+ - live derived GitHub mutation validation for trusted in-repository branches;
132
+ - CodeQL.
133
+
134
+ ## Evidence standard for new claims
135
+
136
+ A new security claim should ideally include all four:
137
+
138
+ 1. a positive path that performs the intended effect;
139
+ 2. an adversarial path that attempts to exceed authority;
140
+ 3. observation at or immediately before the real provider boundary;
141
+ 4. a public CI result that can be rerun.
142
+
143
+ The project should prefer a smaller claim with strong evidence over a broader claim that depends on trust in the model or prompt.
@@ -0,0 +1,136 @@
1
+ # Harness-Managed Connector Mode
2
+
3
+ Agent Authority supports two complementary execution modes.
4
+
5
+ ## 1. Brokered execution
6
+
7
+ Agent Authority owns the provider connection and executes the provider request itself.
8
+
9
+ ```text
10
+ agent -> Agent Authority -> provider adapter -> provider
11
+ ```
12
+
13
+ The agent never sees the long-lived provider credential.
14
+
15
+ This is the preferred mode when Agent Authority can safely own or exchange the credential.
16
+
17
+ ## 2. Harness-managed connector execution
18
+
19
+ Some agent platforms already own provider authentication internally and do not expose their OAuth tokens to plugins or models. Examples include hosted agent products, IDE connectors, enterprise harnesses, and ChatGPT-style connected apps.
20
+
21
+ In that environment the boundary becomes:
22
+
23
+ ```text
24
+ model / planner
25
+ |
26
+ | proposes exact action
27
+ v
28
+ Agent Authority
29
+ |
30
+ | signed short-lived Action Grant
31
+ v
32
+ trusted harness connector middleware
33
+ |
34
+ | verifies grant + exact request hash
35
+ v
36
+ platform-managed connector
37
+ |
38
+ v
39
+ provider
40
+ ```
41
+
42
+ Agent Authority does **not** need the provider secret in this mode.
43
+
44
+ The harness must be trusted to enforce the grant. The model should not be able to bypass the connector middleware and invoke the privileged connector directly.
45
+
46
+ ## Action Grant
47
+
48
+ `issueHarnessActionGrant()` creates a short-lived signed token containing only authority metadata and a hash of the exact operation:
49
+
50
+ - principal ID
51
+ - agent ID
52
+ - mission ID
53
+ - service
54
+ - action
55
+ - exact request fingerprint
56
+ - issued-at time
57
+ - expiration time
58
+ - grant ID
59
+
60
+ The raw provider credential is never present in the grant.
61
+
62
+ Default integrations should keep grants very short-lived (for example 15-30 seconds). The implementation rejects TTL values greater than five minutes.
63
+
64
+ ## Exact-request binding
65
+
66
+ A grant for:
67
+
68
+ ```text
69
+ github.repo.read
70
+ repository = Null-Square/agent-authority
71
+ ```
72
+
73
+ must not authorize:
74
+
75
+ ```text
76
+ github.repo.read
77
+ repository = Null-Square/another-repository
78
+ ```
79
+
80
+ Changing any request field changes the request fingerprint and verification fails.
81
+
82
+ The same applies to mission, principal and agent substitution.
83
+
84
+ ## Recommended connector wrapper
85
+
86
+ A harness integration should place grant verification in trusted middleware immediately before its platform-managed connector:
87
+
88
+ ```js
89
+ import { createHarnessConnectorGate } from '@nullsquare/agent-authority/harness-bridge';
90
+
91
+ const gate = createHarnessConnectorGate({ key: trustedGrantVerificationKey });
92
+
93
+ async function githubConnector(args, authorityContext) {
94
+ gate.verify({
95
+ grant: authorityContext.grant,
96
+ mission: authorityContext.mission,
97
+ request: authorityContext.request
98
+ });
99
+
100
+ return platformGitHubConnector(args);
101
+ }
102
+ ```
103
+
104
+ Do not perform verification inside the LLM prompt, model tool description, or other model-controlled context.
105
+
106
+ ## Hosted-harness proof of concept
107
+
108
+ A hosted harness can therefore use Agent Authority even if it cannot export its internal OAuth tokens:
109
+
110
+ ```text
111
+ ChatGPT / OpenClaw / IDE / enterprise agent
112
+ |
113
+ v
114
+ Agent Authority policy
115
+ |
116
+ v
117
+ signed Action Grant
118
+ |
119
+ v
120
+ harness-owned connector
121
+ ```
122
+
123
+ This mode is intentionally provider-neutral. The same authority runtime can govern a GitHub connector, Gmail connector, Drive connector, Calendar connector, CRM connector or any future platform connector, provided the harness exposes a trustworthy interception point before execution.
124
+
125
+ ## Security requirements
126
+
127
+ A production harness bridge should also implement:
128
+
129
+ 1. one-time grant consumption or a connector-side replay ledger for mutations;
130
+ 2. idempotency for side-effecting operations;
131
+ 3. result receipts posted back to the authority audit ledger;
132
+ 4. independent harness identity binding;
133
+ 5. provider/account/resource normalization before request hashing;
134
+ 6. connector middleware that cannot be bypassed by the model.
135
+
136
+ Harness mode is not a weaker policy model; it is a different credential-ownership model.
@@ -0,0 +1,223 @@
1
+ # Agent Harness Integration
2
+
3
+ Agent Authority is designed to work with many agent runtimes without requiring the model provider to adopt a new protocol first.
4
+
5
+ ## Where Agent Authority sits
6
+
7
+ Agent Authority is **not a model provider and not an agent harness**. It is an authority/control plane between an agent's proposed sensitive action and the system that can actually perform that action.
8
+
9
+ ```text
10
+ User
11
+ |
12
+ | connect accounts once + approve missions
13
+ v
14
+ Agent Authority Wallet / Control Plane
15
+ |
16
+ +----------------------+----------------------+
17
+ | | |
18
+ Codex Claude Code OpenClaw
19
+ | | |
20
+ +----------- proposed tool/action -----------+
21
+ |
22
+ v
23
+ Agent Authority Runtime
24
+ policy / approval / audit
25
+ |
26
+ allow / deny / approve
27
+ |
28
+ v
29
+ Connection Fabric
30
+ OAuth | MCP | API | CLI | browser
31
+ |
32
+ v
33
+ External service
34
+ ```
35
+
36
+ The **default integration** should be a local sidecar or hosted control-plane API. This makes Agent Authority usable by almost any harness without requiring the harness author to redesign their runtime.
37
+
38
+ When a harness exposes a trusted pre-tool execution hook, a native plugin can provide a stronger integration by routing all sensitive tool calls through Agent Authority automatically. The authority semantics remain the same in both modes.
39
+
40
+ ### Integration modes
41
+
42
+ 1. **Universal sidecar/API — default.** Any agent or harness calls Agent Authority before sensitive actions. Lowest adoption friction.
43
+ 2. **Native harness/plugin middleware — preferred when available.** A trusted plugin intercepts tool actions before execution and sends them through Agent Authority. Harder for an agent to bypass accidentally.
44
+ 3. **MCP authority proxy.** Existing MCP clients and servers work through an authority-aware proxy without every server adopting the mission format.
45
+ 4. **CLI credential helper.** Commands receive temporary credentials only inside the authorized child process.
46
+ 5. **Hosted authority service.** Multiple machines and agents share the same user/org connection wallet, policy, approval and audit layer.
47
+
48
+ A harness should not need to become "an Agent Authority harness." It should merely know how to ask Agent Authority to authorize/execute a sensitive action.
49
+
50
+ ## Recommended boundary
51
+
52
+ ```text
53
+ LLM / planner
54
+ |
55
+ v
56
+ Agent harness
57
+ |
58
+ | proposed tool action
59
+ v
60
+ Agent Authority
61
+ |
62
+ +--> deny
63
+ +--> require human approval
64
+ |
65
+ +--> allow
66
+ |
67
+ v
68
+ credential adapter
69
+ |
70
+ v
71
+ tool/service
72
+ ```
73
+
74
+ The authority runtime should ideally execute **outside the model context** so a prompt-injected or compromised agent cannot simply rewrite its own permissions.
75
+
76
+ ## 1. Tool middleware
77
+
78
+ For a custom agent harness, wrap each sensitive tool:
79
+
80
+ ```js
81
+ const decision = authority.evaluate(mission, {
82
+ service: 'github',
83
+ action: 'repo.write',
84
+ context: { repository: 'Null-Square/example' }
85
+ });
86
+
87
+ if (decision.result.decision === 'deny') throw new Error(decision.result.reason);
88
+ if (decision.result.decision === 'require_approval') return requestHumanApproval(decision);
89
+ return authority.execute(mission, request);
90
+ ```
91
+
92
+ The preferred production form is `authority.execute(...)`: the provider credential remains inside Agent Authority rather than being returned to the agent process.
93
+
94
+ ## 2. Local sidecar for coding agents
95
+
96
+ Run `npm start` next to the coding-agent process and call:
97
+
98
+ - `GET /health`
99
+ - `GET /v1/connections`
100
+ - `POST /v1/evaluate`
101
+ - `POST /v1/prepare`
102
+ - `POST /v1/execute`
103
+ - `POST /v1/revoke`
104
+
105
+ A harness can use localhost IPC/HTTP even when it cannot embed the JavaScript library directly.
106
+
107
+ Good targets for early experiments include Codex, Claude Code, Cursor, IDE agents, CI agents, desktop agents, and autonomous terminal workflows.
108
+
109
+ ## 3. OpenClaw
110
+
111
+ OpenClaw should integrate with Agent Authority **around tools, not by replacing OpenClaw's agent harness**.
112
+
113
+ OpenClaw defines an agent harness as the low-level executor for a prepared agent turn. Its native Codex harness, for example, owns Codex-native thread execution while OpenClaw continues to own channels, visible transcript state, tool policy and approvals. Agent Authority solves a different problem: whether a tool/service action is authorized under a human-approved mission.
114
+
115
+ Recommended OpenClaw topology:
116
+
117
+ ```text
118
+ OpenClaw
119
+ |
120
+ | Codex / Claude / ACP / embedded runtime
121
+ v
122
+ proposed sensitive tool call
123
+ |
124
+ v
125
+ Agent Authority plugin or sidecar
126
+ |
127
+ +--> deny
128
+ +--> require approval
129
+ +--> execute through connected account
130
+ |
131
+ v
132
+ GitHub / Google / Cloudflare / MCP / other service
133
+ ```
134
+
135
+ Two practical OpenClaw integration paths:
136
+
137
+ ### A. Sidecar first
138
+
139
+ An OpenClaw tool/plugin calls the local Agent Authority HTTP API. This requires the least coupling and lets us ship immediately.
140
+
141
+ ### B. Trusted native plugin later
142
+
143
+ Where OpenClaw exposes a suitable pre-execution tool/policy seam, a trusted Agent Authority plugin should automatically wrap sensitive tools. The plugin should still delegate policy, connections, credentials, receipts and revocation to the external Agent Authority control plane rather than duplicating them inside OpenClaw.
144
+
145
+ OpenClaw can also run external coding harnesses through ACP. Agent Authority should remain outside those harnesses as the common service-authority layer so a Codex ACP session and a Claude Code ACP session can reuse the same connected accounts and mission semantics.
146
+
147
+ Important distinction: **model-provider login and service authorization are separate concerns.** OpenClaw/Codex/Claude may still need their own model/subscription authentication. Agent Authority's first target is the GitHub/Google/Cloudflare/SaaS/cloud credentials that agents use to perform work. Provider-model authentication can be bridged later where safe and useful.
148
+
149
+ ## 4. MCP proxy
150
+
151
+ ```text
152
+ MCP client
153
+ |
154
+ v
155
+ Agent Authority MCP proxy
156
+ | |
157
+ | +--> mission evaluation
158
+ | +--> approval callback
159
+ | +--> upstream credential brokerage
160
+ | +--> receipt
161
+ v
162
+ Upstream MCP server
163
+ ```
164
+
165
+ The proxy lets existing MCP clients gain mission-scoped controls without requiring every MCP server to understand Agent Authority.
166
+
167
+ ## 5. Connector/plugin platform
168
+
169
+ Connector providers already know how to call hundreds of SaaS APIs. Agent Authority can wrap those connectors rather than rebuilding every integration.
170
+
171
+ ```text
172
+ agent -> authority -> connector adapter -> SaaS
173
+ ```
174
+
175
+ This is especially important for OAuth and API-key services: the connector holds or exchanges credentials while the authority layer decides whether the specific mission can invoke the action.
176
+
177
+ ## 6. CLI credential helper
178
+
179
+ A future helper should support flows conceptually like:
180
+
181
+ ```bash
182
+ agent-authority exec \
183
+ --mission mission.json \
184
+ --service github \
185
+ --action repo.write \
186
+ -- git push
187
+ ```
188
+
189
+ The helper should expose an ephemeral token/environment only to the child process, not to the LLM prompt or durable agent memory.
190
+
191
+ ## 7. Browser-only legacy applications
192
+
193
+ For services with no API or usable OAuth integration, the adapter may need an isolated browser/session broker. The preferred model is:
194
+
195
+ ```text
196
+ agent -> high-level browser action -> authority -> isolated authenticated browser
197
+ ```
198
+
199
+ The agent should not receive raw passwords, long-lived cookies, or unrestricted browser access. This area is high risk and should remain experimental until isolation and anti-exfiltration boundaries are well tested.
200
+
201
+ ## Human approval UX
202
+
203
+ Approval must be portable across harnesses. A decision should include enough data for terminal, IDE, mobile, or web approval surfaces to explain:
204
+
205
+ - mission objective
206
+ - agent identity
207
+ - requested service/action
208
+ - resource being affected
209
+ - financial or destructive impact
210
+ - expiration/delegation context
211
+
212
+ The human approves the **action under the mission**, not a generic permanent permission.
213
+
214
+ ## Integration acceptance test
215
+
216
+ A harness integration is successful when the same mission can:
217
+
218
+ 1. allow a safe action,
219
+ 2. deny a forbidden action,
220
+ 3. pause for approval,
221
+ 4. revoke the mission and stop future actions,
222
+ 5. use a credential mechanism without exposing a permanent root secret to the model,
223
+ 6. move between at least two harnesses without reconnecting the user's provider account.