@agentproto/auth 0.2.0 → 1.0.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/README.md +2 -1
- package/dist/index.d.ts +370 -31
- package/dist/index.mjs +277 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/skill/auth/SKILL.md +0 -131
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentproto/auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "@agentproto/auth — AIP-50 AUTH.md reference implementation. Auth-provider doctype: how CLI tools and agents authenticate to API servers via a standardized discovery chain and pluggable flow engines, aligned to the WorkOS auth.md open standard.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentproto",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"gray-matter": "^4.0.3",
|
|
46
|
-
"zod": "^4.4
|
|
46
|
+
"zod": "^4.5.4",
|
|
47
47
|
"@agentproto/define-doctype": "0.1.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
package/skill/auth/SKILL.md
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: auth
|
|
3
|
-
description:
|
|
4
|
-
Authenticate an agentproto agent or MCP connector to a service via
|
|
5
|
-
@agentproto/auth's credential broker — declare an auth provider
|
|
6
|
-
(pat / service-auth / device-code), store the credential ONCE in a
|
|
7
|
-
CredentialStore, and resolve fresh Authorization headers at call/connect
|
|
8
|
-
time. Use to wire a Bearer/OAuth API (agentpush, a hosted MCP server, an
|
|
9
|
-
internal service) into an agent WITHOUT putting secrets in env vars or
|
|
10
|
-
.mcp.json.
|
|
11
|
-
metadata:
|
|
12
|
-
tags: agentproto, auth, aip-50, credentials, broker, mcp, secrets, bearer, oauth
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## When to use
|
|
16
|
-
|
|
17
|
-
Reach for this whenever an agent (or a child MCP it mounts) must present a
|
|
18
|
-
credential to a remote service and you don't want that secret sprayed into the
|
|
19
|
-
daemon's global env or hardcoded in a config file. The hallmark: "how do I give
|
|
20
|
-
this agent access to `<service>` without leaking the key to every other agent?"
|
|
21
|
-
|
|
22
|
-
- A tool/agent calls a Bearer API (agentpush, Stripe, an internal API).
|
|
23
|
-
- A hosted/remote MCP server needs an `Authorization` header.
|
|
24
|
-
- You want ONE place to store a key, scoped per service, resolved fresh (with
|
|
25
|
-
refresh) at use-time instead of a long-lived env var.
|
|
26
|
-
|
|
27
|
-
Do NOT use for the daemon's own tunnel login (that's `agentproto auth login`, a
|
|
28
|
-
device-code flow already wired) — though it uses the same substrate underneath.
|
|
29
|
-
|
|
30
|
-
## The model — one source of truth, resolved on demand
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
auth provider (declares WHERE/HOW) ──┐
|
|
34
|
-
CredentialStore (holds the secret) ──┤─▶ CredentialBroker.resolveHeaders({ path, audience })
|
|
35
|
-
│ → { Authorization: "Bearer …" } (fresh, per call)
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
- **Provider** — a manifest declaring a service's `id`, `apiBase`, and `auth`
|
|
39
|
-
flow. Config only, never the secret. Registered once (`registerAuthProvider`).
|
|
40
|
-
- **CredentialStore** — where the secret lives: `KeychainStore` (macOS CLI),
|
|
41
|
-
`FileStore` (AES-256-GCM, headless — key from `AGENTPROTO_STORE_KEY`),
|
|
42
|
-
`MemoryStore` (tests). Swap the backend, same interface.
|
|
43
|
-
- **Broker** — `resolveHeaders({ path, audience?, signal? })` turns a provider
|
|
44
|
-
`path` into ready-to-use headers: serves a fresh stored bearer, else runs the
|
|
45
|
-
flow. `audience` (`api` / `mcp` / `tunnel`) scopes the credential so it can't
|
|
46
|
-
be reused cross-plane.
|
|
47
|
-
- **Flows** — pick one per service: `pat` (static token you store/paste),
|
|
48
|
-
`service-auth` (auth.md claim ceremony → short oat + durable assertion),
|
|
49
|
-
`device-code` (RFC 8628 → durable daemon token + refresh).
|
|
50
|
-
|
|
51
|
-
## Recipe
|
|
52
|
-
|
|
53
|
-
### 1. Declare + register the provider
|
|
54
|
-
|
|
55
|
-
TS literal (builtin/tests):
|
|
56
|
-
```ts
|
|
57
|
-
import { defineAuthProvider, registerAuthProvider } from "@agentproto/auth"
|
|
58
|
-
|
|
59
|
-
registerAuthProvider(defineAuthProvider({
|
|
60
|
-
id: "agentpush",
|
|
61
|
-
description: "AgentPush API — paste a personal API key.",
|
|
62
|
-
apiBase: "https://api.agentpush.example",
|
|
63
|
-
audience: "mcp", // or "api"
|
|
64
|
-
auth: { flow: "pat", tokenStore: { keychain: "agentpush", account: "{server}" } },
|
|
65
|
-
}))
|
|
66
|
-
```
|
|
67
|
-
Or ship a vendor `*.auth.md` and `parseAuthProviderManifest(...)` → `registerAuthProvider(...)` — a host adds providers without editing this package.
|
|
68
|
-
|
|
69
|
-
### 2. Store the secret ONCE (out of env, into the store)
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
import { KeychainStore, resolveStoreRef, getAuthProvider } from "@agentproto/auth"
|
|
73
|
-
|
|
74
|
-
const p = getAuthProvider("agentpush")!
|
|
75
|
-
const store = new KeychainStore() // or FileStore for headless
|
|
76
|
-
await store.write(resolveStoreRef(p.auth.tokenStore, p.apiBase, p.audience),
|
|
77
|
-
{ value: process.env.AGENTPUSH_API_KEY!, kind: "pat" })
|
|
78
|
-
```
|
|
79
|
-
Do this once (onboarding / a `secrets set` step) — then delete the env var.
|
|
80
|
-
|
|
81
|
-
### 3. Resolve at use-time
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
import { CredentialBroker, getAuthProvider } from "@agentproto/auth"
|
|
85
|
-
|
|
86
|
-
const broker = new CredentialBroker({ store, getProvider: getAuthProvider })
|
|
87
|
-
const headers = await broker.resolveHeaders({ path: "agentpush", audience: "mcp" })
|
|
88
|
-
// → { Authorization: "Bearer …" } — attach to your fetch / MCP transport
|
|
89
|
-
```
|
|
90
|
-
Fresh every call; for `service-auth`/`device-code` it auto-refreshes. No secret
|
|
91
|
-
touches env or `.mcp.json`.
|
|
92
|
-
|
|
93
|
-
## Two consumption paths
|
|
94
|
-
|
|
95
|
-
**A. Agent calls the service in its own code/tool.** Works TODAY: resolve via the
|
|
96
|
-
broker (step 3) and attach the header. Nothing else to wire.
|
|
97
|
-
|
|
98
|
-
**B. Service exposed as a child MCP the agent mounts.** The clean target is a
|
|
99
|
-
**`credentialRef`** on the child-mcp spec that the daemon resolves via the broker
|
|
100
|
-
at connect-time (the `mcp-header` exposure pattern — `resolveMcpHeaderExposure`
|
|
101
|
-
turns a `credentialPath` into headers via a structural resolver the broker
|
|
102
|
-
satisfies). **Gap:** `agent_start.mcpServers` today carries only
|
|
103
|
-
`{ name, ref, transport }` — no `headers`/`credentialRef` — so brokered auth
|
|
104
|
-
can't yet reach a child MCP at mount. Until that plumbing lands, either use path
|
|
105
|
-
A, or resolve the header at spawn and pass it through your own mount path.
|
|
106
|
-
|
|
107
|
-
## Worked example — agentpush
|
|
108
|
-
|
|
109
|
-
agentpush uses a static Bearer key. Clean-auth wiring:
|
|
110
|
-
1. Register `agentpush` as a `pat` provider (step 1), `audience: "mcp"`.
|
|
111
|
-
2. Move `AGENTPUSH_API_KEY` from the daemon env into the store (step 2).
|
|
112
|
-
3. In-code callers resolve `broker.resolveHeaders({ path: "agentpush" })` (path A) —
|
|
113
|
-
works now, key out of the global env, scoped to this agent.
|
|
114
|
-
4. For agentpush-as-child-MCP (path B), a `credentialRef: "agentpush"` on the
|
|
115
|
-
child-mcp spec + daemon broker-resolve-at-connect is the north star (reuses
|
|
116
|
-
everything here; needs the `agent_start.mcpServers` credentialRef plumbing).
|
|
117
|
-
|
|
118
|
-
## Common mistakes
|
|
119
|
-
|
|
120
|
-
- **Storing the key in the daemon's global env** — every spawned agent inherits
|
|
121
|
-
it. The whole point of the store is per-service, per-spawn scoping.
|
|
122
|
-
- **Skipping `audience`** — set it (`api`/`mcp`/`tunnel`) so a credential minted
|
|
123
|
-
for one plane can't be presented on another (defense-in-depth; the normative
|
|
124
|
-
boundary is server-side).
|
|
125
|
-
- **Caching `resolveHeaders` output** — resolve per call; the broker owns
|
|
126
|
-
freshness/refresh. A cached header defeats `service-auth`/`device-code` refresh.
|
|
127
|
-
- **`pat` where the service issues short-lived tokens** — use `service-auth`
|
|
128
|
-
(mint + refresh) instead of pasting a token that expires.
|
|
129
|
-
- **Wrong header shape** — `resolveHeaders` returns a header map; a service that
|
|
130
|
-
wants `X-Api-Key` (not `Authorization`) needs the provider/flow to emit that
|
|
131
|
-
shape, not a Bearer.
|