@abloatai/ablo 0.5.1 → 0.7.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.
- package/CHANGELOG.md +61 -0
- package/README.md +248 -124
- package/dist/BaseSyncedStore.d.ts +3 -3
- package/dist/BaseSyncedStore.js +3 -3
- package/dist/api/index.d.ts +3 -3
- package/dist/api/index.js +1 -1
- package/dist/client/Ablo.d.ts +91 -93
- package/dist/client/Ablo.js +122 -60
- package/dist/client/ApiClient.d.ts +14 -14
- package/dist/client/ApiClient.js +81 -55
- package/dist/client/createInternalComponents.d.ts +2 -3
- package/dist/client/createInternalComponents.js +2 -3
- package/dist/client/createModelProxy.d.ts +116 -90
- package/dist/client/createModelProxy.js +128 -128
- package/dist/client/index.d.ts +6 -7
- package/dist/client/index.js +4 -5
- package/dist/client/validateAbloOptions.js +5 -5
- package/dist/coordination/index.d.ts +6 -0
- package/dist/coordination/index.js +6 -0
- package/dist/coordination/schema.d.ts +329 -0
- package/dist/coordination/schema.js +209 -0
- package/dist/core/QueryView.d.ts +4 -1
- package/dist/core/QueryView.js +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +7 -0
- package/dist/core/query-utils.d.ts +7 -10
- package/dist/core/query-utils.js +2 -3
- package/dist/errorCodes.d.ts +264 -0
- package/dist/errorCodes.js +251 -0
- package/dist/errors.d.ts +59 -14
- package/dist/errors.js +73 -12
- package/dist/index.d.ts +11 -9
- package/dist/index.js +8 -12
- package/dist/interfaces/index.d.ts +2 -10
- package/dist/mutators/Transaction.d.ts +2 -2
- package/dist/mutators/Transaction.js +2 -2
- package/dist/mutators/mutateActions.d.ts +44 -0
- package/dist/{react/useMutate.js → mutators/mutateActions.js} +11 -28
- package/dist/mutators/readerActions.d.ts +32 -0
- package/dist/{react/useReader.js → mutators/readerActions.js} +2 -18
- package/dist/policy/index.d.ts +1 -1
- package/dist/policy/index.js +1 -1
- package/dist/policy/types.d.ts +31 -0
- package/dist/policy/types.js +15 -0
- package/dist/query/types.d.ts +1 -1
- package/dist/react/AbloProvider.d.ts +13 -1
- package/dist/react/AbloProvider.js +14 -6
- package/dist/react/context.d.ts +4 -4
- package/dist/react/index.d.ts +4 -5
- package/dist/react/index.js +3 -7
- package/dist/react/useAblo.d.ts +14 -14
- package/dist/react/useAblo.js +26 -26
- package/dist/react/useIntent.d.ts +2 -2
- package/dist/react/useIntent.js +2 -2
- package/dist/react/useMutators.d.ts +1 -1
- package/dist/react/usePresence.d.ts +3 -3
- package/dist/react/usePresence.js +4 -4
- package/dist/react/useUndoScope.d.ts +1 -1
- package/dist/schema/ddl.d.ts +62 -0
- package/dist/schema/ddl.js +317 -0
- package/dist/schema/diff.d.ts +167 -0
- package/dist/schema/diff.js +280 -0
- package/dist/schema/field.d.ts +16 -19
- package/dist/schema/field.js +30 -17
- package/dist/schema/generate.d.ts +19 -0
- package/dist/schema/generate.js +87 -0
- package/dist/schema/index.d.ts +9 -3
- package/dist/schema/index.js +14 -2
- package/dist/schema/model.d.ts +87 -25
- package/dist/schema/model.js +33 -3
- package/dist/schema/relation.d.ts +17 -0
- package/dist/schema/roles.d.ts +148 -0
- package/dist/schema/roles.js +149 -0
- package/dist/schema/schema.d.ts +10 -69
- package/dist/schema/schema.js +58 -24
- package/dist/schema/select.d.ts +25 -0
- package/dist/schema/select.js +55 -0
- package/dist/schema/serialize.d.ts +96 -0
- package/dist/schema/serialize.js +231 -0
- package/dist/schema/sugar.d.ts +20 -3
- package/dist/schema/sugar.js +5 -1
- package/dist/schema/tenancy.d.ts +66 -0
- package/dist/schema/tenancy.js +58 -0
- package/dist/sync/HydrationCoordinator.d.ts +2 -0
- package/dist/sync/HydrationCoordinator.js +23 -17
- package/dist/sync/SyncWebSocket.d.ts +17 -0
- package/dist/sync/SyncWebSocket.js +46 -1
- package/dist/sync/awaitIntentGrant.d.ts +26 -0
- package/dist/sync/awaitIntentGrant.js +60 -0
- package/dist/sync/createIntentStream.d.ts +2 -1
- package/dist/sync/createIntentStream.js +89 -5
- package/dist/sync/createPresenceStream.js +1 -1
- package/dist/sync/participants.d.ts +2 -2
- package/dist/sync/participants.js +9 -18
- package/dist/types/global.d.ts +43 -52
- package/dist/types/global.js +16 -18
- package/dist/types/streams.d.ts +90 -42
- package/docs/api-keys.md +44 -0
- package/docs/api.md +72 -173
- package/docs/audit.md +5 -5
- package/docs/cli.md +212 -0
- package/docs/client-behavior.md +42 -43
- package/docs/coordination.md +343 -0
- package/docs/data-sources.md +16 -16
- package/docs/examples/agent-human.md +30 -32
- package/docs/examples/ai-sdk-tool.md +32 -33
- package/docs/examples/existing-python-backend.md +38 -36
- package/docs/examples/nextjs.md +24 -25
- package/docs/examples/scoped-agent.md +78 -0
- package/docs/examples/server-agent.md +20 -61
- package/docs/guarantees.md +34 -56
- package/docs/identity.md +529 -0
- package/docs/index.md +18 -24
- package/docs/integration-guide.md +130 -144
- package/docs/interaction-model.md +32 -95
- package/docs/mcp/claude-code.md +3 -3
- package/docs/mcp/cursor.md +1 -1
- package/docs/mcp/windsurf.md +1 -1
- package/docs/mcp.md +11 -26
- package/docs/quickstart.md +43 -49
- package/docs/react.md +74 -24
- package/docs/roadmap.md +17 -7
- package/llms.txt +34 -39
- package/package.json +8 -1
- package/dist/react/useMutate.d.ts +0 -83
- package/dist/react/useQuery.d.ts +0 -123
- package/dist/react/useQuery.js +0 -145
- package/dist/react/useReader.d.ts +0 -69
- package/docs/capabilities.md +0 -163
package/docs/capabilities.md
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
# Capabilities
|
|
2
|
-
|
|
3
|
-
A capability is scoped credentials for a non-human actor.
|
|
4
|
-
|
|
5
|
-
It is not a task and it is not an intent. It is the permission boundary that
|
|
6
|
-
answers who may touch which resources.
|
|
7
|
-
|
|
8
|
-
Most apps should use `api.agent(...).run(...)`; the SDK creates and revokes the
|
|
9
|
-
capability for that run. Create capabilities directly only for custom runtimes,
|
|
10
|
-
MCP sessions, or protocol-level integrations.
|
|
11
|
-
|
|
12
|
-
## Why capabilities, not API keys
|
|
13
|
-
|
|
14
|
-
Static API keys protect a human-operated workflow with one shared secret —
|
|
15
|
-
fine for a server-to-server integration written once and forgotten. They are
|
|
16
|
-
the wrong primitive for AI agents:
|
|
17
|
-
|
|
18
|
-
- An agent that holds an account-wide key inherits every permission your
|
|
19
|
-
human team has. A leaked key burns the whole account; a confused-deputy
|
|
20
|
-
bug lets the agent write to resources it had no business touching.
|
|
21
|
-
- Per-task work needs per-task attribution. One static key across every
|
|
22
|
-
agent invocation makes the audit trail say "the API key did it" — which
|
|
23
|
-
tells you nothing about which run, which prompt, or which user delegated
|
|
24
|
-
the action.
|
|
25
|
-
- Long-lived secrets accumulate blast radius. The longer a credential is
|
|
26
|
-
valid, the more places it travels (logs, env files, agent prompts), and
|
|
27
|
-
the wider the leak surface.
|
|
28
|
-
|
|
29
|
-
Capabilities replace the one-static-key model with **per-run, per-scope,
|
|
30
|
-
short-lived** credentials. The 2025-2026 AI-agent auth consensus (the
|
|
31
|
-
OAuth 2.1 / MCP spec, GCP short-lived credentials, AWS STS AssumeRole,
|
|
32
|
-
HashiCorp Vault leases, Auth0 Token Vault) converged on the same shape:
|
|
33
|
-
issue scoped tokens, attach a TTL, verify per-request, support fast
|
|
34
|
-
revocation. Capabilities are Ablo's instance of that pattern.
|
|
35
|
-
|
|
36
|
-
## The three-layer security model
|
|
37
|
-
|
|
38
|
-
Every commit is authorized by three independent checks. None of them is
|
|
39
|
-
sufficient on its own; together they cap the blast radius of every
|
|
40
|
-
credible failure mode.
|
|
41
|
-
|
|
42
|
-
1. **Lease (TTL)** — every capability has an expiry encoded in the bearer
|
|
43
|
-
token itself. After the lease, the token decodes but every signature
|
|
44
|
-
check fails. Caps the damage from a leaked token without requiring a
|
|
45
|
-
database lookup on the hot path.
|
|
46
|
-
2. **Signature verification (per request)** — every commit re-verifies
|
|
47
|
-
the token's signature and attenuation. Stateless, cheap (microseconds),
|
|
48
|
-
detects forged or tampered tokens. The token's `syncGroups` and
|
|
49
|
-
`operations` are checked against the commit's actual targets;
|
|
50
|
-
`capability_scope_denied` rejects the request before any write lands.
|
|
51
|
-
3. **Revocation** — `DELETE /v1/capabilities/:id` flips the cap's status
|
|
52
|
-
server-side; live WebSocket sessions are closed, future requests are
|
|
53
|
-
rejected within seconds. Closes the gap between lease refresh cycles
|
|
54
|
-
when you need *immediate* cutoff (compromised agent, accidental
|
|
55
|
-
over-grant, end-of-trial cleanup).
|
|
56
|
-
|
|
57
|
-
The mental model: **lease prevents the slow leak, signature verification
|
|
58
|
-
prevents the forged token, revocation prevents the active attacker.**
|
|
59
|
-
Removing any one of the three leaves a class of failure uncovered.
|
|
60
|
-
|
|
61
|
-
## Why this shape, in one paragraph each
|
|
62
|
-
|
|
63
|
-
**Lease, not "session"** — A session token requires a database round-trip
|
|
64
|
-
on every request to check liveness. A lease is encoded in the token and
|
|
65
|
-
verified stateless. Vault popularized the term ("lease, renew, revoke");
|
|
66
|
-
the mechanic is the same as AWS STS time-bounded credentials and GCP
|
|
67
|
-
short-lived service-account creds. Ablo uses the word "lease" because the
|
|
68
|
-
bearer holds a *bounded grant*, not just a timer — the same word
|
|
69
|
-
`capability_scope_denied` errors reference.
|
|
70
|
-
|
|
71
|
-
**Two scope axes (`syncGroups` + `operations`), not one** — `syncGroups`
|
|
72
|
-
narrows *which rows* the actor can see; `operations` narrows *which verbs*
|
|
73
|
-
the actor can use. Collapsing them into one set forces an explosion
|
|
74
|
-
(`tasks.update:org:acme`, `tasks.delete:org:acme`, ...). Keeping them
|
|
75
|
-
orthogonal lets a 3-group × 5-op cap stay 3+5 instead of 3×5. Same shape
|
|
76
|
-
as IAM policies (`Resource` + `Action`), Stripe Restricted Keys
|
|
77
|
-
(`resource_type` + `permission`), and Biscuit caveats.
|
|
78
|
-
|
|
79
|
-
**Strings from `identityRoles`, never invented** — A consumer who types
|
|
80
|
-
`'org:acme'` literally couples their code to Ablo's identity convention.
|
|
81
|
-
Templates declared once on the schema (see integration-guide.md §1) let
|
|
82
|
-
the convention live in one place; consumers reference it by template, not
|
|
83
|
-
by hand-typing the prefix. Same boundary as Liveblocks' `prepareSession()`
|
|
84
|
-
or PowerSync's named streams: server owns the namespace, client picks a
|
|
85
|
-
subset by id.
|
|
86
|
-
|
|
87
|
-
**`participantKind` cannot be `'user'`** — Capabilities are explicitly
|
|
88
|
-
for non-human actors. A capability minted as a user would let any code
|
|
89
|
-
path with that bearer impersonate the human; instead, user actions flow
|
|
90
|
-
through session auth (cookies / OAuth) so the audit chain says
|
|
91
|
-
"alice@example.com did X" — not "a token did X." Stripe makes the same
|
|
92
|
-
split between Restricted API Keys (system) and Connect OAuth (user-on-
|
|
93
|
-
behalf-of).
|
|
94
|
-
|
|
95
|
-
## What capabilities aren't
|
|
96
|
-
|
|
97
|
-
| Not | Why we didn't ship that |
|
|
98
|
-
|---|---|
|
|
99
|
-
| **A static API key** | One leaked secret = whole-account compromise. No per-run attribution. No automatic expiry. |
|
|
100
|
-
| **An OAuth session token** | OAuth's user-delegation model assumes a human in the loop; agents are the actor, not the delegate. The auth flow round-trips don't fit agent runtimes. |
|
|
101
|
-
| **An opaque DB session** | Per-request DB lookup is the slow path. Stateless verification (signature + lease) is the fast path; the DB is the revocation list, not the live-check. |
|
|
102
|
-
| **A bearer JWT with `exp`** | Conceptually similar, but Biscuit caveats let us *attenuate* a cap further (delegate a narrower sub-scope to a sub-agent) without re-minting. Plain JWTs can't subset themselves. |
|
|
103
|
-
|
|
104
|
-
## Create
|
|
105
|
-
|
|
106
|
-
```ts
|
|
107
|
-
import Ablo from '@abloatai/ablo';
|
|
108
|
-
|
|
109
|
-
const admin = Ablo({ apiKey: process.env.ABLO_API_KEY });
|
|
110
|
-
|
|
111
|
-
const capability = await admin.capabilities.create({
|
|
112
|
-
participantKind: 'agent',
|
|
113
|
-
participantId: 'agent:task-writer',
|
|
114
|
-
// Identity-anchored groups derived from the schema's `identityRoles`
|
|
115
|
-
// registration (see integration-guide.md §1). The strings here mirror
|
|
116
|
-
// whatever templates the schema declared — `org:{id}` and friends for
|
|
117
|
-
// Ablo's stock schema; a third-party schema with `region:{id}` /
|
|
118
|
-
// `customer:{id}` roles would pass those instead.
|
|
119
|
-
syncGroups: ['org:acme', 'user:agent:task-writer'],
|
|
120
|
-
operations: ['tasks.retrieve', 'tasks.update'],
|
|
121
|
-
lease: '10m',
|
|
122
|
-
});
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Pass `capability.token` into the agent runtime. The agent never sees admin
|
|
126
|
-
credentials.
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
const agent = capability.client();
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Inspect
|
|
133
|
-
|
|
134
|
-
```ts
|
|
135
|
-
const record = await admin.capabilities.retrieve(capability.id);
|
|
136
|
-
|
|
137
|
-
record.status; // active | expired | revoked
|
|
138
|
-
record.operations; // ['tasks.retrieve', 'tasks.update']
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Inspection never returns the bearer token. Tokens are returned once at create
|
|
142
|
-
time.
|
|
143
|
-
|
|
144
|
-
## Revoke
|
|
145
|
-
|
|
146
|
-
```ts
|
|
147
|
-
await admin.capabilities.revoke(capability.id);
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Revocation is forward-only. Already accepted commits stand; future requests with
|
|
151
|
-
that token are rejected within seconds.
|
|
152
|
-
|
|
153
|
-
## Scope Grammar
|
|
154
|
-
|
|
155
|
-
| Field | Required | Meaning |
|
|
156
|
-
|---|---|---|
|
|
157
|
-
| `participantKind` | yes | `agent` or `system`. Capabilities cannot impersonate `user`. |
|
|
158
|
-
| `participantId` | recommended | Stable actor id, for example `agent:task-writer`. |
|
|
159
|
-
| `syncGroups` | yes | Sync groups the actor can touch. Strings come from the schema's `identityRoles` templates or a model's `syncGroupFormat` — never invented by the caller. |
|
|
160
|
-
| `operations` | yes | Typed operation names, for example `tasks.update`. |
|
|
161
|
-
| `lease` / `leaseSeconds` | recommended | Crash cleanup window for abandoned actors. |
|
|
162
|
-
| `label` | no | Human-readable label for dashboards and audit. |
|
|
163
|
-
| `userMeta` | no | Customer-attested end-user metadata for B2B2C flows. |
|