@kya-os/mcp-i
Version:
The TypeScript MCP framework with identity features built-in
182 lines (181 loc) • 5.88 kB
TypeScript
/**
* Delegation Verification Module
*
* This module provides the core interfaces and implementations for verifying
* agent delegations in the MCP-I bouncer architecture.
*
* Architecture:
* - DelegationVerifier: Abstract interface (Dependency Inversion Principle)
* - Concrete adapters: CloudflareKVVerifier, AgentShieldAPIVerifier
* - Factory: createDelegationVerifier() selects adapter based on config
*
* Related: PHASE_1_XMCP_I_SERVER.md Epic 1 (Delegation Storage Layer)
*/
import { DelegationRecord } from '@kya-os/contracts/delegation';
import { z } from 'zod';
/**
* Result of delegation verification
*/
export interface VerifyDelegationResult {
/** Whether delegation exists and is valid */
valid: boolean;
/** The delegation record (if found) */
delegation?: DelegationRecord;
/** Reason for invalid result */
reason?: string;
/** Whether result came from cache */
cached?: boolean;
}
/**
* Options for delegation verification
*/
export interface VerifyDelegationOptions {
/** Skip cache and force fresh lookup */
skipCache?: boolean;
/** Maximum cache age in milliseconds (default: 60000 = 1 minute) */
maxCacheAge?: number;
}
/**
* Abstract Delegation Verifier Interface
*
* Implementations:
* - CloudflareKVDelegationVerifier (local storage)
* - AgentShieldAPIDelegationVerifier (remote managed service)
*
* Follows Interface Segregation Principle (SOLID) - minimal required methods
*/
export interface DelegationVerifier {
/**
* Verify if agent has valid delegation for requested scopes
*
* @param agentDid - DID of the agent requesting access
* @param scopes - Required permission scopes
* @param options - Verification options
* @returns Verification result
*/
verify(agentDid: string, scopes: string[], options?: VerifyDelegationOptions): Promise<VerifyDelegationResult>;
/**
* Get delegation record by ID
*
* @param delegationId - Unique delegation identifier
* @returns Delegation record or null if not found
*/
get(delegationId: string): Promise<DelegationRecord | null>;
/**
* Store/update delegation record
*
* @param delegation - Delegation record to store
*/
put(delegation: DelegationRecord): Promise<void>;
/**
* Revoke delegation
*
* @param delegationId - Delegation ID to revoke
* @param reason - Optional revocation reason
*/
revoke(delegationId: string, reason?: string): Promise<void>;
/**
* Close any open connections (cleanup)
*/
close?(): Promise<void>;
}
/**
* Helper: Extract scopes from delegation (handles both simple and CRISP formats)
*
* @param delegation - Delegation record
* @returns Array of scope strings
*/
export declare function extractScopes(delegation: DelegationRecord): string[];
/**
* Helper: Check if delegation scopes satisfy required scopes
*
* @param delegationScopes - Scopes granted by delegation
* @param requiredScopes - Scopes required for operation
* @returns true if all required scopes are present
*/
export declare function checkScopes(delegationScopes: string[], requiredScopes: string[]): boolean;
/**
* Helper: Validate delegation record completeness
*
* @param delegation - Delegation to validate
* @returns Validation result with reason
*/
export declare function validateDelegation(delegation: DelegationRecord): {
valid: boolean;
reason?: string;
};
/**
* Validation schema for verify method inputs
*/
export declare const VerifyDelegationInputSchema: z.ZodObject<{
agentDid: z.ZodString;
scopes: z.ZodArray<z.ZodString, "many">;
options: z.ZodOptional<z.ZodObject<{
skipCache: z.ZodOptional<z.ZodBoolean>;
maxCacheAge: z.ZodOptional<z.ZodNumber>;
}, "strip", z.ZodTypeAny, {
skipCache?: boolean | undefined;
maxCacheAge?: number | undefined;
}, {
skipCache?: boolean | undefined;
maxCacheAge?: number | undefined;
}>>;
}, "strip", z.ZodTypeAny, {
scopes: string[];
agentDid: string;
options?: {
skipCache?: boolean | undefined;
maxCacheAge?: number | undefined;
} | undefined;
}, {
scopes: string[];
agentDid: string;
options?: {
skipCache?: boolean | undefined;
maxCacheAge?: number | undefined;
} | undefined;
}>;
/**
* Configuration for delegation verifiers
*/
export interface DelegationVerifierConfig {
/** Verifier type */
type: 'cloudflare-kv' | 'agentshield-api' | 'memory';
/** Cloudflare KV namespace (for cloudflare-kv type) */
kvNamespace?: {
get(key: string): Promise<string | null>;
put(key: string, value: string): Promise<void>;
delete(key: string): Promise<void>;
list(options?: {
prefix?: string;
}): Promise<{
keys: Array<{
name: string;
}>;
}>;
};
/** AgentShield API configuration (for agentshield-api type) */
agentshield?: {
apiUrl: string;
apiKey: string;
};
/** Cache TTL in milliseconds (default: 60000 = 1 minute) */
cacheTtl?: number;
/** Enable debug logging */
debug?: boolean;
}
/**
* Factory: Create delegation verifier based on config
*
* Note: We import all adapters statically for better compatibility.
* Tree-shaking will remove unused adapters in production builds.
*
* Note: AgentShield API responses use standard wrapper format
* { success: boolean, data: {...}, metadata?: {...} } as defined in
* @kya-os/contracts/agentshield-api. This is handled in the
* AgentShieldAPIDelegationVerifier implementation.
*
* @param config - Verifier configuration
* @returns DelegationVerifier instance
*/
export declare function createDelegationVerifier(config: DelegationVerifierConfig): DelegationVerifier;