managed-deepagents 0.0.3-dev.26 → 0.0.3-dev.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/identity.d.ts +273 -0
  2. package/dist/identity.d.ts.map +1 -0
  3. package/dist/identity.js +358 -0
  4. package/dist/identity.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/runtime/auth.d.ts +44 -0
  10. package/dist/runtime/auth.d.ts.map +1 -0
  11. package/dist/runtime/auth.js +168 -0
  12. package/dist/runtime/auth.js.map +1 -0
  13. package/dist/runtime/credentials.d.ts +60 -0
  14. package/dist/runtime/credentials.d.ts.map +1 -0
  15. package/dist/runtime/credentials.js +189 -0
  16. package/dist/runtime/credentials.js.map +1 -0
  17. package/dist/runtime/identity-http.d.ts +8 -0
  18. package/dist/runtime/identity-http.d.ts.map +1 -0
  19. package/dist/runtime/identity-http.js +23 -0
  20. package/dist/runtime/identity-http.js.map +1 -0
  21. package/dist/runtime/identity-runtime.d.ts +54 -0
  22. package/dist/runtime/identity-runtime.d.ts.map +1 -0
  23. package/dist/runtime/identity-runtime.js +151 -0
  24. package/dist/runtime/identity-runtime.js.map +1 -0
  25. package/dist/runtime/index.d.ts +11 -0
  26. package/dist/runtime/index.d.ts.map +1 -1
  27. package/dist/runtime/index.js +26 -1
  28. package/dist/runtime/index.js.map +1 -1
  29. package/dist/runtime/managed-middleware.d.ts +25 -0
  30. package/dist/runtime/managed-middleware.d.ts.map +1 -0
  31. package/dist/runtime/managed-middleware.js +76 -0
  32. package/dist/runtime/managed-middleware.js.map +1 -0
  33. package/dist/runtime/managed-tools.d.ts +61 -0
  34. package/dist/runtime/managed-tools.d.ts.map +1 -0
  35. package/dist/runtime/managed-tools.js +102 -0
  36. package/dist/runtime/managed-tools.js.map +1 -0
  37. package/dist/runtime/types.d.ts +18 -3
  38. package/dist/runtime/types.d.ts.map +1 -1
  39. package/dist/runtime/validated-token.d.ts +25 -0
  40. package/dist/runtime/validated-token.d.ts.map +1 -0
  41. package/dist/runtime/validated-token.js +260 -0
  42. package/dist/runtime/validated-token.js.map +1 -0
  43. package/dist/types.d.ts +9 -0
  44. package/dist/types.d.ts.map +1 -1
  45. package/package.json +11 -8
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,GACb,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE5E,YAAY,EACV,kBAAkB,EAClB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,WAAW,EACX,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,GACb,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ export { defineDeepAgent } from "./define-deep-agent.js";
2
2
  export { defineMcpServers } from "./connectors.js";
3
3
  export { defineSchedule } from "./schedules.js";
4
4
  export { defineSandbox } from "./sandbox.js";
5
+ export { defineIdentity, providers, validateIdentity } from "./identity.js";
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { Auth } from "@langchain/langgraph-sdk/auth";
2
+ import type { IdentityConfig, IdentityDefinition } from "../identity.js";
3
+ /**
4
+ * The user object `@auth.authenticate` returns. `identity`/`permissions` satisfy
5
+ * the LangGraph base shape; the `mda_*` fields carry the identity envelope into
6
+ * `config.configurable.langgraph_auth_user` for the runtime seam.
7
+ */
8
+ export interface ManagedUser {
9
+ identity: string;
10
+ permissions: string[];
11
+ mda_actor_id: string;
12
+ mda_tenant_id?: string;
13
+ mda_actor_email?: string;
14
+ mda_claims?: Record<string, unknown>;
15
+ [key: string]: unknown;
16
+ }
17
+ /**
18
+ * Build the managed LangGraph custom-auth handler from a declared identity.
19
+ *
20
+ * Handles both ingress modes: `trusted_backend` (reserved headers behind a
21
+ * shared ingress secret) and `validated_token` (browser-direct IdP tokens
22
+ * verified via JWKS / introspection / MDA-signed guest). Also registers thread
23
+ * and store scoping with a studio bypass.
24
+ */
25
+ export declare function buildManagedAuth(identity: IdentityDefinition): Auth;
26
+ /**
27
+ * Fail-closed (403) unless every identity segment the memory scope requires is
28
+ * present in the store `namespace`. `agent`/`none` scopes carry no per-identity
29
+ * restriction (shared or absent memory), so any namespace is allowed.
30
+ */
31
+ export declare function assertStoreAccess(cfg: IdentityConfig, user: ManagedUser, value: unknown): void;
32
+ /**
33
+ * Resolve the caller identity for `trusted_backend`: validate the shared ingress
34
+ * secret, then trust the reserved actor/tenant headers. Fail-closed (401) on a
35
+ * missing/invalid secret, a missing actor, or a missing tenant under multi.
36
+ */
37
+ export declare function resolveTrustedBackendUser(cfg: IdentityConfig, request: Request): ManagedUser;
38
+ /** Derive the owner value `@auth.on.threads` filters on, per the `threads` axis. */
39
+ export declare function threadOwnerKey(cfg: IdentityConfig, user: ManagedUser): string;
40
+ /** True when this deployment exposes guest issuance and the request targets it. */
41
+ export declare function isGuestIssuanceRequest(request: Request, cfg: IdentityConfig): boolean;
42
+ /** Placeholder identity so LangGraph auth middleware allows tokenless issuance. */
43
+ export declare function guestIssuanceBypassUser(): ManagedUser;
44
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/runtime/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EAGL,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAuBzE;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAsCnE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,OAAO,GACb,IAAI,CAuBN;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,OAAO,GACf,WAAW,CAgBb;AAED,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAY7E;AAuBD,mFAAmF;AACnF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,cAAc,GAClB,OAAO,CAaT;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,IAAI,WAAW,CAMrD"}
@@ -0,0 +1,168 @@
1
+ import { Auth, HTTPException, isStudioUser, } from "@langchain/langgraph-sdk/auth";
2
+ import { memoryIdentitySegments } from "./identity-runtime.js";
3
+ import { resolveValidatedTokenUser } from "./validated-token.js";
4
+ /**
5
+ * Reserved transport for the trusted-backend ingress mode. Actor/tenant travel
6
+ * as reserved headers (mapped into `config.configurable` by the generated
7
+ * `langgraph.json` allowlist); the ingress secret is validated here and is
8
+ * deliberately **not** allowlisted, so it never reaches `config.configurable`.
9
+ */
10
+ const ACTOR_HEADER = "x-mda-actor-id";
11
+ const TENANT_HEADER = "x-mda-tenant-id";
12
+ const INGRESS_SECRET_HEADER = "x-mda-ingress-secret";
13
+ /** Deployment env var carrying the shared secret the trusted backend presents. */
14
+ const INGRESS_SECRET_ENV = "MDA_INGRESS_SECRET";
15
+ /** Path MDA exposes for anonymous guest token issuance (must stay public). */
16
+ const GUEST_ISSUANCE_PATH = "/identity/guest";
17
+ /** Synthetic actor used only to satisfy auth middleware on the issuance route. */
18
+ const GUEST_ISSUER_ACTOR = "mda:guest-issuer";
19
+ /**
20
+ * Build the managed LangGraph custom-auth handler from a declared identity.
21
+ *
22
+ * Handles both ingress modes: `trusted_backend` (reserved headers behind a
23
+ * shared ingress secret) and `validated_token` (browser-direct IdP tokens
24
+ * verified via JWKS / introspection / MDA-signed guest). Also registers thread
25
+ * and store scoping with a studio bypass.
26
+ */
27
+ export function buildManagedAuth(identity) {
28
+ const cfg = identity.config;
29
+ const http = cfg.ingress.http;
30
+ const auth = new Auth();
31
+ auth.authenticate(async (request) => {
32
+ if (isGuestIssuanceRequest(request, cfg)) {
33
+ return guestIssuanceBypassUser();
34
+ }
35
+ if (http === "trusted_backend") {
36
+ return resolveTrustedBackendUser(cfg, request);
37
+ }
38
+ return resolveValidatedTokenUser(cfg, http, request);
39
+ });
40
+ auth.on("threads", ({ user, value }) => {
41
+ if (isStudioUser(user)) {
42
+ return true;
43
+ }
44
+ const key = threadOwnerKey(cfg, user);
45
+ if (value && typeof value === "object") {
46
+ const container = value;
47
+ container.metadata = { ...(container.metadata ?? {}), owner: key };
48
+ }
49
+ return { owner: key };
50
+ });
51
+ // Mirror the memory namespace so raw store ops can't cross the identity
52
+ // boundary a run is scoped to (§5, §6.2).
53
+ auth.on("store", ({ user, value }) => {
54
+ if (isStudioUser(user)) {
55
+ return true;
56
+ }
57
+ assertStoreAccess(cfg, user, value);
58
+ return true;
59
+ });
60
+ return auth;
61
+ }
62
+ /**
63
+ * Fail-closed (403) unless every identity segment the memory scope requires is
64
+ * present in the store `namespace`. `agent`/`none` scopes carry no per-identity
65
+ * restriction (shared or absent memory), so any namespace is allowed.
66
+ */
67
+ export function assertStoreAccess(cfg, user, value) {
68
+ const required = memoryIdentitySegments(cfg.scoping.memory, cfg.tenancy, user.mda_actor_id ? String(user.mda_actor_id) : undefined, user.mda_tenant_id ? String(user.mda_tenant_id) : undefined);
69
+ if (required.length === 0) {
70
+ return;
71
+ }
72
+ const namespace = value &&
73
+ typeof value === "object" &&
74
+ Array.isArray(value.namespace)
75
+ ? value.namespace.map(String)
76
+ : [];
77
+ for (const segment of required) {
78
+ if (!namespace.includes(segment)) {
79
+ throw new HTTPException(403, {
80
+ message: "store namespace is outside the caller's identity boundary",
81
+ });
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Resolve the caller identity for `trusted_backend`: validate the shared ingress
87
+ * secret, then trust the reserved actor/tenant headers. Fail-closed (401) on a
88
+ * missing/invalid secret, a missing actor, or a missing tenant under multi.
89
+ */
90
+ export function resolveTrustedBackendUser(cfg, request) {
91
+ requireIngressSecret(request);
92
+ const actor = request.headers.get(ACTOR_HEADER);
93
+ if (!actor) {
94
+ throw new HTTPException(401, { message: `missing ${ACTOR_HEADER}` });
95
+ }
96
+ const tenant = request.headers.get(TENANT_HEADER) ?? undefined;
97
+ assertTenantPresentIfMulti(cfg, tenant);
98
+ return {
99
+ identity: actor,
100
+ permissions: [],
101
+ mda_actor_id: actor,
102
+ ...(tenant ? { mda_tenant_id: tenant } : {}),
103
+ };
104
+ }
105
+ /** Derive the owner value `@auth.on.threads` filters on, per the `threads` axis. */
106
+ export function threadOwnerKey(cfg, user) {
107
+ const scope = cfg.scoping.threads ?? "actor";
108
+ const actor = String(user.mda_actor_id ?? "");
109
+ const tenant = user.mda_tenant_id ? String(user.mda_tenant_id) : undefined;
110
+ if (scope === "tenant") {
111
+ return tenant ?? actor;
112
+ }
113
+ if (scope === "channel") {
114
+ const channel = user.mda_source_thread_id;
115
+ return channel ? String(channel) : actor;
116
+ }
117
+ return actor;
118
+ }
119
+ function requireIngressSecret(request) {
120
+ const expected = process.env[INGRESS_SECRET_ENV];
121
+ const provided = request.headers.get(INGRESS_SECRET_HEADER);
122
+ if (!expected || !provided || !constantTimeEquals(expected, provided)) {
123
+ throw new HTTPException(401, {
124
+ message: "invalid or missing ingress secret",
125
+ });
126
+ }
127
+ }
128
+ function assertTenantPresentIfMulti(cfg, tenant) {
129
+ if (cfg.tenancy === "multi" && !tenant) {
130
+ throw new HTTPException(401, {
131
+ message: "missing tenant for multi-tenant deployment",
132
+ });
133
+ }
134
+ }
135
+ /** True when this deployment exposes guest issuance and the request targets it. */
136
+ export function isGuestIssuanceRequest(request, cfg) {
137
+ if (request.method !== "POST") {
138
+ return false;
139
+ }
140
+ const { pathname } = new URL(request.url);
141
+ if (pathname !== GUEST_ISSUANCE_PATH) {
142
+ return false;
143
+ }
144
+ const http = cfg.ingress.http;
145
+ if (http === "trusted_backend") {
146
+ return false;
147
+ }
148
+ return http.providers.some((provider) => provider.guest?.issue);
149
+ }
150
+ /** Placeholder identity so LangGraph auth middleware allows tokenless issuance. */
151
+ export function guestIssuanceBypassUser() {
152
+ return {
153
+ identity: GUEST_ISSUER_ACTOR,
154
+ permissions: [],
155
+ mda_actor_id: GUEST_ISSUER_ACTOR,
156
+ };
157
+ }
158
+ function constantTimeEquals(a, b) {
159
+ if (a.length !== b.length) {
160
+ return false;
161
+ }
162
+ let mismatch = 0;
163
+ for (let i = 0; i < a.length; i += 1) {
164
+ mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
165
+ }
166
+ return mismatch === 0;
167
+ }
168
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/runtime/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { CredentialTarget, IdentityConfig, ResolvedCredential, RuntimeIdentity } from "../identity.js";
2
+ /**
3
+ * Component 5 — Credentials, custom mode (`scoping.credentials: "custom"`, §7.2).
4
+ *
5
+ * The escape hatch Agent Auth can't cover: bespoke per-actor credential minting
6
+ * via an in-process resolver callback or a hosted token-exchange endpoint. It
7
+ * runs in the worker (not the shared ingress auth handler), applies the output
8
+ * to downstream calls, and caches per `(actor, tenant, target)` until the
9
+ * credential's `expiresAt`. Secrets live only in this in-memory cache keyed by
10
+ * identity — never in thread state or traces (§7.2, §8, identity-final §10).
11
+ *
12
+ * The managed modes (`agent`/`actor`) route to Agent Auth
13
+ * (`@langchain/auth`/`langchain-auth`, §7.1) and are wired separately; this
14
+ * module is only the custom path.
15
+ */
16
+ /** Env var holding the HMAC secret MDA signs the endpoint assertion with. */
17
+ export declare const CREDENTIAL_SIGNING_SECRET_ENV = "MDA_TOKEN_EXCHANGE_SECRET";
18
+ /** Per-call options for {@link CredentialsProvider.for}. */
19
+ export interface CredentialForOptions {
20
+ /** Skip the cache and force a fresh mint (e.g. after a downstream 401). */
21
+ forceRefresh?: boolean;
22
+ }
23
+ /**
24
+ * The per-run credential surface a tool receives as `runtime.credentials`.
25
+ * Tools call `runtime.credentials.for(target)` and attach the returned headers
26
+ * to their downstream request.
27
+ */
28
+ export interface CredentialsProvider {
29
+ for(target: CredentialTarget, options?: CredentialForOptions): Promise<ResolvedCredential>;
30
+ }
31
+ /**
32
+ * Side effects the executor depends on, injectable so resolution is
33
+ * deterministic under test (no real clock, network, or signing key).
34
+ */
35
+ export interface CredentialDeps {
36
+ fetch: typeof fetch;
37
+ now: () => number;
38
+ /** Signs the assertion MDA presents to a hosted token-exchange endpoint. */
39
+ signAssertion: (identity: RuntimeIdentity, target: CredentialTarget) => Promise<string>;
40
+ }
41
+ /**
42
+ * TTL cache for resolved credentials, keyed by `(actor, tenant, target)` so
43
+ * per-repo/per-install tokens never collide. Kept out of thread state; entries
44
+ * expire at the credential's `expiresAt`.
45
+ */
46
+ export declare class CredentialCache {
47
+ private readonly entries;
48
+ get(key: string, nowMs: number): ResolvedCredential | undefined;
49
+ set(key: string, value: ResolvedCredential): void;
50
+ clear(): void;
51
+ }
52
+ /** Clear the process-level credential cache. Test-only. */
53
+ export declare function clearCredentialCacheForTests(): void;
54
+ /**
55
+ * Build the `runtime.credentials` provider for a run, or `undefined` when the
56
+ * deployment isn't in custom-credentials mode. The provider is bound to the
57
+ * run's resolved identity; every `for(target)` call is scoped to that actor.
58
+ */
59
+ export declare function createCredentialsProvider(cfg: IdentityConfig, identity: RuntimeIdentity | undefined, deps?: Partial<CredentialDeps>, cache?: CredentialCache): CredentialsProvider | undefined;
60
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/runtime/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,eAAe,EAChB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;;;;;;GAaG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,8BAA8B,CAAC;AAKzE,4DAA4D;AAC5D,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CACD,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,4EAA4E;IAC5E,aAAa,EAAE,CACb,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,gBAAgB,KACrB,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB;AAQD;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IAEzD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAY/D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IASjD,KAAK,IAAI,IAAI;CAGd;AAKD,2DAA2D;AAC3D,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,IAAI,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,EAC9B,KAAK,GAAE,eAA8B,GACpC,mBAAmB,GAAG,SAAS,CA8BjC"}
@@ -0,0 +1,189 @@
1
+ import { SignJWT } from "jose";
2
+ /**
3
+ * Component 5 — Credentials, custom mode (`scoping.credentials: "custom"`, §7.2).
4
+ *
5
+ * The escape hatch Agent Auth can't cover: bespoke per-actor credential minting
6
+ * via an in-process resolver callback or a hosted token-exchange endpoint. It
7
+ * runs in the worker (not the shared ingress auth handler), applies the output
8
+ * to downstream calls, and caches per `(actor, tenant, target)` until the
9
+ * credential's `expiresAt`. Secrets live only in this in-memory cache keyed by
10
+ * identity — never in thread state or traces (§7.2, §8, identity-final §10).
11
+ *
12
+ * The managed modes (`agent`/`actor`) route to Agent Auth
13
+ * (`@langchain/auth`/`langchain-auth`, §7.1) and are wired separately; this
14
+ * module is only the custom path.
15
+ */
16
+ /** Env var holding the HMAC secret MDA signs the endpoint assertion with. */
17
+ export const CREDENTIAL_SIGNING_SECRET_ENV = "MDA_TOKEN_EXCHANGE_SECRET";
18
+ /** How long a signed endpoint assertion is valid, in seconds. */
19
+ const ASSERTION_TTL_SECONDS = 60;
20
+ /**
21
+ * TTL cache for resolved credentials, keyed by `(actor, tenant, target)` so
22
+ * per-repo/per-install tokens never collide. Kept out of thread state; entries
23
+ * expire at the credential's `expiresAt`.
24
+ */
25
+ export class CredentialCache {
26
+ entries = new Map();
27
+ get(key, nowMs) {
28
+ const hit = this.entries.get(key);
29
+ if (!hit) {
30
+ return undefined;
31
+ }
32
+ if (hit.expiresAtMs !== undefined && nowMs >= hit.expiresAtMs) {
33
+ this.entries.delete(key);
34
+ return undefined;
35
+ }
36
+ return hit.value;
37
+ }
38
+ set(key, value) {
39
+ let expiresAtMs;
40
+ if (value.expiresAt) {
41
+ const parsed = Date.parse(value.expiresAt);
42
+ expiresAtMs = Number.isNaN(parsed) ? undefined : parsed;
43
+ }
44
+ this.entries.set(key, { value, expiresAtMs });
45
+ }
46
+ clear() {
47
+ this.entries.clear();
48
+ }
49
+ }
50
+ /** Process-level cache shared across runs for the lifetime of the deployment. */
51
+ const defaultCache = new CredentialCache();
52
+ /** Clear the process-level credential cache. Test-only. */
53
+ export function clearCredentialCacheForTests() {
54
+ defaultCache.clear();
55
+ }
56
+ /**
57
+ * Build the `runtime.credentials` provider for a run, or `undefined` when the
58
+ * deployment isn't in custom-credentials mode. The provider is bound to the
59
+ * run's resolved identity; every `for(target)` call is scoped to that actor.
60
+ */
61
+ export function createCredentialsProvider(cfg, identity, deps, cache = defaultCache) {
62
+ if (cfg.scoping.credentials !== "custom" || !cfg.credentials) {
63
+ return undefined;
64
+ }
65
+ const resolved = {
66
+ fetch: deps?.fetch ?? fetch,
67
+ now: deps?.now ?? (() => Date.now()),
68
+ signAssertion: deps?.signAssertion ?? defaultSignAssertion,
69
+ };
70
+ return {
71
+ async for(target, options) {
72
+ if (!identity) {
73
+ throw new Error("runtime.credentials.for(...) requires a resolved identity, but none " +
74
+ "was available for this run.");
75
+ }
76
+ const key = cacheKey(identity, target);
77
+ if (!options?.forceRefresh) {
78
+ const hit = cache.get(key, resolved.now());
79
+ if (hit) {
80
+ return hit;
81
+ }
82
+ }
83
+ // Fail-closed: a resolver/endpoint error propagates and nothing is cached.
84
+ const out = await resolveCredential(cfg, identity, target, resolved);
85
+ cache.set(key, out);
86
+ return out;
87
+ },
88
+ };
89
+ }
90
+ async function resolveCredential(cfg, identity, target, deps) {
91
+ const creds = cfg.credentials;
92
+ if (!creds) {
93
+ throw new Error("No credentials resolver is configured for this deployment.");
94
+ }
95
+ if ("resolve" in creds) {
96
+ const out = await creds.resolve({ identity, target });
97
+ return normalizeResolved(out, "resolver");
98
+ }
99
+ const assertion = await deps.signAssertion(identity, target);
100
+ return callTokenExchange(creds.endpoint.url, assertion, deps);
101
+ }
102
+ async function callTokenExchange(url, assertion, deps) {
103
+ const response = await deps.fetch(url, {
104
+ method: "POST",
105
+ headers: {
106
+ "content-type": "application/json",
107
+ authorization: `Bearer ${assertion}`,
108
+ },
109
+ body: JSON.stringify({ assertion }),
110
+ });
111
+ if (!response.ok) {
112
+ throw new Error(`Credential token-exchange endpoint ${url} responded ${response.status}.`);
113
+ }
114
+ return normalizeResolved(await response.json(), `endpoint ${url}`);
115
+ }
116
+ async function defaultSignAssertion(identity, target) {
117
+ const secret = process.env[CREDENTIAL_SIGNING_SECRET_ENV];
118
+ if (!secret) {
119
+ throw new Error(`A hosted credential endpoint requires a signing secret. Set ` +
120
+ `${CREDENTIAL_SIGNING_SECRET_ENV} in the deployment environment.`);
121
+ }
122
+ const issuedAt = Math.floor(Date.now() / 1000);
123
+ return new SignJWT({
124
+ actor_id: identity.actor.id,
125
+ actor_type: identity.actor.type,
126
+ tenant_id: identity.tenant?.id,
127
+ target: { kind: target.kind, name: target.name, intent: target.intent },
128
+ })
129
+ .setProtectedHeader({ alg: "HS256" })
130
+ .setSubject(identity.actor.id)
131
+ .setIssuedAt(issuedAt)
132
+ .setExpirationTime(issuedAt + ASSERTION_TTL_SECONDS)
133
+ .sign(new TextEncoder().encode(secret));
134
+ }
135
+ /**
136
+ * The cache key that discriminates a minted credential: the actor + tenant it
137
+ * belongs to, plus the target's kind/name/intent/thread and metadata (§7.2).
138
+ */
139
+ function cacheKey(identity, target) {
140
+ return stableStringify([
141
+ identity.actor.id,
142
+ identity.tenant?.id ?? null,
143
+ target.kind,
144
+ target.name,
145
+ target.intent ?? null,
146
+ target.threadId ?? null,
147
+ target.metadata ?? null,
148
+ ]);
149
+ }
150
+ /** Deterministic JSON with object keys sorted, so the cache key is stable. */
151
+ function stableStringify(value) {
152
+ if (value === null || typeof value !== "object") {
153
+ return JSON.stringify(value) ?? "null";
154
+ }
155
+ if (Array.isArray(value)) {
156
+ return `[${value.map(stableStringify).join(",")}]`;
157
+ }
158
+ const obj = value;
159
+ return `{${Object.keys(obj)
160
+ .sort()
161
+ .map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`)
162
+ .join(",")}}`;
163
+ }
164
+ /** Validate a resolver/endpoint result into a {@link ResolvedCredential}. */
165
+ function normalizeResolved(value, sourceLabel) {
166
+ if (!value || typeof value !== "object") {
167
+ throw new Error(`Credential ${sourceLabel} returned a non-object result.`);
168
+ }
169
+ const { headers, expiresAt } = value;
170
+ if (!headers || typeof headers !== "object" || Array.isArray(headers)) {
171
+ throw new Error(`Credential ${sourceLabel} result is missing a headers object.`);
172
+ }
173
+ const normalizedHeaders = {};
174
+ for (const [name, headerValue] of Object.entries(headers)) {
175
+ if (typeof headerValue !== "string") {
176
+ throw new Error(`Credential ${sourceLabel} header "${name}" must be a string.`);
177
+ }
178
+ normalizedHeaders[name] = headerValue;
179
+ }
180
+ const result = { headers: normalizedHeaders };
181
+ if (expiresAt !== undefined) {
182
+ if (typeof expiresAt !== "string") {
183
+ throw new Error(`Credential ${sourceLabel} \`expiresAt\` must be an ISO string.`);
184
+ }
185
+ result.expiresAt = expiresAt;
186
+ }
187
+ return result;
188
+ }
189
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/runtime/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Hono } from "hono";
2
+ import type { IdentityDefinition } from "../identity.js";
3
+ /**
4
+ * Build the managed identity HTTP app (guest issuance, etc.) from a declared
5
+ * identity. Mounted via `langgraph.json` `http.app` when identity is enabled.
6
+ */
7
+ export declare function buildManagedIdentityApp(identity: IdentityDefinition): Hono;
8
+ //# sourceMappingURL=identity-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-http.d.ts","sourceRoot":"","sources":["../../src/runtime/identity-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGzD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAoB1E"}
@@ -0,0 +1,23 @@
1
+ import { Hono } from "hono";
2
+ import { issueGuestToken } from "./validated-token.js";
3
+ /**
4
+ * Build the managed identity HTTP app (guest issuance, etc.) from a declared
5
+ * identity. Mounted via `langgraph.json` `http.app` when identity is enabled.
6
+ */
7
+ export function buildManagedIdentityApp(identity) {
8
+ const app = new Hono();
9
+ const http = identity.config.ingress.http;
10
+ if (http === "trusted_backend") {
11
+ return app;
12
+ }
13
+ const guestProvider = http.providers.find((provider) => provider.guest?.issue);
14
+ if (!guestProvider) {
15
+ return app;
16
+ }
17
+ app.post("/identity/guest", async (c) => {
18
+ const token = await issueGuestToken(guestProvider);
19
+ return c.json({ token });
20
+ });
21
+ return app;
22
+ }
23
+ //# sourceMappingURL=identity-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-http.js","sourceRoot":"","sources":["../../src/runtime/identity-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAA4B;IAClE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1C,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACvC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CACpC,CAAC;IACF,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { IdentityConfig, MemoryScope, RuntimeIdentity, Tenancy } from "../identity.js";
2
+ import type { ConfigurableCarrier } from "./types.js";
3
+ /**
4
+ * Resolve the LangGraph `configurable` bag from either a flat runtime or the
5
+ * nested `ToolRuntime` shape LangChain passes to tools (`runtime.config.configurable`).
6
+ */
7
+ export declare function resolveRuntimeConfigurable(runtime: RuntimeConfigLike | undefined): Record<string, unknown> | undefined;
8
+ /**
9
+ * Build the frozen identity envelope for the current run from the trusted
10
+ * `langgraph_auth_user` the custom-auth handler produced (§6.1). Returns
11
+ * `undefined` when the deployment has no resolvable actor (identity is opt-in).
12
+ */
13
+ export declare function buildRuntimeIdentity(configurable: Record<string, unknown> | undefined): RuntimeIdentity | undefined;
14
+ /**
15
+ * The durable Store namespace for the run, per `scoping.memory` (§6.2). A
16
+ * `deploymentId` prefix isolates deployments; identity segments follow. Returns
17
+ * `undefined` for `none` (no durable memory). Fail-closed: an `actor` scope with
18
+ * no actor already rejects at ingress, so the segments are never empty here.
19
+ */
20
+ export declare function memoryNamespace(cfg: IdentityConfig, ident: RuntimeIdentity, deploymentId: string): string[] | undefined;
21
+ /**
22
+ * The runtime the managed seam sees: the shared `configurable` carrier, plus the
23
+ * optional nested `config` (e.g. LangGraph `ToolRuntime.config`) and the frozen
24
+ * `identity` envelope the seam layers on. Single source for the tool, middleware,
25
+ * and memory-namespace helpers.
26
+ */
27
+ export interface RuntimeConfigLike extends ConfigurableCarrier {
28
+ identity?: RuntimeIdentity;
29
+ config?: {
30
+ configurable?: Record<string, unknown>;
31
+ };
32
+ }
33
+ /**
34
+ * Resolve the durable memory namespace for a run directly from the runtime the
35
+ * memory `StoreBackend` receives, per `scoping.memory` (§6.2). This is the
36
+ * plug-in point for the (deferred) Store-backed memory: a `StoreBackend`
37
+ * namespace factory becomes `(ctx) => memoryNamespaceFor(ctx.runtime, cfg, id)`.
38
+ * Returns `undefined` when the run has no durable namespace (`none`, or a
39
+ * per-actor scope with no resolved actor).
40
+ */
41
+ export declare function memoryNamespaceFor(runtime: RuntimeConfigLike | undefined, cfg: IdentityConfig, deploymentId: string): string[] | undefined;
42
+ /**
43
+ * The identity portion of the memory namespace (no deployment prefix), shared by
44
+ * the memory `StoreBackend` and the `@auth.on.store` boundary check so both agree
45
+ * on exactly which segments identify a namespace.
46
+ */
47
+ export declare function memoryIdentitySegments(scope: MemoryScope, tenancy: Tenancy, actorId: string | undefined, tenantId: string | undefined): string[];
48
+ /**
49
+ * Strip client-supplied identity keys from an incoming `configurable` so a
50
+ * request body can never spoof the actor/tenant the handler resolved (§8). The
51
+ * platform-set `langgraph_auth_user` is preserved — it is the only trusted source.
52
+ */
53
+ export declare function sanitizeConfigurable(configurable: Record<string, unknown> | undefined): Record<string, unknown>;
54
+ //# sourceMappingURL=identity-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/identity-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,eAAe,EACf,OAAO,EACR,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA0BtD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAErC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAChD,eAAe,GAAG,SAAS,CAyB7B;AAaD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,MAAM,GACnB,MAAM,EAAE,GAAG,SAAS,CAiBtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAkB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CACrD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,GACnB,MAAM,EAAE,GAAG,SAAS,CAQtB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,EAAE,CAgBV;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}