@zackbart/connecta 0.8.0 → 0.9.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 +128 -0
- package/README.md +31 -55
- package/SECURITY.md +5 -11
- package/dist/activity.d.ts +0 -8
- package/dist/activity.d.ts.map +1 -1
- package/dist/activity.js +0 -1
- package/dist/activity.js.map +1 -1
- package/dist/auth/bearer.d.ts +1 -7
- package/dist/auth/bearer.d.ts.map +1 -1
- package/dist/auth/bearer.js +2 -23
- package/dist/auth/bearer.js.map +1 -1
- package/dist/auth/clerk.d.ts +2 -11
- package/dist/auth/clerk.d.ts.map +1 -1
- package/dist/auth/clerk.js +31 -46
- package/dist/auth/clerk.js.map +1 -1
- package/dist/auth/downstream-oauth.d.ts +15 -6
- package/dist/auth/downstream-oauth.d.ts.map +1 -1
- package/dist/auth/downstream-oauth.js +60 -11
- package/dist/auth/downstream-oauth.js.map +1 -1
- package/dist/call-admission.d.ts.map +1 -1
- package/dist/call-admission.js +0 -1
- package/dist/call-admission.js.map +1 -1
- package/dist/catalog-service.d.ts +1 -2
- package/dist/catalog-service.d.ts.map +1 -1
- package/dist/catalog-service.js +12 -18
- package/dist/catalog-service.js.map +1 -1
- package/dist/catalog.d.ts +6 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +51 -0
- package/dist/catalog.js.map +1 -1
- package/dist/connectors/remote-mcp.d.ts +1 -1
- package/dist/connectors/remote-mcp.d.ts.map +1 -1
- package/dist/connectors/remote-mcp.js +73 -71
- package/dist/connectors/remote-mcp.js.map +1 -1
- package/dist/errors.d.ts +19 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -1
- package/dist/execute.d.ts +4 -9
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +41 -20
- package/dist/execute.js.map +1 -1
- package/dist/executor-result.js +1 -1
- package/dist/executor-result.js.map +1 -1
- package/dist/index.d.ts +3 -82
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -90
- package/dist/index.js.map +1 -1
- package/dist/invocation.d.ts +5 -0
- package/dist/invocation.d.ts.map +1 -1
- package/dist/invocation.js +46 -10
- package/dist/invocation.js.map +1 -1
- package/dist/meta-tools.d.ts +4 -12
- package/dist/meta-tools.d.ts.map +1 -1
- package/dist/meta-tools.js +119 -169
- package/dist/meta-tools.js.map +1 -1
- package/dist/operator-ui/generated.d.ts +2 -2
- package/dist/operator-ui/generated.d.ts.map +1 -1
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/generated.js.map +1 -1
- package/dist/operator-ui/model.d.ts +1 -22
- package/dist/operator-ui/model.d.ts.map +1 -1
- package/dist/operator-ui/model.js.map +1 -1
- package/dist/registry.d.ts +11 -178
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +52 -330
- package/dist/registry.js.map +1 -1
- package/dist/retired-toolkits.d.ts +3 -0
- package/dist/retired-toolkits.d.ts.map +1 -0
- package/dist/retired-toolkits.js +9 -0
- package/dist/retired-toolkits.js.map +1 -0
- package/dist/routes/activity.d.ts.map +1 -1
- package/dist/routes/activity.js +2 -5
- package/dist/routes/activity.js.map +1 -1
- package/dist/routes/credentials.d.ts.map +1 -1
- package/dist/routes/credentials.js +1 -12
- package/dist/routes/credentials.js.map +1 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +94 -188
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/oauth.d.ts.map +1 -1
- package/dist/routes/oauth.js +3 -8
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/shared.d.ts +9 -30
- package/dist/routes/shared.d.ts.map +1 -1
- package/dist/routes/shared.js +10 -69
- package/dist/routes/shared.js.map +1 -1
- package/dist/routes/ui.d.ts.map +1 -1
- package/dist/routes/ui.js +4 -10
- package/dist/routes/ui.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -31
- package/dist/server.js.map +1 -1
- package/dist/skills.d.ts +3 -6
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +9 -38
- package/dist/skills.js.map +1 -1
- package/dist/timeout.d.ts.map +1 -1
- package/dist/timeout.js +2 -4
- package/dist/timeout.js.map +1 -1
- package/dist/types.d.ts +8 -61
- package/dist/types.d.ts.map +1 -1
- package/dist/ui.d.ts +1 -2
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +5 -35
- package/dist/ui.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
- package/src/activity.ts +0 -9
- package/src/auth/bearer.ts +3 -32
- package/src/auth/clerk.ts +35 -48
- package/src/auth/downstream-oauth.ts +106 -24
- package/src/call-admission.ts +0 -1
- package/src/catalog-service.ts +23 -23
- package/src/catalog.ts +55 -0
- package/src/connectors/remote-mcp.ts +106 -86
- package/src/errors.ts +22 -0
- package/src/execute.ts +43 -24
- package/src/executor-result.ts +1 -1
- package/src/index.ts +24 -208
- package/src/invocation.ts +63 -10
- package/src/meta-tools.ts +139 -187
- package/src/operator-ui/browser.css +1 -54
- package/src/operator-ui/browser.ts +16 -150
- package/src/operator-ui/generated.ts +2 -2
- package/src/operator-ui/model.ts +1 -23
- package/src/registry.ts +59 -429
- package/src/retired-toolkits.ts +14 -0
- package/src/routes/activity.ts +1 -6
- package/src/routes/credentials.ts +0 -12
- package/src/routes/mcp.ts +110 -230
- package/src/routes/oauth.ts +2 -8
- package/src/routes/shared.ts +10 -100
- package/src/routes/ui.ts +2 -12
- package/src/server.ts +1 -31
- package/src/skills.ts +9 -38
- package/src/timeout.ts +2 -4
- package/src/types.ts +11 -62
- package/src/ui.ts +9 -46
- package/src/version.ts +1 -1
- package/dist/credential-health.d.ts +0 -205
- package/dist/credential-health.d.ts.map +0 -1
- package/dist/credential-health.js +0 -610
- package/dist/credential-health.js.map +0 -1
- package/dist/toolkits.d.ts +0 -124
- package/dist/toolkits.d.ts.map +0 -1
- package/dist/toolkits.js +0 -322
- package/dist/toolkits.js.map +0 -1
- package/src/credential-health.ts +0 -835
- package/src/toolkits.ts +0 -461
package/dist/toolkits.d.ts
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import type { Connector, InboundAuth, ToolkitBinding } from "./types.js";
|
|
2
|
-
/** Toolkit names share the connector-id grammar: URL-safe, no separators. */
|
|
3
|
-
export declare const TOOLKIT_NAME_RE: RegExp;
|
|
4
|
-
/** One named scope, declared in `ConnectaConfig.toolkits` (config as code). */
|
|
5
|
-
export interface ToolkitDefinition {
|
|
6
|
-
/** Connector ids this toolkit may see. Required, and at least one. */
|
|
7
|
-
connectors: string[];
|
|
8
|
-
/**
|
|
9
|
-
* Optional finer grain: full tool addresses (`"<connectorId>.<toolName>"`).
|
|
10
|
-
* Naming ANY address of a connector narrows that connector to exactly the
|
|
11
|
-
* addresses named; connectors with no entry here keep their whole tool list.
|
|
12
|
-
*/
|
|
13
|
-
includeTools?: string[];
|
|
14
|
-
/** Optional tool addresses to hide, applied after `includeTools`. */
|
|
15
|
-
excludeTools?: string[];
|
|
16
|
-
/** Operator note. Never sent to clients — this is documentation for config. */
|
|
17
|
-
description?: string;
|
|
18
|
-
}
|
|
19
|
-
/** `ConnectaConfig.toolkits` — toolkit name → definition. */
|
|
20
|
-
export type ToolkitConfig = Record<string, ToolkitDefinition>;
|
|
21
|
-
/** A validated toolkit: the visibility predicate the scoped registry consults. */
|
|
22
|
-
export interface Toolkit {
|
|
23
|
-
readonly name: string;
|
|
24
|
-
readonly description?: string;
|
|
25
|
-
/**
|
|
26
|
-
* The validated config this scope came from. Kept as immutable data so
|
|
27
|
-
* deployment-wide operator surfaces can explain the running configuration
|
|
28
|
-
* without inventing a second source of truth.
|
|
29
|
-
*/
|
|
30
|
-
readonly connectors: readonly string[];
|
|
31
|
-
readonly includeTools: readonly string[];
|
|
32
|
-
readonly excludeTools: readonly string[];
|
|
33
|
-
/** True when `connectorId` is inside this toolkit's scope. */
|
|
34
|
-
hasConnector(connectorId: string): boolean;
|
|
35
|
-
/** True when `<connectorId>.<toolName>` is inside this toolkit's scope. */
|
|
36
|
-
hasTool(connectorId: string, toolName: string): boolean;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Split `"<connectorId>.<toolName>"` on the FIRST dot — connector ids contain
|
|
40
|
-
* no dots, so a downstream tool name may. Returns null for a malformed address.
|
|
41
|
-
*/
|
|
42
|
-
export declare function splitAddress(address: string): {
|
|
43
|
-
connectorId: string;
|
|
44
|
-
toolName: string;
|
|
45
|
-
} | null;
|
|
46
|
-
/**
|
|
47
|
-
* Validate every declared toolkit against the connector set. Returns undefined
|
|
48
|
-
* when no toolkits are configured, so an existing deployment keeps exactly its
|
|
49
|
-
* current (unscoped) behavior.
|
|
50
|
-
*/
|
|
51
|
-
export declare function resolveToolkits(toolkits: ToolkitConfig | undefined, connectors: readonly Connector[]): ReadonlyMap<string, Toolkit> | undefined;
|
|
52
|
-
/**
|
|
53
|
-
* The binding half of an inbound-auth adapter's options — the shape every
|
|
54
|
-
* shipped adapter (`bearerToken`, `clerkAuth`) mixes into its own options so an
|
|
55
|
-
* operator writes one thing in one style, next to the credential it binds.
|
|
56
|
-
*/
|
|
57
|
-
export interface ToolkitBindingOptions {
|
|
58
|
-
/**
|
|
59
|
-
* Toolkit names this credential may select with `?toolkit=<name>`. Present ⇒
|
|
60
|
-
* the identity is BOUND: any other toolkit, and (unless `unscoped`) a
|
|
61
|
-
* connection with no `?toolkit=`, is refused at connect time. Absent ⇒
|
|
62
|
-
* unbound, exactly as before bindings existed.
|
|
63
|
-
*/
|
|
64
|
-
toolkits?: readonly string[];
|
|
65
|
-
/**
|
|
66
|
-
* Also allow a connection with no `?toolkit=` (the full registry, and the
|
|
67
|
-
* deployment-wide operator surfaces). Only meaningful beside `toolkits`.
|
|
68
|
-
*/
|
|
69
|
-
unscoped?: boolean;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Validate one adapter's binding options into a `ToolkitBinding`, or undefined
|
|
73
|
-
* when the adapter declares none. Structural mistakes THROW where the operator
|
|
74
|
-
* wrote them (adapter construction), for the same reason toolkit definitions do:
|
|
75
|
-
* a binding that does not say what its author meant is worse than none, because
|
|
76
|
-
* it is invisible until the day it denies — or admits — the wrong caller.
|
|
77
|
-
*
|
|
78
|
-
* Names are only checked against the *grammar* here; cross-checking them
|
|
79
|
-
* against the configured toolkits happens in `validateToolkitBindings`, which
|
|
80
|
-
* runs in `createConnecta` where both halves are finally in scope.
|
|
81
|
-
*/
|
|
82
|
-
export declare function resolveToolkitBinding(source: string, options: ToolkitBindingOptions): ToolkitBinding | undefined;
|
|
83
|
-
/**
|
|
84
|
-
* Resolve the binding one admitted identity is actually held to, from the
|
|
85
|
-
* provider's static declaration and whatever its `authorize` returned.
|
|
86
|
-
*
|
|
87
|
-
* - Neither ⇒ unbound (undefined), the pre-binding behavior.
|
|
88
|
-
* - Declaration only ⇒ the declaration.
|
|
89
|
-
* - Per-identity only ⇒ that binding, validated. This is the custom-adapter
|
|
90
|
-
* seam: a provider that declares nothing is asserting it resolves membership
|
|
91
|
-
* itself, so there is nothing to check it against.
|
|
92
|
-
* - Both ⇒ the **intersection**. The declaration is a CEILING, not a default: an
|
|
93
|
-
* adapter that maps a user-writable IdP claim to toolkits must not be able to
|
|
94
|
-
* widen the credential's own binding, which would turn "support token" into
|
|
95
|
-
* "any toolkit, plus the full registry" for anyone who can set that claim.
|
|
96
|
-
* Narrowing is fine and useful (per-user subsets of the team's view).
|
|
97
|
-
*
|
|
98
|
-
* A malformed binding on either side is not silently ignored — it returns
|
|
99
|
-
* `{ ok: false }` and the caller refuses the request, because the alternative
|
|
100
|
-
* (dropping it) is the fail-open reading.
|
|
101
|
-
*/
|
|
102
|
-
export declare function resolveIdentityBinding(declared: unknown, perIdentity: unknown): {
|
|
103
|
-
ok: true;
|
|
104
|
-
binding?: ToolkitBinding;
|
|
105
|
-
} | {
|
|
106
|
-
ok: false;
|
|
107
|
-
reason: string;
|
|
108
|
-
};
|
|
109
|
-
/**
|
|
110
|
-
* Cross-check every statically declared binding against the deployment's
|
|
111
|
-
* toolkits, in `createConnecta`. A name that no toolkit declares is a typo, and
|
|
112
|
-
* a typo here fails CLOSED — the credential would be refused every connection
|
|
113
|
-
* with a 403 the client reads as a transport failure — so it throws at
|
|
114
|
-
* construction rather than becoming a support ticket. A structurally malformed
|
|
115
|
-
* declaration (only reachable from a hand-written `InboundAuth`, since the
|
|
116
|
-
* shipped adapters validate their own options) throws here too, rather than
|
|
117
|
-
* waiting to refuse every request at runtime.
|
|
118
|
-
*
|
|
119
|
-
* Bindings a provider mints per-identity (`AuthResult.toolkitBinding`) do not
|
|
120
|
-
* exist yet and cannot be checked here; they are validated on arrival and capped
|
|
121
|
-
* by the declaration (`resolveIdentityBinding`).
|
|
122
|
-
*/
|
|
123
|
-
export declare function validateToolkitBindings(auth: readonly InboundAuth[], toolkits: ReadonlyMap<string, Toolkit> | undefined): void;
|
|
124
|
-
//# sourceMappingURL=toolkits.d.ts.map
|
package/dist/toolkits.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolkits.d.ts","sourceRoot":"","sources":["../src/toolkits.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,6EAA6E;AAC7E,eAAO,MAAM,eAAe,QAAkB,CAAC;AAE/C,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6DAA6D;AAC7D,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAE9D,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,8DAA8D;IAC9D,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C,2EAA2E;IAC3E,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CACzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,GACd;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAOlD;AAmID;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,UAAU,EAAE,SAAS,SAAS,EAAE,GAC/B,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAsB1C;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,GAC7B,cAAc,GAAG,SAAS,CA2C5B;AA4CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,OAAO,GAElB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,cAAc,CAAA;CAAE,GACtC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoChC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACjD,IAAI,CA2BN"}
|
package/dist/toolkits.js
DELETED
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
// Toolkits: named, operator-defined scoped views over one deployment's
|
|
2
|
-
// registry, selected per client connection with `?toolkit=<name>` on /mcp.
|
|
3
|
-
//
|
|
4
|
-
// A connecta deployment belongs to an ORG; a toolkit is the view a GROUP OF
|
|
5
|
-
// TEAM MEMBERS inside that org gets — a "support" toolkit seeing Zendesk and
|
|
6
|
-
// Notion, an "exec" toolkit that also sees Gmail. This module only *defines and
|
|
7
|
-
// validates* scopes and the identity bindings that gate them. Enforcement lives
|
|
8
|
-
// in two places, each with one job:
|
|
9
|
-
//
|
|
10
|
-
// - WHICH toolkit an identity may open: the connect-time binding check in
|
|
11
|
-
// `resolveToolkitScope` (src/server.ts), run after the auth gate and before
|
|
12
|
-
// any scoped registry exists.
|
|
13
|
-
// - WHAT a selected toolkit may see: `ScopedRegistry` (src/registry.ts),
|
|
14
|
-
// which every meta-tool inherits through `RegistryView`.
|
|
15
|
-
/** Toolkit names share the connector-id grammar: URL-safe, no separators. */
|
|
16
|
-
export const TOOLKIT_NAME_RE = /^[a-z0-9_-]+$/;
|
|
17
|
-
/**
|
|
18
|
-
* Split `"<connectorId>.<toolName>"` on the FIRST dot — connector ids contain
|
|
19
|
-
* no dots, so a downstream tool name may. Returns null for a malformed address.
|
|
20
|
-
*/
|
|
21
|
-
export function splitAddress(address) {
|
|
22
|
-
const dot = address.indexOf(".");
|
|
23
|
-
if (dot <= 0 || dot === address.length - 1)
|
|
24
|
-
return null;
|
|
25
|
-
return {
|
|
26
|
-
connectorId: address.slice(0, dot),
|
|
27
|
-
toolName: address.slice(dot + 1),
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
/** Group tool addresses by connector id, validating each against the toolkit. */
|
|
31
|
-
function toolFilter(name, addresses, connectorIds, staticTools, field) {
|
|
32
|
-
const byConnector = new Map();
|
|
33
|
-
if (addresses !== undefined && !Array.isArray(addresses)) {
|
|
34
|
-
// A bare string would otherwise iterate character by character and produce
|
|
35
|
-
// a stream of confusing address errors; anything else would throw "not
|
|
36
|
-
// iterable" from deep inside the loop. Name the field instead.
|
|
37
|
-
throw new Error(`Toolkit "${name}" ${field} must be an array of "<connectorId>.<toolName>" addresses.`);
|
|
38
|
-
}
|
|
39
|
-
if (addresses !== undefined &&
|
|
40
|
-
addresses.length === 0 &&
|
|
41
|
-
field === "includeTools") {
|
|
42
|
-
// An empty allowlist reads as "only these tools" but would behave as "all
|
|
43
|
-
// of them" — the one shape here that fails OPEN. (An empty excludeTools is
|
|
44
|
-
// an honest no-op and is allowed.)
|
|
45
|
-
throw new Error(`Toolkit "${name}" has an empty includeTools: remove it to expose every tool, or list the addresses this toolkit may use.`);
|
|
46
|
-
}
|
|
47
|
-
for (const address of addresses ?? []) {
|
|
48
|
-
const parts = splitAddress(address);
|
|
49
|
-
if (!parts) {
|
|
50
|
-
throw new Error(`Toolkit "${name}" ${field} entry "${address}" is not a tool address: expected "<connectorId>.<toolName>".`);
|
|
51
|
-
}
|
|
52
|
-
if (!connectorIds.has(parts.connectorId)) {
|
|
53
|
-
// A typo here would silently do nothing, quietly widening the scope the
|
|
54
|
-
// operator believes they wrote. Fail at construction instead.
|
|
55
|
-
throw new Error(`Toolkit "${name}" ${field} entry "${address}" names connector "${parts.connectorId}", which is not in this toolkit's connectors list.`);
|
|
56
|
-
}
|
|
57
|
-
// Static-only, exactly like the registry's convention checks: an in-code
|
|
58
|
-
// connector's tool list is known now, so a misspelled name — an exclude
|
|
59
|
-
// that silently excludes nothing — is caught. Remote catalogs are fetched
|
|
60
|
-
// lazily over the network and cannot be checked at construction.
|
|
61
|
-
const known = staticTools.get(parts.connectorId);
|
|
62
|
-
if (known && !known.has(parts.toolName)) {
|
|
63
|
-
throw new Error(`Toolkit "${name}" ${field} entry "${address}" names no tool on connector "${parts.connectorId}".`);
|
|
64
|
-
}
|
|
65
|
-
const tools = byConnector.get(parts.connectorId) ?? new Set();
|
|
66
|
-
tools.add(parts.toolName);
|
|
67
|
-
byConnector.set(parts.connectorId, tools);
|
|
68
|
-
}
|
|
69
|
-
return byConnector;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Validate one toolkit definition against the deployment's connectors.
|
|
73
|
-
*
|
|
74
|
-
* Structural mistakes THROW at construction rather than warn: a typo'd id in
|
|
75
|
-
* an allowlist is a scope the operator did not write, and a scope nobody wrote
|
|
76
|
-
* is not one an operator can reason about. (A definition scopes visibility only;
|
|
77
|
-
* WHICH identity may select it is the separate binding below — see the module
|
|
78
|
-
* header and documentation/toolkits.md.) Tool names are checked only for connectors that expose
|
|
79
|
-
* `staticTools` (i.e. `api()`); a remote connector's catalog is fetched lazily
|
|
80
|
-
* over the network and is unknown at construction time.
|
|
81
|
-
*/
|
|
82
|
-
function resolveToolkit(name, definition, known, staticTools) {
|
|
83
|
-
if (!TOOLKIT_NAME_RE.test(name)) {
|
|
84
|
-
throw new Error(`Invalid toolkit name "${name}": must match ${TOOLKIT_NAME_RE.source}`);
|
|
85
|
-
}
|
|
86
|
-
if (!Array.isArray(definition.connectors) ||
|
|
87
|
-
definition.connectors.length === 0) {
|
|
88
|
-
throw new Error(`Toolkit "${name}" selects no connectors: list at least one connector id in "connectors".`);
|
|
89
|
-
}
|
|
90
|
-
const connectorIds = new Set();
|
|
91
|
-
for (const id of definition.connectors) {
|
|
92
|
-
if (!known.has(id)) {
|
|
93
|
-
throw new Error(`Toolkit "${name}" references unknown connector "${id}".`);
|
|
94
|
-
}
|
|
95
|
-
connectorIds.add(id);
|
|
96
|
-
}
|
|
97
|
-
const includes = toolFilter(name, definition.includeTools, connectorIds, staticTools, "includeTools");
|
|
98
|
-
const excludes = toolFilter(name, definition.excludeTools, connectorIds, staticTools, "excludeTools");
|
|
99
|
-
return {
|
|
100
|
-
name,
|
|
101
|
-
...(definition.description ? { description: definition.description } : {}),
|
|
102
|
-
connectors: Object.freeze([...connectorIds]),
|
|
103
|
-
includeTools: Object.freeze([...(definition.includeTools ?? [])]),
|
|
104
|
-
excludeTools: Object.freeze([...(definition.excludeTools ?? [])]),
|
|
105
|
-
hasConnector: (connectorId) => connectorIds.has(connectorId),
|
|
106
|
-
hasTool: (connectorId, toolName) => {
|
|
107
|
-
if (!connectorIds.has(connectorId))
|
|
108
|
-
return false;
|
|
109
|
-
const include = includes.get(connectorId);
|
|
110
|
-
if (include && !include.has(toolName))
|
|
111
|
-
return false;
|
|
112
|
-
return !excludes.get(connectorId)?.has(toolName);
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Validate every declared toolkit against the connector set. Returns undefined
|
|
118
|
-
* when no toolkits are configured, so an existing deployment keeps exactly its
|
|
119
|
-
* current (unscoped) behavior.
|
|
120
|
-
*/
|
|
121
|
-
export function resolveToolkits(toolkits, connectors) {
|
|
122
|
-
if (!toolkits)
|
|
123
|
-
return undefined;
|
|
124
|
-
// Object.entries (not a keyed lookup) so no config key — `__proto__` and
|
|
125
|
-
// friends included — can ever resolve through the prototype chain. Names are
|
|
126
|
-
// then held in a Map, which has no prototype to pollute.
|
|
127
|
-
const entries = Object.entries(toolkits);
|
|
128
|
-
if (entries.length === 0)
|
|
129
|
-
return undefined;
|
|
130
|
-
const known = new Set(connectors.map((connector) => connector.id));
|
|
131
|
-
const staticTools = new Map();
|
|
132
|
-
for (const connector of connectors) {
|
|
133
|
-
if (connector.staticTools) {
|
|
134
|
-
staticTools.set(connector.id, new Set(connector.staticTools.map((tool) => tool.name)));
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const resolved = new Map();
|
|
138
|
-
for (const [name, definition] of entries) {
|
|
139
|
-
resolved.set(name, resolveToolkit(name, definition, known, staticTools));
|
|
140
|
-
}
|
|
141
|
-
return resolved;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Validate one adapter's binding options into a `ToolkitBinding`, or undefined
|
|
145
|
-
* when the adapter declares none. Structural mistakes THROW where the operator
|
|
146
|
-
* wrote them (adapter construction), for the same reason toolkit definitions do:
|
|
147
|
-
* a binding that does not say what its author meant is worse than none, because
|
|
148
|
-
* it is invisible until the day it denies — or admits — the wrong caller.
|
|
149
|
-
*
|
|
150
|
-
* Names are only checked against the *grammar* here; cross-checking them
|
|
151
|
-
* against the configured toolkits happens in `validateToolkitBindings`, which
|
|
152
|
-
* runs in `createConnecta` where both halves are finally in scope.
|
|
153
|
-
*/
|
|
154
|
-
export function resolveToolkitBinding(source, options) {
|
|
155
|
-
const { toolkits, unscoped } = options;
|
|
156
|
-
if (toolkits === undefined) {
|
|
157
|
-
if (unscoped !== undefined) {
|
|
158
|
-
// `unscoped` alone reads like a permission but grants nothing an unbound
|
|
159
|
-
// identity does not already have, so it is almost certainly a half-written
|
|
160
|
-
// binding — the one shape here that would silently fail OPEN.
|
|
161
|
-
throw new Error(`${source}: \`unscoped\` only means something beside \`toolkits\`. ` +
|
|
162
|
-
"List the toolkits this credential may open, or drop `unscoped` to " +
|
|
163
|
-
"leave the credential unbound.");
|
|
164
|
-
}
|
|
165
|
-
return undefined;
|
|
166
|
-
}
|
|
167
|
-
if (!Array.isArray(toolkits)) {
|
|
168
|
-
throw new Error(`${source}: \`toolkits\` must be an array of toolkit names.`);
|
|
169
|
-
}
|
|
170
|
-
const names = [];
|
|
171
|
-
for (const name of toolkits) {
|
|
172
|
-
if (typeof name !== "string" || !TOOLKIT_NAME_RE.test(name)) {
|
|
173
|
-
// A name outside the grammar can never match a declared toolkit, so this
|
|
174
|
-
// would bind the credential to nothing selectable.
|
|
175
|
-
throw new Error(`${source}: \`toolkits\` entry ${JSON.stringify(name)} is not a ` +
|
|
176
|
-
`toolkit name (must match ${TOOLKIT_NAME_RE.source}).`);
|
|
177
|
-
}
|
|
178
|
-
if (!names.includes(name))
|
|
179
|
-
names.push(name);
|
|
180
|
-
}
|
|
181
|
-
if (names.length === 0 && unscoped !== true) {
|
|
182
|
-
throw new Error(`${source}: binds no toolkits and no unscoped access, so this credential ` +
|
|
183
|
-
"could authenticate but never connect. List at least one toolkit, or " +
|
|
184
|
-
"pass `unscoped: true` to bind it to the full registry only.");
|
|
185
|
-
}
|
|
186
|
-
return Object.freeze({
|
|
187
|
-
toolkits: Object.freeze(names),
|
|
188
|
-
...(unscoped === true ? { unscoped: true } : {}),
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Coerce an arbitrary value into a `ToolkitBinding`, or null when it is not one.
|
|
193
|
-
*
|
|
194
|
-
* The shipped adapters build bindings through `resolveToolkitBinding` above, but
|
|
195
|
-
* `InboundAuth` is an open interface and `AuthResult.toolkitBinding` arrives at
|
|
196
|
-
* REQUEST time from code connecta does not own — a custom adapter, or one
|
|
197
|
-
* mapping an IdP claim. Every field is therefore re-checked here rather than
|
|
198
|
-
* trusted from the type, because each way of being wrong fails OPEN if it is
|
|
199
|
-
* merely believed:
|
|
200
|
-
*
|
|
201
|
-
* - `unscoped` is compared to `true` by identity, so a truthy non-boolean (the
|
|
202
|
-
* string `"false"` out of an env var, say) cannot grant the full registry;
|
|
203
|
-
* - `toolkits` must be a real array — a bare string would otherwise reach
|
|
204
|
-
* `String.prototype.includes`, where `?toolkit=sup` would "match" `"support"`
|
|
205
|
-
* by substring;
|
|
206
|
-
* - a missing/!array `toolkits` is not treated as an empty binding, because the
|
|
207
|
-
* caller of a null return refuses the request outright.
|
|
208
|
-
*
|
|
209
|
-
* Returns a frozen, deduplicated copy: nothing downstream can be mutated by the
|
|
210
|
-
* adapter after the check, and every name is known to fit the grammar.
|
|
211
|
-
*/
|
|
212
|
-
function normalizeToolkitBinding(value) {
|
|
213
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
const { toolkits, unscoped } = value;
|
|
217
|
-
if (!Array.isArray(toolkits))
|
|
218
|
-
return null;
|
|
219
|
-
if (unscoped !== undefined && typeof unscoped !== "boolean")
|
|
220
|
-
return null;
|
|
221
|
-
const names = [];
|
|
222
|
-
for (const name of toolkits) {
|
|
223
|
-
if (typeof name !== "string" || !TOOLKIT_NAME_RE.test(name))
|
|
224
|
-
return null;
|
|
225
|
-
if (!names.includes(name))
|
|
226
|
-
names.push(name);
|
|
227
|
-
}
|
|
228
|
-
return Object.freeze({
|
|
229
|
-
toolkits: Object.freeze(names),
|
|
230
|
-
...(unscoped === true ? { unscoped: true } : {}),
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Resolve the binding one admitted identity is actually held to, from the
|
|
235
|
-
* provider's static declaration and whatever its `authorize` returned.
|
|
236
|
-
*
|
|
237
|
-
* - Neither ⇒ unbound (undefined), the pre-binding behavior.
|
|
238
|
-
* - Declaration only ⇒ the declaration.
|
|
239
|
-
* - Per-identity only ⇒ that binding, validated. This is the custom-adapter
|
|
240
|
-
* seam: a provider that declares nothing is asserting it resolves membership
|
|
241
|
-
* itself, so there is nothing to check it against.
|
|
242
|
-
* - Both ⇒ the **intersection**. The declaration is a CEILING, not a default: an
|
|
243
|
-
* adapter that maps a user-writable IdP claim to toolkits must not be able to
|
|
244
|
-
* widen the credential's own binding, which would turn "support token" into
|
|
245
|
-
* "any toolkit, plus the full registry" for anyone who can set that claim.
|
|
246
|
-
* Narrowing is fine and useful (per-user subsets of the team's view).
|
|
247
|
-
*
|
|
248
|
-
* A malformed binding on either side is not silently ignored — it returns
|
|
249
|
-
* `{ ok: false }` and the caller refuses the request, because the alternative
|
|
250
|
-
* (dropping it) is the fail-open reading.
|
|
251
|
-
*/
|
|
252
|
-
export function resolveIdentityBinding(declared, perIdentity) {
|
|
253
|
-
const ceiling = declared === undefined ? undefined : normalizeToolkitBinding(declared);
|
|
254
|
-
if (declared !== undefined && !ceiling) {
|
|
255
|
-
return {
|
|
256
|
-
ok: false,
|
|
257
|
-
reason: "the toolkit binding declared on the provider is malformed " +
|
|
258
|
-
"(`toolkits` must be an array of toolkit names, `unscoped` a boolean)",
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
if (perIdentity === undefined) {
|
|
262
|
-
return ceiling ? { ok: true, binding: ceiling } : { ok: true };
|
|
263
|
-
}
|
|
264
|
-
const identity = normalizeToolkitBinding(perIdentity);
|
|
265
|
-
if (!identity) {
|
|
266
|
-
return {
|
|
267
|
-
ok: false,
|
|
268
|
-
reason: "the toolkit binding its authorize() returned for this identity is " +
|
|
269
|
-
"malformed (`toolkits` must be an array of toolkit names, `unscoped` " +
|
|
270
|
-
"a boolean)",
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
if (!ceiling)
|
|
274
|
-
return { ok: true, binding: identity };
|
|
275
|
-
return {
|
|
276
|
-
ok: true,
|
|
277
|
-
binding: Object.freeze({
|
|
278
|
-
toolkits: Object.freeze(identity.toolkits.filter((name) => ceiling.toolkits.includes(name))),
|
|
279
|
-
...(identity.unscoped === true && ceiling.unscoped === true
|
|
280
|
-
? { unscoped: true }
|
|
281
|
-
: {}),
|
|
282
|
-
}),
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Cross-check every statically declared binding against the deployment's
|
|
287
|
-
* toolkits, in `createConnecta`. A name that no toolkit declares is a typo, and
|
|
288
|
-
* a typo here fails CLOSED — the credential would be refused every connection
|
|
289
|
-
* with a 403 the client reads as a transport failure — so it throws at
|
|
290
|
-
* construction rather than becoming a support ticket. A structurally malformed
|
|
291
|
-
* declaration (only reachable from a hand-written `InboundAuth`, since the
|
|
292
|
-
* shipped adapters validate their own options) throws here too, rather than
|
|
293
|
-
* waiting to refuse every request at runtime.
|
|
294
|
-
*
|
|
295
|
-
* Bindings a provider mints per-identity (`AuthResult.toolkitBinding`) do not
|
|
296
|
-
* exist yet and cannot be checked here; they are validated on arrival and capped
|
|
297
|
-
* by the declaration (`resolveIdentityBinding`).
|
|
298
|
-
*/
|
|
299
|
-
export function validateToolkitBindings(auth, toolkits) {
|
|
300
|
-
for (const provider of auth) {
|
|
301
|
-
if (provider.toolkitBinding === undefined)
|
|
302
|
-
continue;
|
|
303
|
-
const binding = normalizeToolkitBinding(provider.toolkitBinding);
|
|
304
|
-
if (!binding) {
|
|
305
|
-
throw new Error(`Inbound auth provider "${provider.kind}" declares a malformed ` +
|
|
306
|
-
"toolkitBinding: `toolkits` must be an array of toolkit names " +
|
|
307
|
-
`(matching ${TOOLKIT_NAME_RE.source}) and \`unscoped\` a boolean.`);
|
|
308
|
-
}
|
|
309
|
-
if (!toolkits || toolkits.size === 0) {
|
|
310
|
-
throw new Error(`Inbound auth provider "${provider.kind}" binds toolkits ` +
|
|
311
|
-
`(${binding.toolkits.join(", ")}) but this deployment configures no ` +
|
|
312
|
-
"toolkits. Declare them in `toolkits`, or drop the binding.");
|
|
313
|
-
}
|
|
314
|
-
for (const name of binding.toolkits) {
|
|
315
|
-
if (!toolkits.has(name)) {
|
|
316
|
-
throw new Error(`Inbound auth provider "${provider.kind}" binds unknown toolkit ` +
|
|
317
|
-
`"${name}". Configured toolkits: ${[...toolkits.keys()].join(", ")}.`);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
//# sourceMappingURL=toolkits.js.map
|
package/dist/toolkits.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toolkits.js","sourceRoot":"","sources":["../src/toolkits.ts"],"names":[],"mappings":"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"}
|