@cat-factory/gatekeeper-worker 0.4.2 → 0.5.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/README.md +58 -12
- package/dist/capability.d.ts +45 -0
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +60 -4
- package/dist/capability.js.map +1 -1
- package/dist/errors.d.ts +13 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/gatekeeper.d.ts +47 -2
- package/dist/gatekeeper.d.ts.map +1 -1
- package/dist/gatekeeper.js +89 -5
- package/dist/gatekeeper.js.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +12 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +28 -0
- package/dist/markdown.js.map +1 -0
- package/dist/os/account.d.ts +27 -0
- package/dist/os/account.d.ts.map +1 -0
- package/dist/os/account.js +130 -0
- package/dist/os/account.js.map +1 -0
- package/dist/os/descriptions.d.ts +43 -0
- package/dist/os/descriptions.d.ts.map +1 -0
- package/dist/os/descriptions.js +100 -0
- package/dist/os/descriptions.js.map +1 -0
- package/dist/os/discoverability.d.ts +30 -0
- package/dist/os/discoverability.d.ts.map +1 -0
- package/dist/os/discoverability.js +46 -0
- package/dist/os/discoverability.js.map +1 -0
- package/dist/os/exports.d.ts +28 -0
- package/dist/os/exports.d.ts.map +1 -0
- package/dist/os/exports.js +68 -0
- package/dist/os/exports.js.map +1 -0
- package/dist/os/protocol.d.ts +150 -0
- package/dist/os/protocol.d.ts.map +1 -0
- package/dist/os/protocol.js +22 -0
- package/dist/os/protocol.js.map +1 -0
- package/dist/os/queue.d.ts +90 -0
- package/dist/os/queue.d.ts.map +1 -0
- package/dist/os/queue.js +197 -0
- package/dist/os/queue.js.map +1 -0
- package/dist/os/resource-core.d.ts +100 -0
- package/dist/os/resource-core.d.ts.map +1 -0
- package/dist/os/resource-core.js +155 -0
- package/dist/os/resource-core.js.map +1 -0
- package/dist/os/resource.d.ts +16 -0
- package/dist/os/resource.d.ts.map +1 -0
- package/dist/os/resource.js +64 -0
- package/dist/os/resource.js.map +1 -0
- package/dist/os/resources.d.ts +11 -0
- package/dist/os/resources.d.ts.map +1 -0
- package/dist/os/resources.js +26 -0
- package/dist/os/resources.js.map +1 -0
- package/dist/os/session-types.d.ts +6 -0
- package/dist/os/session-types.d.ts.map +1 -0
- package/dist/os/session-types.js +82 -0
- package/dist/os/session-types.js.map +1 -0
- package/dist/os/vendor.d.ts +14 -0
- package/dist/os/vendor.d.ts.map +1 -0
- package/dist/os/vendor.js +95 -0
- package/dist/os/vendor.js.map +1 -0
- package/dist/policy/compile.d.ts +38 -0
- package/dist/policy/compile.d.ts.map +1 -1
- package/dist/policy/compile.js +42 -4
- package/dist/policy/compile.js.map +1 -1
- package/dist/policy/index.d.ts +1 -1
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/index.js +1 -1
- package/dist/policy/index.js.map +1 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +24 -5
- package/dist/worker.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -3,10 +3,23 @@
|
|
|
3
3
|
## What it is
|
|
4
4
|
|
|
5
5
|
The Cloudflare Worker machinery behind a cat-factory **Gatekeeper**: a credential-holding front
|
|
6
|
-
end that lets a [Cloudflare OS](https://github.com/cloudflare/cloudflare-os) workspace
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
end that lets a [Cloudflare OS](https://github.com/cloudflare/cloudflare-os) workspace drive
|
|
7
|
+
cat-factory without an agent ever seeing a credential. Agents hold an object-capability whose
|
|
8
|
+
methods are exactly what policy granted; the keys stay in Worker secrets and Durable Object
|
|
9
|
+
storage.
|
|
10
|
+
|
|
11
|
+
It serves TWO doors onto the same rooms, and which one a caller comes in by decides how it is
|
|
12
|
+
authorized:
|
|
13
|
+
|
|
14
|
+
| Door | Who comes in by it | Authorization |
|
|
15
|
+
| --------------------------------- | ---------------------------------------------------------------- | ------------------- |
|
|
16
|
+
| The `GatekeeperVendor` entrypoint | A Cloudflare OS workspace, over a `GATEKEEPER_*` service binding | Holding the binding |
|
|
17
|
+
| `ALL /rpc` (Cap'n Web over HTTP) | Any other agent runtime that speaks Cap'n Web | `OS_SHARED_TOKEN` |
|
|
18
|
+
|
|
19
|
+
The published Cloudflare OS contract reaches a gatekeeper over native Workers RPC to a
|
|
20
|
+
`WorkerEntrypoint` export named `GatekeeperVendor`; Cap'n Web is that workspace's browser-to-backend
|
|
21
|
+
and gadget-side protocol, which shares the semantics and not the wire. So `/rpc` is the door for
|
|
22
|
+
everything that is NOT a Cloudflare OS deployment, and nothing here is Cloudflare-OS-only.
|
|
10
23
|
|
|
11
24
|
It is the machinery half of the Gatekeeper family:
|
|
12
25
|
|
|
@@ -83,9 +96,20 @@ version has to be the consumer's.
|
|
|
83
96
|
|
|
84
97
|
## What it does
|
|
85
98
|
|
|
86
|
-
- **Object-capability bindings
|
|
87
|
-
|
|
88
|
-
|
|
99
|
+
- **Object-capability bindings.** An agent holds an object whose METHODS are the operations policy
|
|
100
|
+
granted it. There is no allow-list consulted per call, because there is nothing to consult: an
|
|
101
|
+
operation the tier does not carry is not a method that refuses, it is absent.
|
|
102
|
+
- **The Cloudflare OS object model, as a facade over all of it.** `GatekeeperVendor` →
|
|
103
|
+
`CatFactoryAccount` → `CatFactoryResource` → session, with `describe()`,
|
|
104
|
+
`getSupportedResources()` and `getTypeScriptTypes()` all PROJECTIONS of the operation table
|
|
105
|
+
rather than transcriptions of it. A resource is the paired cat-factory workspace, named by a
|
|
106
|
+
URLPattern over the deployment origin: one Gatekeeper serves one workspace, because the
|
|
107
|
+
provisioning key it holds is scoped to one.
|
|
108
|
+
- **The workspace's approval queue, in front of every call.** On the entrypoint path each read is
|
|
109
|
+
authorized before it is MADE, and each write is SUBMITTED and performed only when
|
|
110
|
+
the workspace applies it. Reads that serve captured agent text are marked unshareable, actions
|
|
111
|
+
carry the consequence the table states, and nothing is offered for unattended auto-approval while
|
|
112
|
+
the surface annotates no write as safe. The tier policy underneath stays the floor.
|
|
89
113
|
- **Per-actor credentials.** Each caller gets their own cat-factory key, minted through
|
|
90
114
|
`POST /api/v1/keys` at the tier's scope and stamped with your identity for that person
|
|
91
115
|
(`externalIdentity`), so a run traces back to a human and role-scoped merge policy stays real.
|
|
@@ -138,14 +162,36 @@ The Worker serves five routes:
|
|
|
138
162
|
| Route | Auth | What it is |
|
|
139
163
|
| ------------------------------ | ----------------- | ------------------------------------------------------------- |
|
|
140
164
|
| `POST /webhook` | delivery HMAC | The platform's outbound deliveries. Verified over raw bytes. |
|
|
141
|
-
| `ALL /rpc` | `OS_SHARED_TOKEN` |
|
|
165
|
+
| `ALL /rpc` | `OS_SHARED_TOKEN` | Cap'n Web, for an agent runtime that is not a Cloudflare OS. |
|
|
142
166
|
| `POST /admin/enroll` | `OS_SHARED_TOKEN` | Re-assert the webhook registration. Also runs hourly on cron. |
|
|
143
167
|
| `POST /admin/retire?actorId=…` | `OS_SHARED_TOKEN` | Offboarding: revoke every key minted for one OS user. |
|
|
144
|
-
| `GET /health` | none | Green
|
|
168
|
+
| `GET /health` | none | Green when every binding is set and the policy compiles. |
|
|
169
|
+
|
|
170
|
+
`/rpc` is bearer-gated because a Worker with a route attached is reachable by anyone who finds it,
|
|
171
|
+
and a capability surface whose only defence is obscurity is not one. The Cloudflare OS path does not
|
|
172
|
+
come through here at all: it arrives on a service binding, which never traverses the internet and
|
|
173
|
+
which only that deployment's operator can write, so holding it IS the authorization and a second
|
|
174
|
+
secret in front of it would protect nothing.
|
|
175
|
+
|
|
176
|
+
### `/health` also reports whether a Cloudflare OS could install this
|
|
177
|
+
|
|
178
|
+
Two things decide that, and neither has a request path of its own: the entry module must export the
|
|
179
|
+
four names the object model resolves (`GatekeeperVendor`, `CatFactoryAccount`,
|
|
180
|
+
`CatFactoryResource`, `CatFactoryVerifier`), and the policy must name an `autoProvisionedTier`. A
|
|
181
|
+
workspace that finds either missing does not get an error anyone monitors; it never finishes
|
|
182
|
+
installing. So a green response carries the answer beside `ok`:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{ "ok": true, "os": { "discoverable": true, "blockers": [] } }
|
|
186
|
+
```
|
|
145
187
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
188
|
+
It is REPORTED, never folded into the status, because a Gatekeeper serving `/rpc` and nothing else
|
|
189
|
+
is a supported deployment: this package promises that door to consumers that are not a Cloudflare
|
|
190
|
+
OS, and turning their liveness red on a version bump would be this route answering a question
|
|
191
|
+
nobody asked it. A deployment that wants discovery keys a monitor on `os.discoverable`; each entry
|
|
192
|
+
in `blockers` carries a `reason` (`missing_exports`, `no_auto_provisioned_tier`) and a `detail`
|
|
193
|
+
naming the fix, and both are reported in one pass so a half-wired deployment is not wired one
|
|
194
|
+
redeploy at a time.
|
|
149
195
|
|
|
150
196
|
## What to customize: the policy
|
|
151
197
|
|
package/dist/capability.d.ts
CHANGED
|
@@ -1,12 +1,57 @@
|
|
|
1
1
|
import { RpcTarget } from 'capnweb';
|
|
2
|
+
import type { GatekeeperBinding } from '@cat-factory/gatekeeper-bindings';
|
|
2
3
|
import type { Actor, KeyBroker } from './keys.js';
|
|
3
4
|
import { type CompiledTier } from './policy/compile.js';
|
|
4
5
|
import type { ApprovalCard, GatekeeperState } from './state.js';
|
|
6
|
+
/**
|
|
7
|
+
* The governance a session's calls pass through, when the door it arrived by has one.
|
|
8
|
+
*
|
|
9
|
+
* This is the ONE seam the Cloudflare OS approval queue is threaded onto, and it is one seam
|
|
10
|
+
* because `invoke` below is one closure: every granted operation, and every reserved method that
|
|
11
|
+
* reads platform data, funnels through it. A door with no governance passes `undefined` and gets
|
|
12
|
+
* byte-for-byte the prior behaviour, which is what keeps the `/rpc` surface a promise this package
|
|
13
|
+
* can go on making.
|
|
14
|
+
*
|
|
15
|
+
* The tier policy is the FLOOR underneath it, never a substitute for it: an operation policy never
|
|
16
|
+
* granted is absent from the object, so governance is only ever asked about calls that exist.
|
|
17
|
+
*/
|
|
18
|
+
export interface SessionGovernance {
|
|
19
|
+
/**
|
|
20
|
+
* Authorize a read, BEFORE it is made. Throws to refuse, and a refusal means the upstream call
|
|
21
|
+
* never happened rather than happening and being withheld.
|
|
22
|
+
*/
|
|
23
|
+
observe(binding: GatekeeperBinding, args: Record<string, unknown>): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Authorize a read served from this Gatekeeper's own durable projection of delivered data.
|
|
26
|
+
*
|
|
27
|
+
* Separate from {@link observe} because there is no binding behind it, not because it is a
|
|
28
|
+
* lesser read: the cards and run states came from the paired deployment over the webhook, so
|
|
29
|
+
* showing them is an observation of that deployment.
|
|
30
|
+
*/
|
|
31
|
+
observeLocal(title: string, detail: string): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Submit a side effect and perform it only if it is approved.
|
|
34
|
+
*
|
|
35
|
+
* `perform` is the real call, invoked at most once and only after approval; a refusal throws
|
|
36
|
+
* instead of returning, so a refused action cannot read as a call that returned nothing.
|
|
37
|
+
*/
|
|
38
|
+
act<T>(binding: GatekeeperBinding, args: Record<string, unknown>, perform: () => Promise<T>): Promise<T>;
|
|
39
|
+
/**
|
|
40
|
+
* The session is gone: release everything it was holding on the workspace's behalf.
|
|
41
|
+
*
|
|
42
|
+
* Called from the capability's own disposer, which the runtime runs when the last stub pointing
|
|
43
|
+
* at it is dropped. Without it a session's undecided actions and its hold on the workspace's
|
|
44
|
+
* queue would both outlive the only thing that could ever settle them.
|
|
45
|
+
*/
|
|
46
|
+
close(): void;
|
|
47
|
+
}
|
|
5
48
|
export interface SessionDependencies {
|
|
6
49
|
actor: Actor;
|
|
7
50
|
tier: CompiledTier;
|
|
8
51
|
keys: KeyBroker;
|
|
9
52
|
state: DurableObjectStub<GatekeeperState>;
|
|
53
|
+
/** Present on the OS entrypoint path; absent on `/rpc`, which governs by tier alone. */
|
|
54
|
+
governance?: SessionGovernance;
|
|
10
55
|
}
|
|
11
56
|
/** What `tier()` answers: enough for an OS Gadget to render who the caller is acting as. */
|
|
12
57
|
export interface TierSummary {
|
package/dist/capability.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAWzE,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGjD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAY,MAAM,YAAY,CAAA;AAoBzE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjF;;;;;;OAMG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EACH,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,CAAC,CAAC,CAAA;IACb;;;;;;OAMG;IACH,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,iBAAiB,CAAC,eAAe,CAAC,CAAA;IACzC,wFAAwF;IACxF,UAAU,CAAC,EAAE,iBAAiB,CAAA;CAC/B;AAED,4FAA4F;AAC5F,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,2FAA2F;IAC3F,SAAS,EAAE,OAAO,CAAA;IAClB,0FAA0F;IAC1F,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAA;YACd,OAAO,EAAE,MAAM,CAAA;YACf,OAAO,EAAE,MAAM,CAAA;YACf,oGAAoG;YACpG,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,SAAS;gBACf,IAAI,EAAE,MAAM,CAAA;gBACZ,QAAQ,EAAE,OAAO,CAAA;gBACjB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;gBAC3B,MAAM,EAAE,MAAM,CAAA;aACf,EAAE,CAAA;SACJ,EAAE,CAAA;KACJ,EAAE,CAAA;IACH,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,SAAS,CAmKpE"}
|
package/dist/capability.js
CHANGED
|
@@ -10,10 +10,18 @@
|
|
|
10
10
|
// Methods live on a per-session PROTOTYPE, never on the instance. Cap'n Web deliberately refuses
|
|
11
11
|
// to serve an RpcTarget's own instance properties (they would leak private internals), so an
|
|
12
12
|
// instance-property capability would be a set of methods no caller can reach.
|
|
13
|
+
//
|
|
14
|
+
// ONE object serves both doors, which looks like it should not work and does. `RpcTarget` is
|
|
15
|
+
// imported from `capnweb` while the Cloudflare OS door returns this across NATIVE Workers RPC,
|
|
16
|
+
// which serializes only `cloudflare:workers` targets. They are the same class: inside workerd
|
|
17
|
+
// capnweb re-exports the runtime's own `RpcTarget` rather than declaring one, which is what lets a
|
|
18
|
+
// session cross either wire. It is stated here because the alternative reading (two incompatible
|
|
19
|
+
// base classes, a `DataCloneError` on the first bind) is the more obvious one.
|
|
13
20
|
import { RpcTarget } from 'capnweb';
|
|
14
21
|
import { answerCard, assertAnswerable, pendingParks, describeStale, } from './approvals.js';
|
|
15
22
|
import { GatekeeperError, PolicyError } from './errors.js';
|
|
16
23
|
import { applyMask } from './masking.js';
|
|
24
|
+
import { fenced } from './markdown.js';
|
|
17
25
|
import { describeBinding } from './policy/compile.js';
|
|
18
26
|
/**
|
|
19
27
|
* The methods a capability carries beyond its granted bindings.
|
|
@@ -54,12 +62,46 @@ export function buildCapability(deps) {
|
|
|
54
62
|
if (binding === undefined) {
|
|
55
63
|
throw new GatekeeperError('binding_not_granted', `Tier '${tier.name}' does not grant '${name}'.`);
|
|
56
64
|
}
|
|
57
|
-
const
|
|
58
|
-
|
|
65
|
+
const perform = async () => await deps.keys.run(deps.actor, tier.keyScope, (client) => binding.invoke(client, args));
|
|
66
|
+
const governance = deps.governance;
|
|
67
|
+
if (governance === undefined)
|
|
68
|
+
return applyMask(await perform(), tier.mask);
|
|
69
|
+
// A read is authorized BEFORE it is performed. The contract permits the other order (the
|
|
70
|
+
// result may be in hand when the authorizer is asked), and it buys nothing here while costing
|
|
71
|
+
// something real. It buys nothing because the description is DERIVED from the operation table:
|
|
72
|
+
// the route, the scope floor, the argument bag and whether the read serves captured agent text
|
|
73
|
+
// are all known before the call, and handing an approver the rows themselves would put the
|
|
74
|
+
// very bytes `prohibitAllSharing` exists to withhold into an approval prompt. It costs
|
|
75
|
+
// something because performing first means a refused read has already been made: a real
|
|
76
|
+
// request, with a key minted for the occasion, pulling a telemetry sink's captured prompts into
|
|
77
|
+
// this Worker in order to ask whether the workspace wanted them read.
|
|
78
|
+
if (binding.readOnly) {
|
|
79
|
+
await governance.observe(binding, args);
|
|
80
|
+
return applyMask(await perform(), tier.mask);
|
|
81
|
+
}
|
|
82
|
+
return applyMask(await governance.act(binding, args, perform), tier.mask);
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Authorize a read this Gatekeeper serves from its OWN durable projection.
|
|
86
|
+
*
|
|
87
|
+
* The cards and the run states were delivered by the platform, so serving them is an observation
|
|
88
|
+
* of the paired deployment exactly as a live read is; that the bytes are local is an
|
|
89
|
+
* implementation detail of how they arrived. Governing them keeps "everything the session shows
|
|
90
|
+
* you passed the authorizer" true, which is the property the OS is relying on.
|
|
91
|
+
*/
|
|
92
|
+
const observeLocal = async (title, detail) => {
|
|
93
|
+
await deps.governance?.observeLocal(title, detail);
|
|
59
94
|
};
|
|
60
95
|
class Capability extends RpcTarget {
|
|
61
96
|
}
|
|
62
97
|
const proto = Capability.prototype;
|
|
98
|
+
// The end of the session, in the one place the runtime signals it. Both doors dispose an
|
|
99
|
+
// `RpcTarget` whose stubs have all been dropped, and both call this on the way; a `/rpc` session
|
|
100
|
+
// brings no governance and so has nothing to release. It is keyed by SYMBOL, which is also why
|
|
101
|
+
// it cannot collide with a binding or be reached over RPC as a method.
|
|
102
|
+
proto[Symbol.dispose] = () => {
|
|
103
|
+
deps.governance?.close();
|
|
104
|
+
};
|
|
63
105
|
for (const binding of tier.granted) {
|
|
64
106
|
proto[binding.name] = (args = {}) => invoke(binding.name, args);
|
|
65
107
|
}
|
|
@@ -76,17 +118,31 @@ export function buildCapability(deps) {
|
|
|
76
118
|
// `withheld()` is the degrade-loudly half: an agent that cannot tell "your policy hides this"
|
|
77
119
|
// from "this deployment does not have it" reports the wrong one to whoever has to fix it.
|
|
78
120
|
proto.withheld = () => tier.withheld;
|
|
79
|
-
proto.approvals_list = () =>
|
|
121
|
+
proto.approvals_list = async () => {
|
|
122
|
+
const cards = await deps.state.listCards();
|
|
123
|
+
await observeLocal('List the open approval cards', `${cards.length} card(s) the paired deployment raised and delivered to this Gatekeeper.`);
|
|
124
|
+
return cards;
|
|
125
|
+
};
|
|
80
126
|
// The lifecycle projection the `run.*` subscription feeds. Without it those deliveries would be
|
|
81
127
|
// verified, deduped and dropped, and a status Gadget would be back to polling `tasks_get_run`
|
|
82
128
|
// for a transition the platform already pushed.
|
|
83
|
-
proto.runs_watched = () =>
|
|
129
|
+
proto.runs_watched = async () => {
|
|
130
|
+
// Annotated rather than inferred: the Durable Object stub's serialization type narrows a
|
|
131
|
+
// `Record<string, unknown>` field to `never`, so the inferred result carries no `length`.
|
|
132
|
+
const runs = await deps.state.listRunStates();
|
|
133
|
+
await observeLocal('List the watched runs', `${runs.length} run(s) the paired deployment has pushed lifecycle events for.`);
|
|
134
|
+
return runs;
|
|
135
|
+
};
|
|
84
136
|
proto.approvals_inspect = async (cardId) => {
|
|
85
137
|
const card = await deps.state.getCard(cardId);
|
|
86
138
|
if (card === null) {
|
|
87
139
|
throw new GatekeeperError('card_not_found', `No approval card '${cardId}'. It may have been raised against a different paired ` +
|
|
88
140
|
'workspace, or predate this Gatekeeper.');
|
|
89
141
|
}
|
|
142
|
+
// The card's own title is agent- and user-authored: it came off a task somebody filed, rode
|
|
143
|
+
// the delivery in, and is about to be interpolated into Markdown a person reads in order to
|
|
144
|
+
// decide something. It gets the same fence the argument bag gets, for the same reason.
|
|
145
|
+
await observeLocal(`Inspect approval card ${cardId}`, `The card raised for run ${card.runId}, titled:\n\n${fenced(card.title, '')}`);
|
|
90
146
|
const list = (await invoke('decisions_list', { runId: card.runId }));
|
|
91
147
|
const parks = pendingParks(list).map((park) => ({
|
|
92
148
|
kind: park.kind,
|
package/dist/capability.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,EAAE;AACF,kGAAkG;AAClG,mGAAmG;AACnG,gGAAgG;AAChG,8FAA8F;AAC9F,+FAA+F;AAC/F,4DAA4D;AAC5D,EAAE;AACF,iGAAiG;AACjG,6FAA6F;AAC7F,8EAA8E;
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -13,7 +13,19 @@ export type GatekeeperReason = 'unknown_actor' | 'unknown_tier' | 'binding_not_g
|
|
|
13
13
|
/** The platform sent a parked decision without the id every answer to it addresses. */
|
|
14
14
|
| 'malformed_decision'
|
|
15
15
|
/** A minted credential was refused upstream and re-minting it was refused too. */
|
|
16
|
-
| 'credential_rejected'
|
|
16
|
+
| 'credential_rejected'
|
|
17
|
+
/** The workspace decided against a submitted action, so it was never performed. */
|
|
18
|
+
| 'action_rejected'
|
|
19
|
+
/** A decision named an action id this resource is not holding: already settled, or not ours. */
|
|
20
|
+
| 'unknown_action'
|
|
21
|
+
/** The session that submitted an action went away before the workspace decided it. */
|
|
22
|
+
| 'session_ended'
|
|
23
|
+
/** The URL the workspace asked for is not one this Gatekeeper serves. */
|
|
24
|
+
| 'no_such_resource'
|
|
25
|
+
/** Sharing an observation onward was refused, which is this Gatekeeper's default. */
|
|
26
|
+
| 'sharing_refused'
|
|
27
|
+
/** The deployment's entry module does not export something the OS object model needs. */
|
|
28
|
+
| 'missing_export';
|
|
17
29
|
/** A refusal the caller (or the OS deployment operating it) acts on. */
|
|
18
30
|
export declare class GatekeeperError extends Error {
|
|
19
31
|
readonly reason: GatekeeperReason;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAcA,uEAAuE;AACvE,qBAAa,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,mEAAmE;AACnE,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,cAAc,GACd,qBAAqB,GACrB,gBAAgB,GAChB,uBAAuB,GACvB,oBAAoB;AACtB,mFAAmF;GACjF,gBAAgB;AAClB,sEAAsE;GACpE,cAAc;AAChB,0EAA0E;GACxE,gBAAgB;AAClB,uFAAuF;GACrF,oBAAoB;AACtB,kFAAkF;GAChF,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAcA,uEAAuE;AACvE,qBAAa,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,mEAAmE;AACnE,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,cAAc,GACd,qBAAqB,GACrB,gBAAgB,GAChB,uBAAuB,GACvB,oBAAoB;AACtB,mFAAmF;GACjF,gBAAgB;AAClB,sEAAsE;GACpE,cAAc;AAChB,0EAA0E;GACxE,gBAAgB;AAClB,uFAAuF;GACrF,oBAAoB;AACtB,kFAAkF;GAChF,qBAAqB;AACvB,mFAAmF;GACjF,iBAAiB;AACnB,gGAAgG;GAC9F,gBAAgB;AAClB,sFAAsF;GACpF,eAAe;AACjB,yEAAyE;GACvE,kBAAkB;AACpB,qFAAqF;GACnF,iBAAiB;AACnB,yFAAyF;GACvF,gBAAgB,CAAA;AAEpB,wEAAwE;AACxE,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IAEjC,YAAY,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAIpD;CACF"}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,4FAA4F;AAC5F,+FAA+F;AAC/F,6FAA6F;AAC7F,mGAAmG;AACnG,mGAAmG;AACnG,2EAA2E;AAC3E,EAAE;AACF,gGAAgG;AAChG,kGAAkG;AAClG,iGAAiG;AACjG,oEAAoE;AAEpE,uEAAuE;AACvE,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,aAAa,CAAA;IAC3B,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,4FAA4F;AAC5F,+FAA+F;AAC/F,6FAA6F;AAC7F,mGAAmG;AACnG,mGAAmG;AACnG,2EAA2E;AAC3E,EAAE;AACF,gGAAgG;AAChG,kGAAkG;AAClG,iGAAiG;AACjG,oEAAoE;AAEpE,uEAAuE;AACvE,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,aAAa,CAAA;IAC3B,CAAC;CACF;AAiCD,wEAAwE;AACxE,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,MAAM,CAAkB;IAEjC,YAAY,MAAwB,EAAE,OAAe;QACnD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF"}
|
package/dist/gatekeeper.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type SessionGovernance } from './capability.js';
|
|
1
2
|
import { type GatekeeperEnv } from './env.js';
|
|
2
3
|
import { type Actor } from './keys.js';
|
|
3
|
-
import { type GatekeeperPolicy } from './policy/compile.js';
|
|
4
|
+
import { type CompiledTier, type GatekeeperPolicy } from './policy/compile.js';
|
|
4
5
|
import { type VerificationResult } from './webhook/signature.js';
|
|
5
6
|
/** Why a delivery was refused, drawn from the verifier so the two cannot drift. */
|
|
6
7
|
type RejectionReason = Extract<VerificationResult, {
|
|
@@ -40,7 +41,51 @@ export declare class Gatekeeper {
|
|
|
40
41
|
* The tier is resolved from the Gatekeeper's OWN policy, never from anything the caller sent:
|
|
41
42
|
* an agent that could name its tier would be its own authorization.
|
|
42
43
|
*/
|
|
43
|
-
capabilityFor(actor: Actor): import("capnweb").RpcTarget;
|
|
44
|
+
capabilityFor(actor: Actor, governance?: SessionGovernance): import("capnweb").RpcTarget;
|
|
45
|
+
/**
|
|
46
|
+
* The capability for an auto-provisioned Cloudflare OS account.
|
|
47
|
+
*
|
|
48
|
+
* A sibling of `capabilityFor` rather than a flag on it, because the two doors resolve a tier
|
|
49
|
+
* from different halves of the policy: `/rpc` names a person the OS asserts, and an account was
|
|
50
|
+
* minted here with no name at all. Everything after the resolution is the one implementation.
|
|
51
|
+
*/
|
|
52
|
+
capabilityForAccount(accountId: string, governance: SessionGovernance): import("capnweb").RpcTarget;
|
|
53
|
+
/**
|
|
54
|
+
* The compiled tier an actor holds, or a refusal naming what an operator has to change.
|
|
55
|
+
*
|
|
56
|
+
* Exposed beside `capabilityFor` because the OS object model asks about a tier without building
|
|
57
|
+
* a session from it: the resource's TypeScript types and its auto-approvable action kinds are
|
|
58
|
+
* both projections of the tier, and both are read before any session exists.
|
|
59
|
+
*/
|
|
60
|
+
tierFor(actorId: string): CompiledTier;
|
|
61
|
+
/**
|
|
62
|
+
* The tier an auto-provisioned Cloudflare OS account holds, or a refusal naming the knob.
|
|
63
|
+
*
|
|
64
|
+
* Separate from {@link tierFor} because the refusal has to name the right thing: a deployment
|
|
65
|
+
* that has not opted into OS discovery has not misconfigured anything, and telling its operator
|
|
66
|
+
* to add an actor to `grants` would be telling them to write a line for an id that did not exist
|
|
67
|
+
* when they were reading.
|
|
68
|
+
*/
|
|
69
|
+
tierForAccount(accountId: string): CompiledTier;
|
|
70
|
+
/**
|
|
71
|
+
* The tier EVERY auto-provisioned account falls to, asked without an account.
|
|
72
|
+
*
|
|
73
|
+
* The vendor is questioned before any account exists (its published session types are the ones a
|
|
74
|
+
* new account will get), and that question has an answer of its own. Asking it by minting a
|
|
75
|
+
* throwaway id would resolve the same tier and, when there is none, refuse by naming an
|
|
76
|
+
* `acct_…` that appears nowhere in the operator's policy.
|
|
77
|
+
*/
|
|
78
|
+
tierForNewAccount(): CompiledTier;
|
|
79
|
+
/**
|
|
80
|
+
* The tier NAME a policy nominates for auto-provisioned accounts, or `null`.
|
|
81
|
+
*
|
|
82
|
+
* The raw knob rather than the compiled tier, because the one caller that wants it is `/health`,
|
|
83
|
+
* reporting whether this deployment has opted into Cloudflare OS discovery at all. A refusal
|
|
84
|
+
* would be the wrong shape there: not having opted in is a state, not a fault.
|
|
85
|
+
*/
|
|
86
|
+
get autoProvisionedTierName(): string | null;
|
|
87
|
+
/** The origin of the cat-factory deployment this Gatekeeper is paired with. */
|
|
88
|
+
get deployment(): string;
|
|
44
89
|
/**
|
|
45
90
|
* Retire an actor: revoke every key this Gatekeeper minted for them, upstream and here.
|
|
46
91
|
*
|
package/dist/gatekeeper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gatekeeper.d.ts","sourceRoot":"","sources":["../src/gatekeeper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gatekeeper.d.ts","sourceRoot":"","sources":["../src/gatekeeper.ts"],"names":[],"mappings":"AAWA,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAEzD,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,WAAW,CAAA;AACjD,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAgBhF,mFAAmF;AACnF,KAAK,eAAe,GAAG,OAAO,CAAC,kBAAkB,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;AAE3E,oDAAoD;AACpD,MAAM,MAAM,eAAe,GACvB;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAChD;IAAE,OAAO,EAAE,aAAa,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5C;IACE,OAAO,EAAE,UAAU,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,MAAM,CAAA;CACvD,CAAA;AAEL,qBAAa,UAAU;;IAMrB,OAAO,eAiBN;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAEtE;IAED,mEAAmE;IACnE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAIxC;IAED;;;;;OAKG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,iBAAiB,+BAEzD;IAED;;;;;;OAMG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,+BAMpE;IAYD;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAUrC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAU9C;IAED;;;;;;;OAOG;IACH,iBAAiB,IAAI,YAAY,CAUhC;IAED;;;;;;OAMG;IACH,IAAI,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAE3C;IAED,+EAA+E;IAC/E,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;;;;OAKG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAEjF;IAED;;;;;;OAMG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CA2B1D;IAED;;;;;;;;;OASG;IACG,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA0B1E;CACF"}
|
package/dist/gatekeeper.js
CHANGED
|
@@ -12,11 +12,20 @@ import { buildCapability } from './capability.js';
|
|
|
12
12
|
import { requireVar } from './env.js';
|
|
13
13
|
import { GatekeeperError } from './errors.js';
|
|
14
14
|
import { KeyBroker } from './keys.js';
|
|
15
|
-
import { compilePolicy, tierForActor, } from './policy/compile.js';
|
|
15
|
+
import { autoProvisionedTier, compilePolicy, tierForAccount, tierForActor, } from './policy/compile.js';
|
|
16
16
|
import { cardEffectOf, readDelivery, SUBSCRIBED_CARD_TYPES } from './webhook/delivery.js';
|
|
17
17
|
import { verifyDelivery } from './webhook/signature.js';
|
|
18
18
|
/** Identifies this integration in the deployment's logs, beside the SDK's own version. */
|
|
19
19
|
const USER_AGENT = 'cat-factory-gatekeeper';
|
|
20
|
+
/**
|
|
21
|
+
* The one remedy both auto-provisioning refusals end on.
|
|
22
|
+
*
|
|
23
|
+
* Stated once because the two refusals differ only in what they could not do (open a session for a
|
|
24
|
+
* named account, describe the session a new one would get) and never in the fix.
|
|
25
|
+
*/
|
|
26
|
+
const AUTO_PROVISIONED_TIER_REMEDY = "Name a tier as the policy's autoProvisionedTier to turn Cloudflare OS discovery on; it is " +
|
|
27
|
+
'deliberately separate from defaultTier, because an account the workspace minted carries no ' +
|
|
28
|
+
'identity your grants could have named.';
|
|
20
29
|
export class Gatekeeper {
|
|
21
30
|
#env;
|
|
22
31
|
#policy;
|
|
@@ -61,13 +70,88 @@ export class Gatekeeper {
|
|
|
61
70
|
* The tier is resolved from the Gatekeeper's OWN policy, never from anything the caller sent:
|
|
62
71
|
* an agent that could name its tier would be its own authorization.
|
|
63
72
|
*/
|
|
64
|
-
capabilityFor(actor) {
|
|
65
|
-
|
|
73
|
+
capabilityFor(actor, governance) {
|
|
74
|
+
return this.#capability(actor, this.tierFor(actor.id), governance);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The capability for an auto-provisioned Cloudflare OS account.
|
|
78
|
+
*
|
|
79
|
+
* A sibling of `capabilityFor` rather than a flag on it, because the two doors resolve a tier
|
|
80
|
+
* from different halves of the policy: `/rpc` names a person the OS asserts, and an account was
|
|
81
|
+
* minted here with no name at all. Everything after the resolution is the one implementation.
|
|
82
|
+
*/
|
|
83
|
+
capabilityForAccount(accountId, governance) {
|
|
84
|
+
return this.#capability({ id: accountId, label: accountId }, this.tierForAccount(accountId), governance);
|
|
85
|
+
}
|
|
86
|
+
#capability(actor, tier, governance) {
|
|
87
|
+
return buildCapability({
|
|
88
|
+
actor,
|
|
89
|
+
tier,
|
|
90
|
+
keys: this.#keys,
|
|
91
|
+
state: this.#state,
|
|
92
|
+
...(governance ? { governance } : {}),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The compiled tier an actor holds, or a refusal naming what an operator has to change.
|
|
97
|
+
*
|
|
98
|
+
* Exposed beside `capabilityFor` because the OS object model asks about a tier without building
|
|
99
|
+
* a session from it: the resource's TypeScript types and its auto-approvable action kinds are
|
|
100
|
+
* both projections of the tier, and both are read before any session exists.
|
|
101
|
+
*/
|
|
102
|
+
tierFor(actorId) {
|
|
103
|
+
const tier = tierForActor(this.#policy, actorId);
|
|
66
104
|
if (tier === null) {
|
|
67
|
-
throw new GatekeeperError('unknown_actor', `No tier is granted to '${
|
|
105
|
+
throw new GatekeeperError('unknown_actor', `No tier is granted to '${actorId}'. Add them to this Gatekeeper's policy under ` +
|
|
68
106
|
'grants, or set a defaultTier if this deployment means every OS user to have one.');
|
|
69
107
|
}
|
|
70
|
-
return
|
|
108
|
+
return tier;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The tier an auto-provisioned Cloudflare OS account holds, or a refusal naming the knob.
|
|
112
|
+
*
|
|
113
|
+
* Separate from {@link tierFor} because the refusal has to name the right thing: a deployment
|
|
114
|
+
* that has not opted into OS discovery has not misconfigured anything, and telling its operator
|
|
115
|
+
* to add an actor to `grants` would be telling them to write a line for an id that did not exist
|
|
116
|
+
* when they were reading.
|
|
117
|
+
*/
|
|
118
|
+
tierForAccount(accountId) {
|
|
119
|
+
const tier = tierForAccount(this.#policy, accountId);
|
|
120
|
+
if (tier === null) {
|
|
121
|
+
throw new GatekeeperError('unknown_actor', 'This Gatekeeper serves no auto-provisioned accounts, so it cannot open a session for ' +
|
|
122
|
+
`'${accountId}'. ${AUTO_PROVISIONED_TIER_REMEDY}`);
|
|
123
|
+
}
|
|
124
|
+
return tier;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The tier EVERY auto-provisioned account falls to, asked without an account.
|
|
128
|
+
*
|
|
129
|
+
* The vendor is questioned before any account exists (its published session types are the ones a
|
|
130
|
+
* new account will get), and that question has an answer of its own. Asking it by minting a
|
|
131
|
+
* throwaway id would resolve the same tier and, when there is none, refuse by naming an
|
|
132
|
+
* `acct_…` that appears nowhere in the operator's policy.
|
|
133
|
+
*/
|
|
134
|
+
tierForNewAccount() {
|
|
135
|
+
const tier = autoProvisionedTier(this.#policy);
|
|
136
|
+
if (tier === null) {
|
|
137
|
+
throw new GatekeeperError('unknown_actor', 'This Gatekeeper serves no auto-provisioned accounts, so there is no session for it to ' +
|
|
138
|
+
`describe. ${AUTO_PROVISIONED_TIER_REMEDY}`);
|
|
139
|
+
}
|
|
140
|
+
return tier;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The tier NAME a policy nominates for auto-provisioned accounts, or `null`.
|
|
144
|
+
*
|
|
145
|
+
* The raw knob rather than the compiled tier, because the one caller that wants it is `/health`,
|
|
146
|
+
* reporting whether this deployment has opted into Cloudflare OS discovery at all. A refusal
|
|
147
|
+
* would be the wrong shape there: not having opted in is a state, not a fault.
|
|
148
|
+
*/
|
|
149
|
+
get autoProvisionedTierName() {
|
|
150
|
+
return this.#policy.autoProvisionedTier;
|
|
151
|
+
}
|
|
152
|
+
/** The origin of the cat-factory deployment this Gatekeeper is paired with. */
|
|
153
|
+
get deployment() {
|
|
154
|
+
return requireVar(this.#env, 'CAT_FACTORY_BASE_URL');
|
|
71
155
|
}
|
|
72
156
|
/**
|
|
73
157
|
* Retire an actor: revoke every key this Gatekeeper minted for them, upstream and here.
|
package/dist/gatekeeper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gatekeeper.js","sourceRoot":"","sources":["../src/gatekeeper.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,EAAE;AACF,0FAA0F;AAC1F,6FAA6F;AAC7F,EAAE;AACF,+FAA+F;AAC/F,6FAA6F;AAC7F,2FAA2F;AAC3F,cAAc;AAEd,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"gatekeeper.js","sourceRoot":"","sources":["../src/gatekeeper.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,5 +7,18 @@ export { KeyBroker, type Actor, type KeyBrokerDependencies, type LeasedClient }
|
|
|
7
7
|
export { answerCard, assertAnswerable, describeStale, pendingParks, type AnswerInput, type AnswerOutcome, type BindingInvoker, type DecisionListShape, type PendingPark, } from './approvals.js';
|
|
8
8
|
export { cardEffectOf, dispositionOf, PARKED_DECISION_CARD_TYPES, readDelivery, SUBSCRIBED_CARD_TYPES, type CardDisposition, type Delivery, } from './webhook/delivery.js';
|
|
9
9
|
export { DEFAULT_MAX_SKEW_MS, verifyDelivery, type VerificationResult, } from './webhook/signature.js';
|
|
10
|
+
export { createGatekeeperVendor } from './os/vendor.js';
|
|
11
|
+
export { createGatekeeperAccount, createGatekeeperVerifier, type AccountProps, } from './os/account.js';
|
|
12
|
+
export { createGatekeeperResource } from './os/resource.js';
|
|
13
|
+
export { ResourceCore, type ResourceProps } from './os/resource-core.js';
|
|
14
|
+
export { OS_EXPORTS, missingOsExports, type OsExportRole } from './os/exports.js';
|
|
15
|
+
export { describeDiscoverability, type DiscoverabilityReport, type DiscoveryBlocker, type DiscoveryBlockerReason, } from './os/discoverability.js';
|
|
16
|
+
export { supportedResourceFor } from './os/resources.js';
|
|
17
|
+
export { SESSION_INTERFACE_NAME, renderTierSessionTypes } from './os/session-types.js';
|
|
18
|
+
export { ActionLedger, holdQueue, queueGovernance, type LedgerSession } from './os/queue.js';
|
|
19
|
+
export { actionKindOf, describeAction, describeObservation, type CallSubject, } from './os/descriptions.js';
|
|
20
|
+
export { fenced } from './markdown.js';
|
|
21
|
+
export type { AccountDescription, AccountEntrypoint, ActionDescription, ActionKind, ApprovalQueue, AvatarImage, ObservationAuthorizer, ObservationDescription, ResourceDescription, ResourceObject, SupportedResource, VendorDescription, VendorEntrypoint, VerifierEntrypoint, } from './os/protocol.js';
|
|
22
|
+
export type { SessionGovernance } from './capability.js';
|
|
10
23
|
export * from './policy/index.js';
|
|
11
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAIlE,OAAO,EACL,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EACL,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AAEhG,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,QAAQ,GACd,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAIlE,OAAO,EACL,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EACL,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AAEhG,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,QAAQ,GACd,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAA;AAM/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACjF,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACtF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EACL,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAIxD,cAAc,mBAAmB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,21 @@ export { KeyBroker } from './keys.js';
|
|
|
17
17
|
export { answerCard, assertAnswerable, describeStale, pendingParks, } from './approvals.js';
|
|
18
18
|
export { cardEffectOf, dispositionOf, PARKED_DECISION_CARD_TYPES, readDelivery, SUBSCRIBED_CARD_TYPES, } from './webhook/delivery.js';
|
|
19
19
|
export { DEFAULT_MAX_SKEW_MS, verifyDelivery, } from './webhook/signature.js';
|
|
20
|
+
// The Cloudflare OS object model: a second door onto the rooms above, never a fork of them. The
|
|
21
|
+
// workspace discovers a `GatekeeperVendor` entrypoint over a service binding, mints an account,
|
|
22
|
+
// binds the paired workspace as a resource, and opens a session whose every call passes through the
|
|
23
|
+
// approval queue it supplied. `/rpc` and the admin routes are unchanged and still bearer-gated.
|
|
24
|
+
export { createGatekeeperVendor } from './os/vendor.js';
|
|
25
|
+
export { createGatekeeperAccount, createGatekeeperVerifier, } from './os/account.js';
|
|
26
|
+
export { createGatekeeperResource } from './os/resource.js';
|
|
27
|
+
export { ResourceCore } from './os/resource-core.js';
|
|
28
|
+
export { OS_EXPORTS, missingOsExports } from './os/exports.js';
|
|
29
|
+
export { describeDiscoverability, } from './os/discoverability.js';
|
|
30
|
+
export { supportedResourceFor } from './os/resources.js';
|
|
31
|
+
export { SESSION_INTERFACE_NAME, renderTierSessionTypes } from './os/session-types.js';
|
|
32
|
+
export { ActionLedger, holdQueue, queueGovernance } from './os/queue.js';
|
|
33
|
+
export { actionKindOf, describeAction, describeObservation, } from './os/descriptions.js';
|
|
34
|
+
export { fenced } from './markdown.js';
|
|
20
35
|
// The policy vocabulary, also reachable on its own at `@cat-factory/gatekeeper-worker/policy` for
|
|
21
36
|
// a policy file that should not have to load a Worker runtime to be read or tested.
|
|
22
37
|
export * from './policy/index.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,uFAAuF;AACvF,EAAE;AACF,mGAAmG;AACnG,kGAAkG;AAClG,kGAAkG;AAClG,iGAAiG;AACjG,wCAAwC;AAExC,OAAO,EAAE,sBAAsB,EAAgC,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAElE,0FAA0F;AAC1F,6FAA6F;AAC7F,OAAO,EACL,eAAe,GAQhB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAA;AAC1D,OAAO,EACL,eAAe,GAIhB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,SAAS,EAA6D,MAAM,WAAW,CAAA;AAEhG,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,YAAY,GAMb,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,qBAAqB,GAGtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,cAAc,GAEf,MAAM,wBAAwB,CAAA;AAE/B,kGAAkG;AAClG,oFAAoF;AACpF,cAAc,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,uFAAuF;AACvF,EAAE;AACF,mGAAmG;AACnG,kGAAkG;AAClG,kGAAkG;AAClG,iGAAiG;AACjG,wCAAwC;AAExC,OAAO,EAAE,sBAAsB,EAAgC,MAAM,aAAa,CAAA;AAClF,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAElE,0FAA0F;AAC1F,6FAA6F;AAC7F,OAAO,EACL,eAAe,GAQhB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAsB,MAAM,UAAU,CAAA;AAC1D,OAAO,EACL,eAAe,GAIhB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,SAAS,EAA6D,MAAM,WAAW,CAAA;AAEhG,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,YAAY,GAMb,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,qBAAqB,GAGtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,cAAc,GAEf,MAAM,wBAAwB,CAAA;AAE/B,gGAAgG;AAChG,gGAAgG;AAChG,oGAAoG;AACpG,gGAAgG;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EACL,uBAAuB,EACvB,wBAAwB,GAEzB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAsB,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAqB,MAAM,iBAAiB,CAAA;AACjF,OAAO,EACL,uBAAuB,GAIxB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACtF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAsB,MAAM,eAAe,CAAA;AAC5F,OAAO,EACL,YAAY,EACZ,cAAc,EACd,mBAAmB,GAEpB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAmBtC,kGAAkG;AAClG,oFAAoF;AACpF,cAAc,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fence a payload so it cannot break out of the code block that holds it.
|
|
3
|
+
*
|
|
4
|
+
* Sized one backtick longer than the longest run the payload contains, which is what makes it
|
|
5
|
+
* total: a payload holding ```` closes a ``` fence and everything after it, including the rest of
|
|
6
|
+
* the description, renders as prose the reader takes for ours.
|
|
7
|
+
*
|
|
8
|
+
* The language tag is the caller's, because a JSON argument bag and a free-text title are both
|
|
9
|
+
* fenced and only one of them is JSON.
|
|
10
|
+
*/
|
|
11
|
+
export declare function fenced(payload: string, language?: string): string;
|
|
12
|
+
//# sourceMappingURL=markdown.d.ts.map
|