@kya-os/mcp 1.5.0 → 1.6.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 +67 -0
- package/dist/authz/accountability.d.ts +35 -0
- package/dist/authz/accountability.d.ts.map +1 -0
- package/dist/authz/accountability.js +28 -0
- package/dist/authz/accountability.js.map +1 -0
- package/dist/authz/adapter.d.ts +47 -0
- package/dist/authz/adapter.d.ts.map +1 -0
- package/dist/authz/adapter.js +10 -0
- package/dist/authz/adapter.js.map +1 -0
- package/dist/authz/examples/inmemory-oidc.d.ts +29 -0
- package/dist/authz/examples/inmemory-oidc.d.ts.map +1 -0
- package/dist/authz/examples/inmemory-oidc.js +68 -0
- package/dist/authz/examples/inmemory-oidc.js.map +1 -0
- package/dist/authz/index.d.ts +19 -0
- package/dist/authz/index.d.ts.map +1 -0
- package/dist/authz/index.js +19 -0
- package/dist/authz/index.js.map +1 -0
- package/dist/authz/oidc/authorize.d.ts +25 -0
- package/dist/authz/oidc/authorize.d.ts.map +1 -0
- package/dist/authz/oidc/authorize.js +24 -0
- package/dist/authz/oidc/authorize.js.map +1 -0
- package/dist/authz/oidc/metadata.d.ts +43 -0
- package/dist/authz/oidc/metadata.d.ts.map +1 -0
- package/dist/authz/oidc/metadata.js +32 -0
- package/dist/authz/oidc/metadata.js.map +1 -0
- package/dist/authz/oidc/oidc-adapter.d.ts +52 -0
- package/dist/authz/oidc/oidc-adapter.d.ts.map +1 -0
- package/dist/authz/oidc/oidc-adapter.js +131 -0
- package/dist/authz/oidc/oidc-adapter.js.map +1 -0
- package/dist/authz/oidc/pkce.d.ts +20 -0
- package/dist/authz/oidc/pkce.d.ts.map +1 -0
- package/dist/authz/oidc/pkce.js +29 -0
- package/dist/authz/oidc/pkce.js.map +1 -0
- package/dist/authz/registry.d.ts +29 -0
- package/dist/authz/registry.d.ts.map +1 -0
- package/dist/authz/registry.js +48 -0
- package/dist/authz/registry.js.map +1 -0
- package/dist/authz/requirement.d.ts +38 -0
- package/dist/authz/requirement.d.ts.map +1 -0
- package/dist/authz/requirement.js +45 -0
- package/dist/authz/requirement.js.map +1 -0
- package/dist/delegation/chain-enforcement.d.ts +86 -0
- package/dist/delegation/chain-enforcement.d.ts.map +1 -0
- package/dist/delegation/chain-enforcement.js +224 -0
- package/dist/delegation/chain-enforcement.js.map +1 -0
- package/dist/delegation/holder-binding.d.ts +128 -0
- package/dist/delegation/holder-binding.d.ts.map +1 -0
- package/dist/delegation/holder-binding.js +175 -0
- package/dist/delegation/holder-binding.js.map +1 -0
- package/dist/delegation/index.d.ts +2 -0
- package/dist/delegation/index.d.ts.map +1 -1
- package/dist/delegation/index.js +2 -0
- package/dist/delegation/index.js.map +1 -1
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/with-kya-os.d.ts +35 -1
- package/dist/middleware/with-kya-os.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.js +94 -192
- package/dist/middleware/with-kya-os.js.map +1 -1
- package/dist/providers/grant-store.d.ts +98 -0
- package/dist/providers/grant-store.d.ts.map +1 -0
- package/dist/providers/grant-store.js +92 -0
- package/dist/providers/grant-store.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/runtime-fetch.d.ts +14 -0
- package/dist/providers/runtime-fetch.d.ts.map +1 -1
- package/dist/providers/runtime-fetch.js +22 -0
- package/dist/providers/runtime-fetch.js.map +1 -1
- package/dist/providers/web-crypto.d.ts +35 -0
- package/dist/providers/web-crypto.d.ts.map +1 -0
- package/dist/providers/web-crypto.js +91 -0
- package/dist/providers/web-crypto.js.map +1 -0
- package/package.json +25 -16
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,73 @@ All notable changes to @kya-os/mcp will be documented here.
|
|
|
5
5
|
Format: https://keepachangelog.com/en/1.0.0/
|
|
6
6
|
Versioning: https://semver.org/spec/v2.0.0.html
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.6.0] - 2026-06-03
|
|
11
|
+
|
|
12
|
+
Advances the E3 verifier-consolidation groundwork and hardens the delegation
|
|
13
|
+
gate: an isomorphic WebCrypto provider so the proof verifier can run on edge
|
|
14
|
+
runtimes without `node:crypto`, the delegation chain-enforcement rules lifted
|
|
15
|
+
into a framework-agnostic core reusable by any host, and holder-of-key binding
|
|
16
|
+
enforced at the inbound gate. Additive over 1.5.x.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- `./authz` authorization seam: a neutral, method-agnostic
|
|
21
|
+
`AuthorizationServerAdapter` port with a shared dispatch predicate, an
|
|
22
|
+
`AuthorizationServerRegistry` that routes a tool's protection to one adapter,
|
|
23
|
+
and a generic-OIDC reference adapter under `authz/oidc/` (mandatory S256 PKCE,
|
|
24
|
+
RFC 8707 resource binding, injectable fetch seam — no named vendor IdP, per
|
|
25
|
+
the donation's vendor-neutrality). The `AuthorizationRequirement` union
|
|
26
|
+
(`oauth`/`mdl`/`idv`/`credential`/`none`) anticipates further adapters as
|
|
27
|
+
siblings of `oidc/`.
|
|
28
|
+
- `AccountabilityContext` projection (agent → accountable-admin → user →
|
|
29
|
+
intent) that feeds the policy principal's `responsibleParty`; `orgRootDid` is
|
|
30
|
+
a forward-compatible slot pending the organization root identity.
|
|
31
|
+
- A deterministic, network-free in-memory OIDC example exercising the full
|
|
32
|
+
authorization path. Additive; no new runtime dependency (zod, jose, Web
|
|
33
|
+
Crypto only).
|
|
34
|
+
- `GrantStore` provider + `MemoryGrantStore` reference implementation: the
|
|
35
|
+
post-approval counterpart to `ResumeTokenStore`. A grant binds to the agent
|
|
36
|
+
DID (durable authority) and optionally to a session (the confused-deputy-safe,
|
|
37
|
+
no-paste retry convenience — a grant bound to one session is never returned to
|
|
38
|
+
another). Soft revocation, TTL cleanup, lookup by agent or session. The memory
|
|
39
|
+
impl is the dev/reference store; production injects Redis / a Durable Object /
|
|
40
|
+
a database behind the same interface (mirroring `NonceCacheProvider`).
|
|
41
|
+
- **Holder-of-key binding** at the inbound gate (spec §11.8). A delegation
|
|
42
|
+
credential is a bearer token, so the caller must now prove possession of the
|
|
43
|
+
delegation subject's key on the request itself. For a `did:key` subject the
|
|
44
|
+
DID encodes the public key, so binding needs no new credential fields and no
|
|
45
|
+
new crypto: `assertHolderBinding` verifies the request proof against the key
|
|
46
|
+
derived from the subject DID — a stolen-credential replay fails signature
|
|
47
|
+
binding, a tampered request fails content binding, and a proof minted for
|
|
48
|
+
another server fails audience binding (RFC 8707). The client half
|
|
49
|
+
(`generateRequestProof`, request-only with a fresh nonce per call) and the PEP
|
|
50
|
+
half (`assertHolderBinding`) ship in `delegation/holder-binding`. Opt-in.
|
|
51
|
+
- Framework-agnostic delegation **chain-enforcement core**
|
|
52
|
+
(`validateDelegationChain`, with the injected `DelegationCredentialVerifierPort`
|
|
53
|
+
and `RevocationChecker` ports, plus `validateScopeAttenuation` /
|
|
54
|
+
`getDelegationScopes`), lifted out of the `with-kya-os` middleware closure so
|
|
55
|
+
the leaf→root chain walk, scope attenuation, audience / confused-deputy
|
|
56
|
+
binding (§11.6), and ancestor-revocation rules run identically in any host
|
|
57
|
+
(MCP middleware, an HTTP PEP, the conformance harness) instead of a
|
|
58
|
+
per-transport fork. Dependencies are injected as ports; nothing imports a
|
|
59
|
+
transport. Includes the correctness fix behind the new graph-backed
|
|
60
|
+
`RevocationChecker` (reference adapter `CascadingRevocationManager`): a
|
|
61
|
+
cascade-revoked ancestor is now caught even when the leaf's own StatusList bit
|
|
62
|
+
never flipped. Exported from `@kya-os/mcp/delegation`.
|
|
63
|
+
- `NoopFetchProvider` — the offline `FetchProvider` fallback (used when the
|
|
64
|
+
runtime exposes no global `fetch`) extracted from an inline literal into a
|
|
65
|
+
named, exported class alongside `RuntimeFetchProvider`, and reused at the
|
|
66
|
+
holder-binding gate.
|
|
67
|
+
- `WebCryptoProvider` — an isomorphic `CryptoProvider` backed by the WebCrypto
|
|
68
|
+
API (`globalThis.crypto.subtle`, Ed25519), so an edge runtime (Cloudflare
|
|
69
|
+
Workers, Deno, browsers, Node 20+) can drive `ProofVerifier` without
|
|
70
|
+
`node:crypto`. Mirrors `NodeCryptoProvider`'s key formats exactly — raw
|
|
71
|
+
32-byte Ed25519 keys, base64-encoded; `sha256:<hex>` digests — so the two are
|
|
72
|
+
drop-in interchangeable: a proof signed under one verifies under the other,
|
|
73
|
+
with byte-identical signatures. Exported from `@kya-os/mcp/providers`.
|
|
74
|
+
|
|
8
75
|
## [1.5.0] - 2026-06-01
|
|
9
76
|
|
|
10
77
|
Exposes the policy-request projection as a reusable primitive and adds a
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DelegationCredentialSubject } from '../types/protocol.js';
|
|
2
|
+
import type { PolicyRequestInput } from '../policy/projection.js';
|
|
3
|
+
/**
|
|
4
|
+
* The accountability chain behind an agent action: agent -> accountable admin
|
|
5
|
+
* -> user -> intent. It is a read-only projection of a delegation credential
|
|
6
|
+
* subject, assembled so policy enforcement has auditable provenance for who is
|
|
7
|
+
* answerable for an action.
|
|
8
|
+
*
|
|
9
|
+
* `accountableAdminDid` is the organization/responsible-admin rung. Today it is
|
|
10
|
+
* sourced from the credential `controller`; when a dedicated org-admin identity
|
|
11
|
+
* lands it will be populated from there instead. `orgRootDid` is a
|
|
12
|
+
* forward-compatible slot that stays undefined until the Org Root DID work
|
|
13
|
+
* exists — defined now so the contract is stable for downstream consumers.
|
|
14
|
+
*/
|
|
15
|
+
export interface AccountabilityContext {
|
|
16
|
+
/** The agent acting (delegation subject). */
|
|
17
|
+
agentDid: string;
|
|
18
|
+
/** The accountable admin / responsible party, when known. */
|
|
19
|
+
accountableAdminDid?: string;
|
|
20
|
+
/** The end user on whose behalf the agent acts, when known. */
|
|
21
|
+
userDid?: string;
|
|
22
|
+
/** The organization root identity. Forward-compatible; unpopulated today. */
|
|
23
|
+
orgRootDid?: string;
|
|
24
|
+
/** The delegated scopes — the coarse statement of intent. */
|
|
25
|
+
scopes: string[];
|
|
26
|
+
}
|
|
27
|
+
/** Project the accountability chain from a delegation credential subject. */
|
|
28
|
+
export declare function projectAccountability(subject: DelegationCredentialSubject): AccountabilityContext;
|
|
29
|
+
/**
|
|
30
|
+
* Map an accountability context onto the policy principal so a PolicyEngine can
|
|
31
|
+
* gate on accountability. The accountable admin becomes `responsibleParty`,
|
|
32
|
+
* which is emitted only when present (matching buildPolicyRequest's contract).
|
|
33
|
+
*/
|
|
34
|
+
export declare function accountabilityToPolicyPrincipal(context: AccountabilityContext): PolicyRequestInput['principal'];
|
|
35
|
+
//# sourceMappingURL=accountability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountability.d.ts","sourceRoot":"","sources":["../../src/authz/accountability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,2BAA2B,GACnC,qBAAqB,CAUvB;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,qBAAqB,GAC7B,kBAAkB,CAAC,WAAW,CAAC,CAOjC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Project the accountability chain from a delegation credential subject. */
|
|
2
|
+
export function projectAccountability(subject) {
|
|
3
|
+
const { delegation } = subject;
|
|
4
|
+
const context = {
|
|
5
|
+
agentDid: delegation.subjectDid,
|
|
6
|
+
scopes: delegation.scopes ?? [],
|
|
7
|
+
};
|
|
8
|
+
if (delegation.controller)
|
|
9
|
+
context.accountableAdminDid = delegation.controller;
|
|
10
|
+
if (delegation.userDid)
|
|
11
|
+
context.userDid = delegation.userDid;
|
|
12
|
+
// orgRootDid intentionally left undefined until Org Root DID exists.
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Map an accountability context onto the policy principal so a PolicyEngine can
|
|
17
|
+
* gate on accountability. The accountable admin becomes `responsibleParty`,
|
|
18
|
+
* which is emitted only when present (matching buildPolicyRequest's contract).
|
|
19
|
+
*/
|
|
20
|
+
export function accountabilityToPolicyPrincipal(context) {
|
|
21
|
+
return {
|
|
22
|
+
agentDid: context.agentDid,
|
|
23
|
+
...(context.accountableAdminDid
|
|
24
|
+
? { responsibleParty: context.accountableAdminDid }
|
|
25
|
+
: {}),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=accountability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountability.js","sourceRoot":"","sources":["../../src/authz/accountability.ts"],"names":[],"mappings":"AA4BA,6EAA6E;AAC7E,MAAM,UAAU,qBAAqB,CACnC,OAAoC;IAEpC,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC/B,MAAM,OAAO,GAA0B;QACrC,QAAQ,EAAE,UAAU,CAAC,UAAU;QAC/B,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,EAAE;KAChC,CAAC;IACF,IAAI,UAAU,CAAC,UAAU;QAAE,OAAO,CAAC,mBAAmB,GAAG,UAAU,CAAC,UAAU,CAAC;IAC/E,IAAI,UAAU,CAAC,OAAO;QAAE,OAAO,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IAC7D,qEAAqE;IACrE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC7C,OAA8B;IAE9B,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,GAAG,CAAC,OAAO,CAAC,mBAAmB;YAC7B,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,mBAAmB,EAAE;YACnD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { NeedsAuthorizationError } from '../types/protocol.js';
|
|
2
|
+
import type { VerifyDelegationResult } from '../auth/types.js';
|
|
3
|
+
import type { AuthorizationRequirement, ToolProtection } from './requirement.js';
|
|
4
|
+
/**
|
|
5
|
+
* Parameters handed to an adapter when it initiates an authorization flow for a
|
|
6
|
+
* protected tool. The adapter turns these into a `needs_authorization`
|
|
7
|
+
* challenge the agent surfaces to the user.
|
|
8
|
+
*/
|
|
9
|
+
export interface FlowParams {
|
|
10
|
+
/** The protection (tool + requirement) that triggered the flow. */
|
|
11
|
+
protection: ToolProtection;
|
|
12
|
+
/** The agent DID requesting access. */
|
|
13
|
+
agentDid: string;
|
|
14
|
+
/** Where the authorization server should return control after consent. */
|
|
15
|
+
redirectUri: string;
|
|
16
|
+
/** Opaque value echoed back to correlate the result with this request. */
|
|
17
|
+
state: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The authorization-server port.
|
|
21
|
+
*
|
|
22
|
+
* One adapter per authorization *method* (`type`). KYA-OS owns the neutral
|
|
23
|
+
* requirement/result vocabulary; an adapter renders the method-specific
|
|
24
|
+
* behavior: decide whether it applies, produce a challenge, verify a result.
|
|
25
|
+
* Implement this to back authorization with a generic OIDC provider (a
|
|
26
|
+
* reference adapter ships in this package), or any downstream identity system.
|
|
27
|
+
* The shape mirrors the policy seam: a small, neutral interface with a
|
|
28
|
+
* reference implementation and pluggable downstream adapters.
|
|
29
|
+
*/
|
|
30
|
+
export interface AuthorizationServerAdapter {
|
|
31
|
+
/** The {@link AuthorizationRequirement} discriminant this adapter handles. */
|
|
32
|
+
readonly type: AuthorizationRequirement['type'];
|
|
33
|
+
/** Whether this adapter must run for the given tool protection. */
|
|
34
|
+
isRequired(protection: ToolProtection): boolean;
|
|
35
|
+
/** Produce a `needs_authorization` challenge for an unmet requirement. */
|
|
36
|
+
initiateFlow(params: FlowParams): Promise<NeedsAuthorizationError>;
|
|
37
|
+
/** Verify a returned authorization result into a delegation outcome. */
|
|
38
|
+
verifyAuthorization(flowState: string, result: unknown): Promise<VerifyDelegationResult>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Shared dispatch predicate: a protection is handled by the adapter whose
|
|
42
|
+
* `type` equals the protection's requirement discriminant. Every adapter's
|
|
43
|
+
* `isRequired` is built on this, so dispatch stays consistent across adapters
|
|
44
|
+
* (DRY) and the registry can route a protection to exactly one adapter.
|
|
45
|
+
*/
|
|
46
|
+
export declare function requirementMatchesAdapter(adapterType: AuthorizationRequirement['type'], protection: ToolProtection): boolean;
|
|
47
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/authz/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEjF;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,UAAU,EAAE,cAAc,CAAC;IAC3B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,0BAA0B;IACzC,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAEhD,mEAAmE;IACnE,UAAU,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC;IAEhD,0EAA0E;IAC1E,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAEnE,wEAAwE;IACxE,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC1F;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,wBAAwB,CAAC,MAAM,CAAC,EAC7C,UAAU,EAAE,cAAc,GACzB,OAAO,CAET"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared dispatch predicate: a protection is handled by the adapter whose
|
|
3
|
+
* `type` equals the protection's requirement discriminant. Every adapter's
|
|
4
|
+
* `isRequired` is built on this, so dispatch stays consistent across adapters
|
|
5
|
+
* (DRY) and the registry can route a protection to exactly one adapter.
|
|
6
|
+
*/
|
|
7
|
+
export function requirementMatchesAdapter(adapterType, protection) {
|
|
8
|
+
return protection.requirement.type === adapterType;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/authz/adapter.ts"],"names":[],"mappings":"AA6CA;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACvC,WAA6C,EAC7C,UAA0B;IAE1B,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,KAAK,WAAW,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { NeedsAuthorizationError } from '../../types/protocol.js';
|
|
2
|
+
import type { VerifyDelegationResult } from '../../auth/types.js';
|
|
3
|
+
import type { PolicyRequestInput } from '../../policy/projection.js';
|
|
4
|
+
/**
|
|
5
|
+
* A deterministic, network-free demonstration of the authorization seam.
|
|
6
|
+
*
|
|
7
|
+
* Wires the generic-OIDC reference adapter into a registry and backs its single
|
|
8
|
+
* IdP call (the token exchange) with an in-memory token endpoint, so the full
|
|
9
|
+
* path runs edge to edge with zero network: protect a tool -> resolve the
|
|
10
|
+
* adapter -> produce a challenge -> verify the returned code -> map to a
|
|
11
|
+
* delegation outcome -> derive the policy principal. This is the reliable,
|
|
12
|
+
* CI-safe showcase of the pluggable adapter pattern; richer live-IdP demos bind
|
|
13
|
+
* the same port without changing the core.
|
|
14
|
+
*/
|
|
15
|
+
export interface InMemoryFlowParams {
|
|
16
|
+
toolName: string;
|
|
17
|
+
requiredScopes: string[];
|
|
18
|
+
agentDid: string;
|
|
19
|
+
accountableAdminDid?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface InMemoryFlowOutcome {
|
|
22
|
+
challenge: NeedsAuthorizationError;
|
|
23
|
+
result: VerifyDelegationResult;
|
|
24
|
+
policyPrincipal: PolicyRequestInput['principal'];
|
|
25
|
+
/** Count of real (non in-memory) network calls — always 0 here. */
|
|
26
|
+
networkCalls: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function runInMemoryAuthorizationFlow(params: InMemoryFlowParams): Promise<InMemoryFlowOutcome>;
|
|
29
|
+
//# sourceMappingURL=inmemory-oidc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inmemory-oidc.d.ts","sourceRoot":"","sources":["../../../src/authz/examples/inmemory-oidc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAMrE;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,eAAe,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACjD,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;CACtB;AAwBD,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { AuthorizationServerRegistry } from '../registry.js';
|
|
2
|
+
import { GenericOidcAdapter } from '../oidc/oidc-adapter.js';
|
|
3
|
+
import { accountabilityToPolicyPrincipal } from '../accountability.js';
|
|
4
|
+
/** An in-memory token endpoint standing in for a live OIDC provider. */
|
|
5
|
+
function inMemoryTokenEndpoint(grantedScopes) {
|
|
6
|
+
let external = 0;
|
|
7
|
+
const fetchImpl = async (url, init) => {
|
|
8
|
+
// Only the configured in-memory token endpoint is served; anything else
|
|
9
|
+
// would be a real network call, which this example never makes.
|
|
10
|
+
if (url !== 'memory://idp/token') {
|
|
11
|
+
external += 1;
|
|
12
|
+
throw new Error(`unexpected external call to ${url}`);
|
|
13
|
+
}
|
|
14
|
+
const body = String(init?.body ?? '');
|
|
15
|
+
if (!body.includes('grant_type=authorization_code') || !body.includes('code_verifier=')) {
|
|
16
|
+
return new Response('invalid_request', { status: 400 });
|
|
17
|
+
}
|
|
18
|
+
return new Response(JSON.stringify({ access_token: 'memory-access-token', token_type: 'Bearer', scope: grantedScopes.join(' ') }), { status: 200, headers: { 'content-type': 'application/json' } });
|
|
19
|
+
};
|
|
20
|
+
return { fetchImpl, externalCalls: () => external };
|
|
21
|
+
}
|
|
22
|
+
export async function runInMemoryAuthorizationFlow(params) {
|
|
23
|
+
const { fetchImpl, externalCalls } = inMemoryTokenEndpoint(params.requiredScopes);
|
|
24
|
+
const adapter = new GenericOidcAdapter({
|
|
25
|
+
type: 'oauth',
|
|
26
|
+
issuer: 'memory://idp',
|
|
27
|
+
authorizationEndpoint: 'memory://idp/authorize',
|
|
28
|
+
tokenEndpoint: 'memory://idp/token',
|
|
29
|
+
clientId: 'example-agent-client',
|
|
30
|
+
scopes: params.requiredScopes,
|
|
31
|
+
resource: 'memory://resource/mcp',
|
|
32
|
+
fetchImpl,
|
|
33
|
+
});
|
|
34
|
+
const registry = new AuthorizationServerRegistry();
|
|
35
|
+
registry.register(adapter);
|
|
36
|
+
registry.seal();
|
|
37
|
+
const protection = {
|
|
38
|
+
toolName: params.toolName,
|
|
39
|
+
requirement: { type: 'oauth', provider: 'generic-oidc', requiredScopes: params.requiredScopes },
|
|
40
|
+
};
|
|
41
|
+
const resolved = registry.resolve(protection);
|
|
42
|
+
if (!resolved)
|
|
43
|
+
throw new Error('no adapter resolved for the protected tool');
|
|
44
|
+
const state = 'example-state';
|
|
45
|
+
const challenge = await resolved.initiateFlow({
|
|
46
|
+
protection,
|
|
47
|
+
agentDid: params.agentDid,
|
|
48
|
+
redirectUri: 'memory://app/callback',
|
|
49
|
+
state,
|
|
50
|
+
});
|
|
51
|
+
// The user "authorizes": the provider redirects back with a code + state.
|
|
52
|
+
const result = await resolved.verifyAuthorization(challenge.resumeToken, {
|
|
53
|
+
code: 'example-auth-code',
|
|
54
|
+
state,
|
|
55
|
+
});
|
|
56
|
+
const accountability = {
|
|
57
|
+
agentDid: params.agentDid,
|
|
58
|
+
accountableAdminDid: params.accountableAdminDid,
|
|
59
|
+
scopes: result.credential?.scopes ?? [],
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
challenge,
|
|
63
|
+
result,
|
|
64
|
+
policyPrincipal: accountabilityToPolicyPrincipal(accountability),
|
|
65
|
+
networkCalls: externalCalls(),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=inmemory-oidc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inmemory-oidc.js","sourceRoot":"","sources":["../../../src/authz/examples/inmemory-oidc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authorization-server seam for KYA-OS.
|
|
3
|
+
*
|
|
4
|
+
* A neutral, pluggable authorization layer mirroring the policy seam: a small
|
|
5
|
+
* port ({@link AuthorizationServerAdapter}), a registry that routes a tool's
|
|
6
|
+
* protection to an adapter, a generic-OIDC reference adapter, and the
|
|
7
|
+
* accountability projection that feeds the policy principal. Concrete vendor
|
|
8
|
+
* adapters (commercial identity providers, an identity-provider plugin) live
|
|
9
|
+
* downstream and bind the same port without changing this core.
|
|
10
|
+
*/
|
|
11
|
+
export { AuthorizationRequirementSchema, ToolProtectionSchema, type AuthorizationRequirement, type ToolProtection, } from './requirement.js';
|
|
12
|
+
export { requirementMatchesAdapter, type AuthorizationServerAdapter, type FlowParams, } from './adapter.js';
|
|
13
|
+
export { buildAuthorizeUrl, type AuthorizeUrlParams } from './oidc/authorize.js';
|
|
14
|
+
export { buildAuthorizationServerMetadata, buildProtectedResourceMetadata, type AuthorizationServerMetadata, type AuthorizationServerMetadataInput, type ProtectedResourceMetadata, type ProtectedResourceMetadataInput, } from './oidc/metadata.js';
|
|
15
|
+
export { isS256ChallengeMethod, computeS256Challenge, verifyS256Challenge, type S256, } from './oidc/pkce.js';
|
|
16
|
+
export { GenericOidcAdapter, type GenericOidcAdapterConfig, type FetchImpl, } from './oidc/oidc-adapter.js';
|
|
17
|
+
export { AuthorizationServerRegistry } from './registry.js';
|
|
18
|
+
export { projectAccountability, accountabilityToPolicyPrincipal, type AccountabilityContext, } from './accountability.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/authz/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,UAAU,GAChB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,OAAO,EACL,gCAAgC,EAChC,8BAA8B,EAC9B,KAAK,2BAA2B,EAChC,KAAK,gCAAgC,EACrC,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,GACpC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,IAAI,GACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,KAAK,SAAS,GACf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EACL,qBAAqB,EACrB,+BAA+B,EAC/B,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authorization-server seam for KYA-OS.
|
|
3
|
+
*
|
|
4
|
+
* A neutral, pluggable authorization layer mirroring the policy seam: a small
|
|
5
|
+
* port ({@link AuthorizationServerAdapter}), a registry that routes a tool's
|
|
6
|
+
* protection to an adapter, a generic-OIDC reference adapter, and the
|
|
7
|
+
* accountability projection that feeds the policy principal. Concrete vendor
|
|
8
|
+
* adapters (commercial identity providers, an identity-provider plugin) live
|
|
9
|
+
* downstream and bind the same port without changing this core.
|
|
10
|
+
*/
|
|
11
|
+
export { AuthorizationRequirementSchema, ToolProtectionSchema, } from './requirement.js';
|
|
12
|
+
export { requirementMatchesAdapter, } from './adapter.js';
|
|
13
|
+
export { buildAuthorizeUrl } from './oidc/authorize.js';
|
|
14
|
+
export { buildAuthorizationServerMetadata, buildProtectedResourceMetadata, } from './oidc/metadata.js';
|
|
15
|
+
export { isS256ChallengeMethod, computeS256Challenge, verifyS256Challenge, } from './oidc/pkce.js';
|
|
16
|
+
export { GenericOidcAdapter, } from './oidc/oidc-adapter.js';
|
|
17
|
+
export { AuthorizationServerRegistry } from './registry.js';
|
|
18
|
+
export { projectAccountability, accountabilityToPolicyPrincipal, } from './accountability.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/authz/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,8BAA8B,EAC9B,oBAAoB,GAGrB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,yBAAyB,GAG1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAA2B,MAAM,qBAAqB,CAAC;AAEjF,OAAO,EACL,gCAAgC,EAChC,8BAA8B,GAK/B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,GAEpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,GAGnB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EACL,qBAAqB,EACrB,+BAA+B,GAEhC,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { S256 } from './pkce.js';
|
|
2
|
+
/**
|
|
3
|
+
* Inputs to the authorization-code request URL. PKCE is mandatory and S256-only
|
|
4
|
+
* (see {@link S256}); the optional `resource` is an RFC 8707 resource indicator
|
|
5
|
+
* binding the issued token's audience to the protected resource.
|
|
6
|
+
*/
|
|
7
|
+
export interface AuthorizeUrlParams {
|
|
8
|
+
authorizationEndpoint: string;
|
|
9
|
+
clientId: string;
|
|
10
|
+
redirectUri: string;
|
|
11
|
+
scopes: string[];
|
|
12
|
+
state: string;
|
|
13
|
+
codeChallenge: string;
|
|
14
|
+
/** Always S256; present so a caller cannot silently request `plain`. */
|
|
15
|
+
codeChallengeMethod?: S256;
|
|
16
|
+
/** RFC 8707 resource indicator (optional). */
|
|
17
|
+
resource?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build an OAuth 2.1 authorization-code request URL. Pure: constructs a URL,
|
|
21
|
+
* no network. Throws if a non-S256 challenge method is supplied — S256 is
|
|
22
|
+
* mandatory.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildAuthorizeUrl(params: AuthorizeUrlParams): string;
|
|
25
|
+
//# sourceMappingURL=authorize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../../src/authz/oidc/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,mBAAmB,CAAC,EAAE,IAAI,CAAC;IAC3B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAkBpE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build an OAuth 2.1 authorization-code request URL. Pure: constructs a URL,
|
|
3
|
+
* no network. Throws if a non-S256 challenge method is supplied — S256 is
|
|
4
|
+
* mandatory.
|
|
5
|
+
*/
|
|
6
|
+
export function buildAuthorizeUrl(params) {
|
|
7
|
+
const method = params.codeChallengeMethod ?? 'S256';
|
|
8
|
+
if (method !== 'S256') {
|
|
9
|
+
throw new Error(`Unsupported code_challenge_method "${method}"; S256 is required.`);
|
|
10
|
+
}
|
|
11
|
+
const url = new URL(params.authorizationEndpoint);
|
|
12
|
+
url.searchParams.set('response_type', 'code');
|
|
13
|
+
url.searchParams.set('client_id', params.clientId);
|
|
14
|
+
url.searchParams.set('redirect_uri', params.redirectUri);
|
|
15
|
+
url.searchParams.set('scope', params.scopes.join(' '));
|
|
16
|
+
url.searchParams.set('state', params.state);
|
|
17
|
+
url.searchParams.set('code_challenge', params.codeChallenge);
|
|
18
|
+
url.searchParams.set('code_challenge_method', 'S256');
|
|
19
|
+
if (params.resource !== undefined) {
|
|
20
|
+
url.searchParams.set('resource', params.resource);
|
|
21
|
+
}
|
|
22
|
+
return url.toString();
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=authorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../../src/authz/oidc/authorize.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA0B;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC;IACpD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,sBAAsB,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAClD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC9C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IACzD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAC7D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authorization-server and protected-resource metadata assembly (RFC 8414 and
|
|
3
|
+
* RFC 9728). Pure: shapes the metadata objects from configuration, no network.
|
|
4
|
+
* S256-only PKCE is advertised unconditionally.
|
|
5
|
+
*/
|
|
6
|
+
export interface AuthorizationServerMetadataInput {
|
|
7
|
+
issuer: string;
|
|
8
|
+
authorizationEndpoint: string;
|
|
9
|
+
tokenEndpoint: string;
|
|
10
|
+
scopesSupported?: string[];
|
|
11
|
+
/** Defaults to ['code'] (authorization-code only). */
|
|
12
|
+
responseTypesSupported?: string[];
|
|
13
|
+
/** Defaults to ['authorization_code', 'refresh_token']. */
|
|
14
|
+
grantTypesSupported?: string[];
|
|
15
|
+
jwksUri?: string;
|
|
16
|
+
revocationEndpoint?: string;
|
|
17
|
+
}
|
|
18
|
+
/** RFC 8414 Authorization Server Metadata (S256-only PKCE). */
|
|
19
|
+
export interface AuthorizationServerMetadata {
|
|
20
|
+
issuer: string;
|
|
21
|
+
authorization_endpoint: string;
|
|
22
|
+
token_endpoint: string;
|
|
23
|
+
response_types_supported: string[];
|
|
24
|
+
grant_types_supported: string[];
|
|
25
|
+
code_challenge_methods_supported: ['S256'];
|
|
26
|
+
scopes_supported?: string[];
|
|
27
|
+
jwks_uri?: string;
|
|
28
|
+
revocation_endpoint?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function buildAuthorizationServerMetadata(input: AuthorizationServerMetadataInput): AuthorizationServerMetadata;
|
|
31
|
+
export interface ProtectedResourceMetadataInput {
|
|
32
|
+
resource: string;
|
|
33
|
+
authorizationServers: string[];
|
|
34
|
+
scopesSupported?: string[];
|
|
35
|
+
}
|
|
36
|
+
/** RFC 9728 Protected Resource Metadata. */
|
|
37
|
+
export interface ProtectedResourceMetadata {
|
|
38
|
+
resource: string;
|
|
39
|
+
authorization_servers: string[];
|
|
40
|
+
scopes_supported?: string[];
|
|
41
|
+
}
|
|
42
|
+
export declare function buildProtectedResourceMetadata(input: ProtectedResourceMetadataInput): ProtectedResourceMetadata;
|
|
43
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../../src/authz/oidc/metadata.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,sDAAsD;IACtD,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,2DAA2D;IAC3D,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,+DAA+D;AAC/D,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gCAAgC,EAAE,CAAC,MAAM,CAAC,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,gCAAgC,GACtC,2BAA2B,CAa7B;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,4CAA4C;AAC5C,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,8BAA8B,GACpC,yBAAyB,CAO3B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authorization-server and protected-resource metadata assembly (RFC 8414 and
|
|
3
|
+
* RFC 9728). Pure: shapes the metadata objects from configuration, no network.
|
|
4
|
+
* S256-only PKCE is advertised unconditionally.
|
|
5
|
+
*/
|
|
6
|
+
export function buildAuthorizationServerMetadata(input) {
|
|
7
|
+
const metadata = {
|
|
8
|
+
issuer: input.issuer,
|
|
9
|
+
authorization_endpoint: input.authorizationEndpoint,
|
|
10
|
+
token_endpoint: input.tokenEndpoint,
|
|
11
|
+
response_types_supported: input.responseTypesSupported ?? ['code'],
|
|
12
|
+
grant_types_supported: input.grantTypesSupported ?? ['authorization_code', 'refresh_token'],
|
|
13
|
+
code_challenge_methods_supported: ['S256'],
|
|
14
|
+
};
|
|
15
|
+
if (input.scopesSupported)
|
|
16
|
+
metadata.scopes_supported = input.scopesSupported;
|
|
17
|
+
if (input.jwksUri)
|
|
18
|
+
metadata.jwks_uri = input.jwksUri;
|
|
19
|
+
if (input.revocationEndpoint)
|
|
20
|
+
metadata.revocation_endpoint = input.revocationEndpoint;
|
|
21
|
+
return metadata;
|
|
22
|
+
}
|
|
23
|
+
export function buildProtectedResourceMetadata(input) {
|
|
24
|
+
const metadata = {
|
|
25
|
+
resource: input.resource,
|
|
26
|
+
authorization_servers: input.authorizationServers,
|
|
27
|
+
};
|
|
28
|
+
if (input.scopesSupported)
|
|
29
|
+
metadata.scopes_supported = input.scopesSupported;
|
|
30
|
+
return metadata;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/authz/oidc/metadata.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4BH,MAAM,UAAU,gCAAgC,CAC9C,KAAuC;IAEvC,MAAM,QAAQ,GAAgC;QAC5C,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,sBAAsB,EAAE,KAAK,CAAC,qBAAqB;QACnD,cAAc,EAAE,KAAK,CAAC,aAAa;QACnC,wBAAwB,EAAE,KAAK,CAAC,sBAAsB,IAAI,CAAC,MAAM,CAAC;QAClE,qBAAqB,EAAE,KAAK,CAAC,mBAAmB,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC;QAC3F,gCAAgC,EAAE,CAAC,MAAM,CAAC;KAC3C,CAAC;IACF,IAAI,KAAK,CAAC,eAAe;QAAE,QAAQ,CAAC,gBAAgB,GAAG,KAAK,CAAC,eAAe,CAAC;IAC7E,IAAI,KAAK,CAAC,OAAO;QAAE,QAAQ,CAAC,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC;IACrD,IAAI,KAAK,CAAC,kBAAkB;QAAE,QAAQ,CAAC,mBAAmB,GAAG,KAAK,CAAC,kBAAkB,CAAC;IACtF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAeD,MAAM,UAAU,8BAA8B,CAC5C,KAAqC;IAErC,MAAM,QAAQ,GAA8B;QAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,qBAAqB,EAAE,KAAK,CAAC,oBAAoB;KAClD,CAAC;IACF,IAAI,KAAK,CAAC,eAAe;QAAE,QAAQ,CAAC,gBAAgB,GAAG,KAAK,CAAC,eAAe,CAAC;IAC7E,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type NeedsAuthorizationError } from '../../types/protocol.js';
|
|
2
|
+
import type { VerifyDelegationResult } from '../../auth/types.js';
|
|
3
|
+
import type { AuthorizationServerAdapter, FlowParams } from '../adapter.js';
|
|
4
|
+
import type { ToolProtection } from '../requirement.js';
|
|
5
|
+
/** A minimal fetch signature — the injectable seam for IdP HTTP calls. */
|
|
6
|
+
export type FetchImpl = (url: string, init?: {
|
|
7
|
+
method?: string;
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
body?: string;
|
|
10
|
+
}) => Promise<Response>;
|
|
11
|
+
export interface GenericOidcAdapterConfig {
|
|
12
|
+
readonly type: 'oauth';
|
|
13
|
+
issuer: string;
|
|
14
|
+
authorizationEndpoint: string;
|
|
15
|
+
tokenEndpoint: string;
|
|
16
|
+
clientId: string;
|
|
17
|
+
scopes: string[];
|
|
18
|
+
/** RFC 8707 resource indicator bound into the authorize request + token audience. */
|
|
19
|
+
resource?: string;
|
|
20
|
+
clientSecret?: string;
|
|
21
|
+
/** Resume-token lifetime in ms (default 10 minutes). */
|
|
22
|
+
resumeTokenTtlMs?: number;
|
|
23
|
+
/** Injected fetch seam; defaults to the runtime global fetch. */
|
|
24
|
+
fetchImpl?: FetchImpl;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Reference generic-OIDC authorization-server adapter.
|
|
28
|
+
*
|
|
29
|
+
* Implements {@link AuthorizationServerAdapter} for a standards-only OpenID
|
|
30
|
+
* Connect / OAuth 2.1 provider. No named vendor identity provider appears
|
|
31
|
+
* here; concrete commercial providers are downstream adapters binding the same
|
|
32
|
+
* port. The pure pieces (authorize URL, PKCE) run inline; the single IdP HTTP
|
|
33
|
+
* call (token
|
|
34
|
+
* exchange) goes through an injectable fetch seam, so the adapter is fully
|
|
35
|
+
* deterministic under test with no network.
|
|
36
|
+
*
|
|
37
|
+
* The PKCE code verifier is held server-side keyed by the resume token and is
|
|
38
|
+
* never placed in the authorization URL — only the S256 challenge travels.
|
|
39
|
+
*/
|
|
40
|
+
export declare class GenericOidcAdapter implements AuthorizationServerAdapter {
|
|
41
|
+
private readonly config;
|
|
42
|
+
readonly type: "oauth";
|
|
43
|
+
private readonly pending;
|
|
44
|
+
private readonly fetchImpl;
|
|
45
|
+
constructor(config: GenericOidcAdapterConfig);
|
|
46
|
+
isRequired(protection: ToolProtection): boolean;
|
|
47
|
+
initiateFlow(params: FlowParams): Promise<NeedsAuthorizationError>;
|
|
48
|
+
verifyAuthorization(flowState: string, result: unknown): Promise<VerifyDelegationResult>;
|
|
49
|
+
/** Test/inspection seam: the pending code verifier for a resume token, if any. */
|
|
50
|
+
pendingVerifierFor(resumeToken: string): string | undefined;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=oidc-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc-adapter.d.ts","sourceRoot":"","sources":["../../../src/authz/oidc/oidc-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,0BAA0B,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACxE,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAUD;;;;;;;;;;;;;GAaG;AACH,qBAAa,kBAAmB,YAAW,0BAA0B;IAKvD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAET,MAAM,EAAE,wBAAwB;IAI7D,UAAU,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO;IAIzC,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAsClE,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAqD9F,kFAAkF;IAClF,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG5D"}
|