@vess-id/ai-identity 0.14.0-alpha.3 → 0.14.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/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config/index.ts","../src/did/key-manager.ts","../src/storage/filesystem-key-storage.ts","../src/storage/memory-key-storage.ts","../src/utils/sdjwt-client.ts","../src/utils/crypto.ts","../src/did/did-utils.ts","../src/agent/agent-did-manager.ts","../src/did/agent.ts","../src/identity/user-identity-manager.ts","../src/vc/vc-manager.ts","../src/vp/vp-manager.ts","../src/vp/kb-jwt-builder.ts","../src/tool/tool-manager.ts","../src/grant/grant-manager.ts","../src/client.ts","../src/identity/user-key-pair-manager.ts","../src/identity/device-enroll-manager.ts","../src/types/agent.ts","../src/types/vc.ts","../src/types/errors.ts","../src/types/permission-vc.ts","../src/types/grant.ts","../src/types/receipt.ts","../src/types/intent.ts","../src/types/oauth.ts","../src/types/invitation.ts","../src/types/permission-mode.ts","../src/types/tier.ts","../src/utils/sdjwt-disclosure.ts","../src/vc/api-vc-manager.ts","../src/constraint/constraint-evaluator.ts","../src/state/json-state-store.ts","../src/gateway/gateway-client.ts","../src/auth/auth-provider.ts","../src/registry/action-registry.ts","../src/registry/providers.ts","../src/registry/access-orchestrator.ts","../src/registry/action-registry-json.ts","../src/registry/resource-types.ts","../src/registry/action-aliases.ts","../src/registry/action-normalizer.ts","../src/registry/reauth-constants.ts","../src/registry/action-summary.ts","../src/resolver/target-resolver.ts","../src/utils/action-classifier.ts","../src/utils/tier-utils.ts","../src/utils/freemail-domains.ts","../src/internal-signature/canonical.ts","../src/internal-signature/signer.ts","../src/policy/cedar-engine.ts","../src/registry/action-risk.ts","../src/policy/cedar-entities.ts","../src/policy/decision.ts"],"sourcesContent":["// Main client\nexport { AIdentityClient, getClient } from './client'\n\n// Configuration\nexport { configure, AIdentityConfig } from './config'\n\n// Managers\nexport { AgentManager } from './did/agent'\nexport { KeyManager } from './did/key-manager'\nexport { AgentDIDManager } from './agent/agent-did-manager'\nexport { UserIdentityManager } from './identity/user-identity-manager'\nexport { UserKeyPairManager } from './identity/user-key-pair-manager'\nexport type { KeyPairGenerationResult } from './identity/user-key-pair-manager'\nexport {\n DeviceEnrollManager,\n DeviceEnrollStartParams,\n DeviceEnrollServerSideParams,\n DeviceEnrollStartResult,\n DeviceEnrollPollResult,\n} from './identity/device-enroll-manager'\nexport { VCManager } from './vc/vc-manager'\nexport { APIVCManager } from './vc/api-vc-manager'\nexport { VPManager } from './vp/vp-manager'\nexport {\n buildKbJwtPayload,\n KB_JWT_DEFAULT_LIFETIME_SECONDS,\n normalizeDomain,\n readVcExpSeconds,\n KbJwtPayload,\n BuildKbJwtPayloadArgs,\n BuildKbJwtPayloadDeps,\n} from './vp/kb-jwt-builder'\nexport { ToolManager, ToolDefinition } from './tool/tool-manager'\n\nexport {\n getDefaultDisclosureFields,\n DisclosureFields,\n} from './utils/sdjwt-disclosure'\n\n// Constraint Evaluation\nexport {\n ConstraintEvaluator,\n ConstraintEvaluatorOptions,\n defaultConstraintEvaluator,\n evaluateConstraints,\n} from './constraint/constraint-evaluator'\n\n// Storage providers\nexport * from './storage'\n\n// State persistence\nexport type { IStateStore } from './state/state-store.interface'\nexport { JsonStateStore } from './state/json-state-store'\n\n// Gateway client\nexport { GatewayClient, GatewayError } from './gateway/gateway-client'\nexport type {\n GatewayEvent,\n GetEventsResponse,\n GetEventsOptions,\n AckEventResponse,\n ApiKeyValidationResult,\n} from './gateway/gateway-client'\n\n// Auth provider\nexport { AuthProvider } from './auth/auth-provider'\nexport type { AuthState } from './auth/auth-provider'\n\nexport * from './registry'\n\n// Action summary utilities\nexport { generateActionSummary, generateActionParamsDisplay, ACTION_PARAMS_MAX_SIZE } from './registry/action-summary'\nexport type { ActionParamDisplay } from './registry/action-summary'\n\n// Utils\nexport { generateKeyPair, signJWT, verifyJWT, generateNonce } from './utils/crypto'\nexport { SDJwtClient } from './utils/sdjwt-client'\n\n// DID Utilities\nexport {\n createDidJwk,\n extractPublicKey,\n extractPublicKeyFromDid,\n isValidDidJwk,\n getKeyIdFromDid,\n publicKeysMatch,\n} from './did/did-utils'\n\n// Target Resolution\nexport { TargetResolver, extractProjectKey } from './resolver/target-resolver'\n\n// Types (consolidated from @vess-id/ai-identity-types)\nexport * from './types'\n\n// Cedar + RAR Phase 1 — explicit named re-exports for ergonomic imports.\n// Note: these are also available via `export * from './types'` above; the\n// explicit re-exports here pin the public surface for assert:publish-surface.\nexport type {\n PolicyRef,\n PolicyRefInline,\n PolicyRefReference,\n PermissionVcClaims_V2,\n PermissionVcClaims_V3,\n Phase1VcLayer,\n VcApprovalClaim,\n} from './types/permission-vc'\nexport {\n isPolicyRefInline,\n isPolicyRefReference,\n PHASE_1_VC_LAYER,\n buildPhase1VcClaims,\n} from './types/permission-vc'\nexport type {\n CedarSchema,\n CedarPolicySetHandle,\n CedarSchemaHandle,\n CedarDecisionValue,\n CedarDecisionDiagnostic,\n} from './types/cedar-policy'\n\n// Action Classifier\nexport { isWriteAction, WRITE_ACTION_NAMES } from './utils/action-classifier'\n\n// Tier Utilities\nexport { resolveUserTier, getTierLimits, isUnlimited } from './utils/tier-utils'\n\n// Freemail domain list — grant internalDomains validation guard\n// (block *@<freemail> domain-wide wildcard; individual addresses allowed)\nexport { FREEMAIL_DOMAINS, isFreemailDomain } from './utils/freemail-domains'\n\n// Internal-signature (HMAC) — P1-A14a-2d\n// Single source of truth for canonical-string + signer used by\n// api (verify) / remote-mcp (sign) / slack-bot (sign).\nexport * from './internal-signature'\n\n// Cedar policy engine (Phase 1 Step 1)\nexport {\n createCedarEngine,\n CedarEngineUnavailableError,\n CedarParseError,\n} from './policy'\nexport type {\n CedarEngine,\n CedarDecision,\n CedarEntity,\n CedarEvaluateRequest,\n EvaluateInput,\n EvaluateResult,\n CedarError,\n SchemaHandle,\n PolicySetHandle,\n} from './policy'\n\n// Phase 2-1-H — structured policy validation error surface for the\n// lint API + grant-manage UI. `buildValidationErrors` is exposed so\n// callers (API service) can re-classify off-line if cedar-wasm changes.\nexport {\n buildValidationErrors,\n classifyCedarErrorMessage,\n} from './policy'\nexport type { PolicyValidationError } from './policy'\n\n// Cedar unification Step 1 — 7-value Decision + Cedar entity builder\nexport { buildCedarEntities, DECISION_VALUES, isDecision } from './policy'\nexport type {\n CedarEntitiesInput,\n CedarEntityDescriptor,\n Decision,\n} from './policy'\nexport { resolveActionRisk } from './registry/action-risk'\nexport type { ActionRisk } from './registry/action-risk'\n\n// Version\nexport const version = '0.0.1'\n","export interface AIdentityConfig {\n didApi?: {\n baseUrl: string\n apiKey?: string\n bearerToken?: string\n }\n issuerApi?: {\n baseUrl: string\n apiKey?: string\n bearerToken?: string\n }\n verifierApi?: {\n baseUrl: string\n apiKey?: string\n bearerToken?: string\n }\n proxyApi?: {\n baseUrl: string\n }\n storage?: {\n keyStorePath?: string // Default: ~/.vess-aidentity/keys\n }\n}\n\nlet globalConfig: AIdentityConfig = {}\n\nexport function configure(config: AIdentityConfig): void {\n globalConfig = { ...globalConfig, ...config }\n}\n\nexport function getConfig(): AIdentityConfig {\n return globalConfig\n}\n\nexport function getDidApiUrl(path: string): string {\n const baseUrl = globalConfig.didApi?.baseUrl || process.env.DID_API_BASE_URL\n if (!baseUrl) {\n throw new Error('DID API base URL not configured')\n }\n return `${baseUrl}${path}`\n}\n\nexport function getIssuerApiUrl(path: string): string {\n const baseUrl = globalConfig.issuerApi?.baseUrl || process.env.ISSUER_API_BASE_URL\n if (!baseUrl) {\n throw new Error('Issuer API base URL not configured')\n }\n return `${baseUrl}${path}`\n}\n\nexport function getVerifierApiUrl(path: string): string {\n const baseUrl = globalConfig.verifierApi?.baseUrl || process.env.VERIFIER_API_BASE_URL\n if (!baseUrl) {\n throw new Error('Verifier API base URL not configured')\n }\n return `${baseUrl}${path}`\n}\n\nexport function getApiHeaders(apiType: 'did' | 'issuer' | 'verifier'): any {\n const headers: any = {\n 'Content-Type': 'application/json',\n }\n\n let apiKey: string | undefined\n let bearerToken: string | undefined\n\n switch (apiType) {\n case 'did':\n apiKey = globalConfig.didApi?.apiKey || process.env.DID_API_KEY\n bearerToken = globalConfig.didApi?.bearerToken\n break\n case 'issuer':\n apiKey = globalConfig.issuerApi?.apiKey || process.env.ISSUER_API_KEY\n bearerToken = globalConfig.issuerApi?.bearerToken\n break\n case 'verifier':\n apiKey = globalConfig.verifierApi?.apiKey || process.env.VERIFIER_API_KEY\n bearerToken = globalConfig.verifierApi?.bearerToken\n break\n }\n\n if (apiKey) {\n headers['x-api-key'] = apiKey\n }\n if (bearerToken) {\n headers['Authorization'] = `Bearer ${bearerToken}`\n }\n\n return headers\n}\n","import * as crypto from 'crypto'\nimport { KeyStorageProvider, FilesystemKeyStorage } from '../storage'\nimport { getConfig } from '../config'\n\nexport class KeyManager {\n private encryptionKey?: Buffer\n private storageProvider: KeyStorageProvider\n\n constructor(password?: string, storageProvider?: KeyStorageProvider) {\n if (password) {\n // Derive encryption key from password\n this.encryptionKey = crypto.scryptSync(password, 'aidentity-salt', 32)\n }\n\n // Use provided storage provider or default to filesystem\n this.storageProvider = storageProvider || this.createDefaultStorageProvider()\n }\n\n private createDefaultStorageProvider(): KeyStorageProvider {\n const config = getConfig()\n return new FilesystemKeyStorage({\n type: 'filesystem',\n options: {\n path: config.storage?.keyStorePath,\n },\n })\n }\n\n async storeKey(did: string, privateKey: any): Promise<void> {\n const keyData = JSON.stringify(privateKey)\n const encrypted = this.encrypt(keyData)\n // const keyId = this.getKeyId(did)\n\n await this.storageProvider.store(did, encrypted)\n }\n\n async getKey(did: string): Promise<any | null> {\n // const keyId = this.getKeyId(did)\n const encrypted = await this.storageProvider.retrieve(did)\n\n if (!encrypted) {\n return null\n }\n\n const decrypted = this.decrypt(encrypted)\n return JSON.parse(decrypted)\n }\n\n async deleteKey(did: string): Promise<void> {\n // const keyId = this.getKeyId(did)\n await this.storageProvider.delete(did)\n }\n\n async listDids(): Promise<string[]> {\n const keyIds = await this.storageProvider.list()\n return keyIds.map(keyId => this.didFromKeyId(keyId))\n }\n\n /**\n * Check if storage is available\n */\n async isAvailable(): Promise<boolean> {\n return this.storageProvider.isAvailable()\n }\n\n // private getKeyId(did: string): string {\n // // Use SHA256 hash to create short, storage-safe identifier\n // return crypto.createHash('sha256').update(did).digest('hex').substring(0, 16)\n // }\n\n private didFromKeyId(keyId: string): string {\n // For now, we cannot reverse the hash, so we need to store the mapping\n // This is a limitation of the current design.\n // TODO: Consider storing DID->keyId mapping in storage provider\n return keyId // Temporary fallback\n }\n\n private encrypt(data: string): string {\n if (!this.encryptionKey) {\n // No encryption if no password provided\n return Buffer.from(data).toString('base64')\n }\n\n const iv = crypto.randomBytes(16)\n const cipher = crypto.createCipheriv('aes-256-gcm', this.encryptionKey, iv)\n\n let encrypted = cipher.update(data, 'utf8', 'base64')\n encrypted += cipher.final('base64')\n\n const authTag = cipher.getAuthTag()\n\n // Combine iv, authTag, and encrypted data\n const combined = Buffer.concat([iv, authTag, Buffer.from(encrypted, 'base64')])\n\n return combined.toString('base64')\n }\n\n private decrypt(encrypted: string): string {\n if (!this.encryptionKey) {\n // No decryption if no password provided\n return Buffer.from(encrypted, 'base64').toString('utf-8')\n }\n\n const combined = Buffer.from(encrypted, 'base64')\n\n // Extract iv, authTag, and encrypted data\n const iv = combined.subarray(0, 16)\n const authTag = combined.subarray(16, 32)\n const encryptedData = combined.subarray(32)\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', this.encryptionKey, iv)\n decipher.setAuthTag(authTag)\n\n let decrypted = decipher.update(encryptedData, undefined, 'utf8')\n decrypted += decipher.final('utf8')\n\n return decrypted\n }\n}\n","import * as fs from 'fs/promises'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { KeyStorageProvider, KeyStorageConfig } from './key-storage.interface'\n\n/**\n * Filesystem-based key storage provider\n */\nexport class FilesystemKeyStorage implements KeyStorageProvider {\n private keyStorePath: string\n\n constructor(config?: KeyStorageConfig) {\n this.keyStorePath = config?.options?.path || path.join(os.homedir(), '.vess-aidentity', 'keys')\n }\n\n async store(id: string, encryptedKey: string): Promise<void> {\n await this.ensureKeyStoreExists()\n const keyPath = this.getKeyPath(id)\n await fs.writeFile(keyPath, encryptedKey, 'utf-8')\n }\n\n async retrieve(id: string): Promise<string | null> {\n const keyPath = this.getKeyPath(id)\n\n try {\n return await fs.readFile(keyPath, 'utf-8')\n } catch (error) {\n if ((error as any).code === 'ENOENT') {\n return null\n }\n throw error\n }\n }\n\n async delete(id: string): Promise<void> {\n const keyPath = this.getKeyPath(id)\n\n try {\n await fs.unlink(keyPath)\n } catch (error) {\n if ((error as any).code !== 'ENOENT') {\n throw error\n }\n }\n }\n\n async list(): Promise<string[]> {\n await this.ensureKeyStoreExists()\n\n const files = await fs.readdir(this.keyStorePath)\n return files\n .filter(f => f.endsWith('.key'))\n .map(f => f.replace('.key', ''))\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n await this.ensureKeyStoreExists()\n return true\n } catch {\n return false\n }\n }\n\n private async ensureKeyStoreExists(): Promise<void> {\n try {\n await fs.access(this.keyStorePath)\n } catch {\n await fs.mkdir(this.keyStorePath, { recursive: true })\n }\n }\n\n private getKeyPath(id: string): string {\n return path.join(this.keyStorePath, `${id}.key`)\n }\n}","import { KeyStorageProvider } from './key-storage.interface'\n\n/**\n * In-memory key storage provider (for testing)\n */\nexport class MemoryKeyStorage implements KeyStorageProvider {\n private keys: Map<string, string> = new Map()\n\n async store(id: string, encryptedKey: string): Promise<void> {\n this.keys.set(id, encryptedKey)\n }\n\n async retrieve(id: string): Promise<string | null> {\n return this.keys.get(id) || null\n }\n\n async delete(id: string): Promise<void> {\n this.keys.delete(id)\n }\n\n async list(): Promise<string[]> {\n return Array.from(this.keys.keys())\n }\n\n async isAvailable(): Promise<boolean> {\n return true\n }\n\n /**\n * Clear all stored keys (for testing)\n */\n clear(): void {\n this.keys.clear()\n }\n}","import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc'\nimport { ES256, digest, generateSalt } from '@sd-jwt/crypto-nodejs'\nimport { generateKeyPair, getSigner, getVerifier } from './crypto'\nimport { KeyManager } from '../did/key-manager'\nimport { extractPublicKeyFromDid } from '../did/did-utils'\nimport type { DisclosureFrame } from '@sd-jwt/types'\nimport type { JWK } from 'jose'\nimport { subtle } from 'node:crypto'\n\nexport class SDJwtClient {\n private static instances: Map<string, SDJwtVcInstance> = new Map()\n private static keyManager: KeyManager\n private static signerCache: Map<string, any> = new Map()\n private static verifierCache: Map<string, any> = new Map()\n\n private constructor() {}\n\n /**\n * Initialize with KeyManager for DID-based key management\n */\n public static setKeyManager(keyManager: KeyManager) {\n this.keyManager = keyManager\n }\n\n /**\n * Get SDJwtVcInstance for issuer role (VC issuance)\n */\n public static async getIssuerInstance(issuerDid: string): Promise<SDJwtVcInstance> {\n const cacheKey = `${issuerDid}:issuer`\n if (!this.instances.has(cacheKey)) {\n const instance = await this.createInstance(issuerDid, 'issuer')\n this.instances.set(cacheKey, instance)\n }\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Get SDJwtVcInstance for holder role (VP presentation)\n */\n public static async getHolderInstance(holderDid: string): Promise<SDJwtVcInstance> {\n const cacheKey = `${holderDid}:holder`\n if (!this.instances.has(cacheKey)) {\n const instance = await this.createInstance(holderDid, 'holder')\n this.instances.set(cacheKey, instance)\n }\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Get SDJwtVcInstance with specified role (backward compatibility)\n */\n public static async getSDJwtInstance(\n did: string,\n options?: { role?: 'issuer' | 'holder' }\n ): Promise<SDJwtVcInstance> {\n const role = options?.role || 'issuer' // Default to issuer for backward compatibility\n return role === 'holder' ? this.getHolderInstance(did) : this.getIssuerInstance(did)\n }\n\n /**\n * Create a new SDJwtVcInstance with DID-based keys and role\n */\n private static async createInstance(\n did: string,\n role: 'issuer' | 'holder'\n ): Promise<SDJwtVcInstance> {\n if (!this.keyManager) {\n this.keyManager = new KeyManager()\n }\n\n // Get private key for DID\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error(`Private key not found for ${role}: ${did}`)\n }\n\n try {\n // Check cache first\n const signerCacheKey = `signer:${did}`\n const verifierCacheKey = `verifier:${did}`\n\n let signer = this.signerCache.get(signerCacheKey)\n let verifier = this.verifierCache.get(verifierCacheKey)\n\n if (!signer) {\n signer = await getSigner(privateKey)\n this.signerCache.set(signerCacheKey, signer)\n }\n\n if (!verifier) {\n // Extract public key from private key for verifier\n const { d, key_ops, ...publicKey } = privateKey // Remove private component and key_ops\n const publicKeyForVerifier = {\n ...publicKey,\n key_ops: ['verify'], // Set correct key operations for verifier\n }\n verifier = await getVerifier(publicKeyForVerifier)\n this.verifierCache.set(verifierCacheKey, verifier)\n }\n\n // Configure based on role\n const config: any = {\n signer,\n verifier,\n signAlg: ES256.alg,\n hasher: digest,\n hashAlg: 'sha-256',\n saltGenerator: generateSalt,\n }\n\n // Add key binding configuration only for holder role\n if (role === 'holder') {\n config.kbSigner = signer\n config.kbSignAlg = ES256.alg\n }\n\n return new SDJwtVcInstance(config)\n } catch (error) {\n console.error('❌ Error creating SDJwtVcInstance:', error)\n throw error\n }\n }\n\n /**\n * Claims that MUST NOT be selectively disclosable.\n *\n * - cnf: Proof of Possession binding (RFC 7800). If disclosable, Holder can\n * hide cnf to bypass PoP verification and transfer VC to another party.\n * - Standard JWT registered claims (iss, sub, exp, iat, nbf, jti) must\n * always be visible for signature verification and expiry checks.\n * - vct: SD-JWT VC credential type discriminator.\n */\n private static readonly NEVER_DISCLOSE = new Set([\n 'cnf', 'iss', 'sub', 'exp', 'iat', 'nbf', 'jti', 'vct',\n ])\n\n /**\n * Create disclosure frame for selective disclosure\n */\n public static createDisclosureFrame<T extends Record<string, any>>(\n claims: T,\n selectivelyDisclosable: string[] = []\n ): DisclosureFrame<T> {\n const frame: any = {}\n\n // Filter selectively disclosable fields to only include fields that actually exist in claims\n // and are not in the NEVER_DISCLOSE set\n const existingDisclosableFields = selectivelyDisclosable.filter(field =>\n claims.hasOwnProperty(field) && !this.NEVER_DISCLOSE.has(field)\n )\n\n // Make specified fields selectively disclosable\n if (existingDisclosableFields.length > 0) {\n frame._sd = existingDisclosableFields\n frame._sd_decoy = Math.max(0, Math.floor(existingDisclosableFields.length * 0.1))\n }\n\n // Process nested objects — skip fields that must never be disclosed\n for (const [key, value] of Object.entries(claims)) {\n if (this.NEVER_DISCLOSE.has(key)) continue\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recursively process nested objects\n const nestedKeys = Object.keys(value)\n const nestedFrame = this.createDisclosureFrame(\n value,\n nestedKeys // Make all nested fields disclosable\n )\n frame[key] = nestedFrame\n }\n }\n\n return frame as DisclosureFrame<T>\n }\n\n /**\n * Issue an SD-JWT with selective disclosure\n */\n public static async issueSDJWT(\n payload: Record<string, any>,\n _privateKey: any, // Not used since we get key from KeyManager based on issuer DID\n selectiveDisclosureFields: string[] = []\n ): Promise<string> {\n const issuerDid = payload.iss || 'unknown'\n const sdjwtInstance = await this.getIssuerInstance(issuerDid)\n\n // Ensure payload has required vct field for SD-JWT VC\n const vcPayload = {\n vct: 'IdentityCredential', // Default VC type\n ...payload,\n }\n\n // Create disclosure frame for selective disclosure\n const disclosureFrame = this.createDisclosureFrame(vcPayload, selectiveDisclosureFields)\n\n return await sdjwtInstance.issue(vcPayload as any, disclosureFrame)\n }\n\n /**\n * Verify an SD-JWT\n */\n public static async verifySDJWT(\n credential: string\n ): Promise<{ valid: boolean; payload?: any; error?: string }> {\n try {\n // Parse to get issuer from the SD-JWT\n const parts = credential.split('~')\n if (parts.length === 0) {\n return { valid: false, error: 'Invalid SD-JWT format' }\n }\n\n const jwt = parts[0]\n const jwtParts = jwt.split('.')\n if (jwtParts.length !== 3) {\n return { valid: false, error: 'Invalid JWT format in SD-JWT' }\n }\n\n const payload = JSON.parse(Buffer.from(jwtParts[1], 'base64url').toString())\n const issuerDid = payload.iss\n\n if (!issuerDid) {\n return { valid: false, error: 'Issuer DID not found in SD-JWT' }\n }\n\n const sdjwtInstance = await this.getIssuerInstance(issuerDid)\n\n // Verify the SD-JWT\n const verificationResult = await sdjwtInstance.verify(credential)\n const claims = await sdjwtInstance.getClaims(credential)\n\n return {\n valid: true,\n payload: {\n ...verificationResult.payload,\n claims,\n },\n }\n } catch (error: any) {\n return {\n valid: false,\n error: error.message,\n }\n }\n }\n\n /**\n * Legacy methods for backward compatibility\n */\n public static async createSignerVerifier() {\n const { privateKey, publicKey } = await this.generateKeyPair()\n return {\n signer: await getSigner(privateKey),\n verifier: await getVerifier(publicKey),\n }\n }\n\n public static async generateKeyPair() {\n return await generateKeyPair()\n }\n\n /**\n * Clear caches for optimization\n */\n public static clearCaches(): void {\n this.instances.clear()\n this.signerCache.clear()\n this.verifierCache.clear()\n }\n\n /**\n * Clear cache for specific issuer\n */\n public static clearIssuerCache(issuerDid: string): void {\n this.instances.delete(issuerDid)\n this.signerCache.delete(`signer:${issuerDid}`)\n this.verifierCache.delete(`verifier:${issuerDid}`)\n }\n\n /**\n * Get cache statistics\n */\n public static getCacheStats(): {\n instanceCount: number\n signerCount: number\n verifierCount: number\n } {\n return {\n instanceCount: this.instances.size,\n signerCount: this.signerCache.size,\n verifierCount: this.verifierCache.size,\n }\n }\n\n /**\n * Create a verifier function from an external public key\n * This is used for verifying SD-JWTs when you don't have the private key\n * (e.g., API side verifying credentials issued by MCP)\n */\n private static async getVerifierFromPublicKey(publicKey: JWK): Promise<(data: string, signature: string) => Promise<boolean>> {\n const key = await subtle.importKey(\n 'jwk',\n publicKey,\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true,\n ['verify']\n )\n\n return async (data: string, signatureBase64url: string) => {\n const encoder = new TextEncoder()\n const signature = Uint8Array.from(\n atob(signatureBase64url.replace(/-/g, '+').replace(/_/g, '/')),\n c => c.charCodeAt(0)\n )\n\n const isValid = await subtle.verify(\n {\n name: 'ECDSA',\n hash: { name: 'SHA-256' },\n },\n key,\n signature,\n encoder.encode(data)\n )\n\n return isValid\n }\n }\n\n /**\n * Get SDJwtVcInstance for verification with an external public key\n * Used when verifying credentials without having the issuer's private key\n */\n private static async getVerificationInstance(publicKey: JWK): Promise<SDJwtVcInstance> {\n const cacheKey = `verify:${JSON.stringify(publicKey)}`\n\n if (!this.instances.has(cacheKey)) {\n const dummySigner = async () => 'dummy'\n const verifier = await this.getVerifierFromPublicKey(publicKey)\n\n const instance = new SDJwtVcInstance({\n signer: dummySigner,\n verifier,\n signAlg: ES256.alg,\n hasher: digest,\n hashAlg: 'sha-256',\n saltGenerator: generateSalt,\n })\n\n this.instances.set(cacheKey, instance)\n }\n\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Get SDJwtVcInstance for decoding without verification\n */\n private static async getDecodingInstance(): Promise<SDJwtVcInstance> {\n const cacheKey = 'decode:dummy'\n\n if (!this.instances.has(cacheKey)) {\n const dummySigner = async () => 'dummy'\n const dummyVerifier = async () => false\n\n const instance = new SDJwtVcInstance({\n signer: dummySigner,\n verifier: dummyVerifier,\n signAlg: ES256.alg,\n hasher: digest,\n hashAlg: 'sha-256',\n saltGenerator: generateSalt,\n })\n\n this.instances.set(cacheKey, instance)\n }\n\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Verify an SD-JWT with an external public key\n * Use this when you have the issuer's public key but not their private key\n *\n * @param credential - The SD-JWT credential string\n * @param publicKey - The issuer's public key (JWK format)\n * @returns Verification result with valid flag and payload\n *\n * @example\n * ```typescript\n * const publicKey = extractPublicKeyFromDid(issuerDid)\n * const result = await SDJwtClient.verifyWithExternalKey(credential, publicKey)\n * if (result.valid) {\n * console.log('Verified claims:', result.payload.claims)\n * }\n * ```\n */\n public static async verifyWithExternalKey(\n credential: string,\n publicKey: JWK\n ): Promise<{ valid: boolean; payload?: any; claims?: any; error?: string }> {\n try {\n const sdJwtInstance = await this.getVerificationInstance(publicKey)\n\n // Verify the SD-JWT\n const verificationResult = await sdJwtInstance.verify(credential, {})\n\n if (!verificationResult) {\n return { valid: false, error: 'Verification failed' }\n }\n\n // Get disclosed claims\n const claims = await sdJwtInstance.getClaims(credential)\n\n return {\n valid: true,\n payload: verificationResult.payload,\n claims,\n }\n } catch (error: any) {\n return {\n valid: false,\n error: error.message,\n }\n }\n }\n\n /**\n * Verify an SD-JWT by extracting the issuer's public key from the DID\n * Automatically resolves did:jwk DIDs\n *\n * @param credential - The SD-JWT credential string\n * @returns Verification result with valid flag and payload\n *\n * @example\n * ```typescript\n * const result = await SDJwtClient.verifyWithIssuerDid(credential)\n * if (result.valid) {\n * console.log('Issuer:', result.payload.iss)\n * }\n * ```\n */\n public static async verifyWithIssuerDid(\n credential: string\n ): Promise<{ valid: boolean; payload?: any; claims?: any; issuerDid?: string; error?: string }> {\n try {\n // First decode to get the issuer DID\n const decoded = await this.decodeWithoutVerification(credential)\n\n if (!decoded.payload) {\n return { valid: false, error: 'Failed to decode credential' }\n }\n\n const issuerDid = decoded.payload.iss || decoded.payload.issuer\n\n if (!issuerDid || typeof issuerDid !== 'string') {\n return { valid: false, error: 'Issuer DID not found in credential' }\n }\n\n // Extract public key from DID\n const publicKey = extractPublicKeyFromDid(issuerDid)\n\n // Verify with the extracted public key\n const result = await this.verifyWithExternalKey(credential, publicKey)\n\n return {\n ...result,\n issuerDid,\n }\n } catch (error: any) {\n return {\n valid: false,\n error: error.message,\n }\n }\n }\n\n /**\n * Decode an SD-JWT without verification\n * Use this when you need to inspect the credential before verification\n * or when you don't have the issuer's public key\n *\n * WARNING: The returned payload has not been verified!\n * Only use this for inspection purposes, not for authorization decisions.\n *\n * @param credential - The SD-JWT credential string\n * @returns Decoded JWT payload, header, and disclosures\n *\n * @example\n * ```typescript\n * const decoded = await SDJwtClient.decodeWithoutVerification(credential)\n * console.log('Issuer (unverified):', decoded.payload?.iss)\n * console.log('Disclosures:', decoded.disclosures?.length)\n * ```\n */\n public static async decodeWithoutVerification(\n credential: string\n ): Promise<{\n payload?: any\n header?: any\n disclosures?: any[]\n claims?: any\n error?: string\n }> {\n try {\n const sdJwtInstance = await this.getDecodingInstance()\n const decoded = await sdJwtInstance.decode(credential)\n\n if (!decoded || !decoded.jwt) {\n return { error: 'Failed to decode SD-JWT' }\n }\n\n // Get claims with disclosures applied\n const claims = await decoded.getClaims(digest)\n\n return {\n payload: decoded.jwt.payload,\n header: decoded.jwt.header,\n disclosures: decoded.disclosures,\n claims,\n }\n } catch (error: any) {\n return { error: error.message }\n }\n }\n\n /**\n * Extract issuer DID from an SD-JWT without verification\n * Useful for determining the issuer before verification\n *\n * @param credential - The SD-JWT credential string\n * @returns The issuer DID or null if not found\n */\n public static extractIssuerDid(credential: string): string | null {\n try {\n const parts = credential.split('~')\n if (parts.length === 0) return null\n\n const jwt = parts[0]\n const jwtParts = jwt.split('.')\n if (jwtParts.length !== 3) return null\n\n const payload = JSON.parse(Buffer.from(jwtParts[1], 'base64url').toString())\n return payload.iss || payload.issuer || null\n } catch {\n return null\n }\n }\n}\n","import * as jose from 'jose'\nimport { v4 as uuidv4 } from 'uuid'\nimport { subtle } from 'node:crypto'\n\nexport interface KeyPair {\n publicKey: any\n privateKey: any\n}\n\nexport async function generateKeyPair(): Promise<KeyPair> {\n const keyPair = await subtle.generateKey(\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true, // extractable\n ['sign', 'verify']\n )\n\n // Export keys in JWK format\n const publicJwk = await subtle.exportKey('jwk', keyPair.publicKey)\n const privateJwk = await subtle.exportKey('jwk', keyPair.privateKey)\n\n // Add key ID\n const kid = uuidv4()\n ;(publicJwk as any).kid = kid\n ;(privateJwk as any).kid = kid\n\n // Add algorithm\n ;(publicJwk as any).alg = 'ES256'\n ;(privateJwk as any).alg = 'ES256'\n\n return {\n publicKey: publicJwk,\n privateKey: privateJwk,\n }\n}\n\nexport async function signJWT(\n payload: any,\n privateKey: any,\n options?: {\n issuer?: string\n audience?: string\n expiresIn?: string\n notBefore?: string\n subject?: string\n jti?: string\n }\n): Promise<string> {\n const alg = privateKey.alg || 'ES256'\n const key = await jose.importJWK(privateKey, alg)\n\n const jwt = new jose.SignJWT(payload)\n .setProtectedHeader({ alg, kid: privateKey.kid })\n .setIssuedAt()\n .setJti(options?.jti ?? uuidv4())\n\n if (options?.issuer) jwt.setIssuer(options.issuer)\n if (options?.audience) jwt.setAudience(options.audience)\n if (options?.expiresIn) jwt.setExpirationTime(options.expiresIn)\n if (options?.notBefore) jwt.setNotBefore(options.notBefore)\n if (options?.subject) jwt.setSubject(options.subject)\n\n return await jwt.sign(key)\n}\n\nexport async function verifyJWT(\n jwt: string,\n publicKey: any,\n options?: {\n issuer?: string\n audience?: string\n }\n): Promise<jose.JWTPayload> {\n const alg = publicKey.alg || 'ES256'\n const key = await jose.importJWK(publicKey, alg)\n\n const verifyOptions: jose.JWTVerifyOptions = {}\n if (options?.issuer) verifyOptions.issuer = options.issuer\n if (options?.audience) verifyOptions.audience = options.audience\n\n const { payload } = await jose.jwtVerify(jwt, key, verifyOptions)\n return payload\n}\n\nexport function generateNonce(): string {\n return uuidv4()\n}\n\nexport async function getSigner(privateKey: any) {\n try {\n const key = await subtle.importKey(\n 'jwk',\n privateKey,\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true,\n ['sign']\n )\n\n return async (data: string) => {\n const encoder = new TextEncoder()\n const signature = await subtle.sign(\n {\n name: 'ECDSA',\n hash: { name: 'SHA-256' },\n },\n key,\n encoder.encode(data)\n )\n\n const result = btoa(String.fromCharCode(...new Uint8Array(signature)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '') // Convert to base64url format\n\n return result\n }\n } catch (error) {\n console.error('Error in getSigner:', error instanceof Error ? error.message : 'Unknown error')\n console.error('Key algorithm:', privateKey?.alg || 'unknown')\n console.error('Key type:', privateKey?.kty || 'unknown')\n throw error\n }\n}\n\nexport async function getVerifier(publicKey: any) {\n const key = await subtle.importKey(\n 'jwk',\n publicKey,\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true,\n ['verify']\n )\n\n return async (data: string, signatureBase64url: string) => {\n const encoder = new TextEncoder()\n const signature = Uint8Array.from(\n atob(signatureBase64url.replace(/-/g, '+').replace(/_/g, '/')),\n c => c.charCodeAt(0)\n )\n\n const isValid = await subtle.verify(\n {\n name: 'ECDSA',\n hash: { name: 'SHA-256' },\n },\n key,\n signature,\n encoder.encode(data)\n )\n\n return isValid\n }\n}\n","/**\n * DID Utilities\n *\n * Common utility functions for DID operations.\n * These functions are shared across AgentDIDManager, EphemeralDIDManager,\n * UserIdentityManager, and UserRootDIDManager.\n */\n\nimport type { JWK } from 'jose'\n\n/**\n * Public key JWK properties for did:jwk creation\n */\nexport interface PublicKeyJWK {\n kty: string\n crv?: string\n x?: string\n y?: string\n use?: string\n alg?: string\n}\n\n/**\n * Create did:jwk from a public key JWK\n *\n * @param publicKey - The public key JWK (can include private key fields, they will be filtered)\n * @returns The did:jwk string\n *\n * @example\n * ```typescript\n * const keyPair = await SDJwtClient.generateKeyPair()\n * const did = createDidJwk(keyPair.publicKey)\n * // => did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6Ii4uLiIsInkiOiIuLi4ifQ\n * ```\n */\nexport function createDidJwk(publicKey: JWK | PublicKeyJWK): string {\n const publicJwk: PublicKeyJWK = {\n kty: publicKey.kty!,\n crv: publicKey.crv,\n x: publicKey.x,\n y: publicKey.y,\n use: publicKey.use,\n alg: publicKey.alg,\n }\n\n // Remove undefined values for cleaner encoding\n const cleanedJwk = Object.fromEntries(\n Object.entries(publicJwk).filter(([_, v]) => v !== undefined)\n )\n\n const encoded = Buffer.from(JSON.stringify(cleanedJwk)).toString('base64url')\n return `did:jwk:${encoded}`\n}\n\n/**\n * Extract public key JWK from a private key JWK\n *\n * @param privateKey - The private key JWK containing the 'd' parameter\n * @returns The public key JWK (without private key material)\n *\n * @example\n * ```typescript\n * const keyPair = await SDJwtClient.generateKeyPair()\n * const publicKey = extractPublicKey(keyPair.privateKey)\n * ```\n */\nexport function extractPublicKey(privateKey: JWK): JWK {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { d, key_ops, ...publicKey } = privateKey\n return publicKey as JWK\n}\n\n/**\n * Extract public key JWK from a did:jwk string\n *\n * @param did - The did:jwk string\n * @returns The public key JWK decoded from the DID\n * @throws Error if the DID is not in did:jwk format\n *\n * @example\n * ```typescript\n * const publicKey = extractPublicKeyFromDid('did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6Ii4uLiIsInkiOiIuLi4ifQ')\n * ```\n */\nexport function extractPublicKeyFromDid(did: string): JWK {\n if (!did.startsWith('did:jwk:')) {\n throw new Error('Only did:jwk format is supported')\n }\n\n const encoded = did.replace('did:jwk:', '')\n return JSON.parse(Buffer.from(encoded, 'base64url').toString()) as JWK\n}\n\n/**\n * Validate that a string is a valid did:jwk\n *\n * @param did - The string to validate\n * @returns true if valid did:jwk, false otherwise\n */\nexport function isValidDidJwk(did: string): boolean {\n if (!did.startsWith('did:jwk:')) {\n return false\n }\n\n try {\n const encoded = did.replace('did:jwk:', '')\n const decoded = JSON.parse(Buffer.from(encoded, 'base64url').toString())\n return typeof decoded === 'object' && decoded.kty !== undefined\n } catch {\n return false\n }\n}\n\n/**\n * Get the key ID (kid) from a did:jwk\n * Following the did:jwk specification, the key ID is the DID with #0 appended\n *\n * @param did - The did:jwk string\n * @returns The key ID\n */\nexport function getKeyIdFromDid(did: string): string {\n return `${did}#0`\n}\n\n/**\n * Compare two EC public key JWKs for equality.\n * Only compares canonical fields (kty, crv, x, y) to avoid\n * mismatches from optional fields like alg, use, kid, key_ops.\n * Returns false if any canonical field is missing or undefined.\n */\nexport function publicKeysMatch(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): boolean {\n if (!a.kty || !a.crv || !a.x || !a.y) return false\n if (!b.kty || !b.crv || !b.x || !b.y) return false\n return a.kty === b.kty && a.crv === b.crv && a.x === b.x && a.y === b.y\n}\n","import { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { createDidJwk, extractPublicKey } from '../did/did-utils'\n\n/**\n * Agent DID Manager\n * Manages DID generation and lifecycle for AI Agents specifically\n */\nexport class AgentDIDManager {\n private keyManager: KeyManager\n private agentDIDMap: Map<string, string> = new Map() // agentId -> DID mapping\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n }\n\n /**\n * Generate a new DID for an AI Agent\n */\n async generateAgentDID(agentId: string): Promise<string> {\n // Generate unique key pair for this agent\n const keyPair = await SDJwtClient.generateKeyPair()\n\n // Create did:jwk from public key\n const did = createDidJwk(keyPair.publicKey)\n\n // Store private key with agent-specific namespace\n await this.keyManager.storeKey(did, keyPair.privateKey)\n\n // Store agent ID -> DID mapping\n this.agentDIDMap.set(agentId, did)\n await this.saveAgentDIDMapping(agentId, did)\n\n return did\n }\n\n /**\n * Get DID for a specific agent\n */\n async getAgentDID(agentId: string): Promise<string> {\n // Check memory cache first\n if (this.agentDIDMap.has(agentId)) {\n return this.agentDIDMap.get(agentId)!\n }\n\n // Load from storage\n const did = await this.loadAgentDIDMapping(agentId)\n if (did) {\n this.agentDIDMap.set(agentId, did)\n return did\n }\n\n throw new Error(`No DID found for agent: ${agentId}`)\n }\n\n /**\n * Check if agent has a DID\n */\n async hasAgentDID(agentId: string): Promise<boolean> {\n try {\n await this.getAgentDID(agentId)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get agent's key pair\n */\n async getAgentKeyPair(agentId: string): Promise<any> {\n const did = await this.getAgentDID(agentId)\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error(`Private key not found for agent: ${agentId}`)\n }\n\n return {\n privateKey,\n publicKey: extractPublicKey(privateKey),\n }\n }\n\n /**\n * Delete agent DID and associated keys\n */\n async deleteAgentDID(agentId: string): Promise<void> {\n try {\n const did = await this.getAgentDID(agentId)\n\n // Delete private key\n await this.keyManager.deleteKey(did)\n\n // Remove from memory cache\n this.agentDIDMap.delete(agentId)\n\n // Remove from persistent storage\n await this.deleteAgentDIDMapping(agentId)\n } catch (error) {\n throw new Error(`Failed to delete agent DID: ${error}`)\n }\n }\n\n /**\n * List all agent DIDs\n */\n async listAgentDIDs(): Promise<Array<{ agentId: string; did: string }>> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingDir = path.join(os.homedir(), '.vess-aidentity', 'agent-dids')\n\n try {\n const files = await fs.readdir(mappingDir)\n const results: Array<{ agentId: string; did: string }> = []\n\n for (const file of files) {\n if (file.endsWith('.did')) {\n const agentId = file.replace('.did', '')\n try {\n const did = await this.getAgentDID(agentId)\n results.push({ agentId, did })\n } catch {\n // Skip invalid entries\n }\n }\n }\n\n return results\n } catch {\n return []\n }\n }\n\n\n /**\n * Save agent ID -> DID mapping to persistent storage\n */\n private async saveAgentDIDMapping(agentId: string, did: string): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingDir = path.join(os.homedir(), '.vess-aidentity', 'agent-dids')\n await fs.mkdir(mappingDir, { recursive: true })\n\n const mappingFile = path.join(mappingDir, `${agentId}.did`)\n await fs.writeFile(mappingFile, did, 'utf-8')\n }\n\n /**\n * Load agent ID -> DID mapping from persistent storage\n */\n private async loadAgentDIDMapping(agentId: string): Promise<string | null> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingFile = path.join(os.homedir(), '.vess', 'agent-dids', `${agentId}.did`)\n\n try {\n return await fs.readFile(mappingFile, 'utf-8')\n } catch {\n return null\n }\n }\n\n /**\n * Delete agent ID -> DID mapping from persistent storage\n */\n private async deleteAgentDIDMapping(agentId: string): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingFile = path.join(os.homedir(), '.vess', 'agent-dids', `${agentId}.did`)\n\n try {\n await fs.unlink(mappingFile)\n } catch {\n // File might not exist, ignore\n }\n }\n}\n","import { Agent, DIDDocument } from '../types'\nimport { getDidApiUrl, getApiHeaders } from '../config'\nimport { KeyManager } from './key-manager'\nimport { AgentDIDManager } from '../agent/agent-did-manager'\nimport { v4 as uuidv4 } from 'uuid'\n\nexport class AgentManager {\n private keyManager: KeyManager\n private agentDIDManager: AgentDIDManager\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n this.agentDIDManager = new AgentDIDManager(this.keyManager)\n }\n\n /**\n * Create a new AI agent with unique ID and DID\n */\n async create(metadata?: Record<string, any>): Promise<Agent & { id: string }> {\n // Generate unique agent ID\n const agentId = uuidv4()\n\n // Generate dedicated DID for this agent\n const agentDid = await this.agentDIDManager.generateAgentDID(agentId)\n\n // Create DID Document for the agent\n const didDocument = this.resolveDidJwkLocally(agentDid)\n\n // Create agent with ID and DID\n const agent: Agent & { id: string } = {\n id: agentId,\n did: agentDid,\n didDocument,\n createdAt: new Date().toISOString(),\n metadata,\n }\n\n // Optionally register with DID API (if configured)\n try {\n await this.registerDid(agent)\n } catch (error) {\n console.warn('Failed to register DID with API:', error)\n // Continue even if registration fails - DID:jwk works locally\n }\n\n return agent\n }\n\n /**\n * Get agent DID by agent ID\n */\n async getAgentDID(agentId: string): Promise<string> {\n return await this.agentDIDManager.getAgentDID(agentId)\n }\n\n /**\n * Get agent by ID\n */\n async getAgent(agentId: string): Promise<Agent & { id: string }> {\n const agentDid = await this.agentDIDManager.getAgentDID(agentId)\n const didDocument = await this.resolve(agentDid)\n\n return {\n id: agentId,\n did: agentDid,\n didDocument,\n createdAt: new Date().toISOString(), // TODO: Store actual creation time\n }\n }\n\n /**\n * Delete an agent and its DID\n */\n async deleteAgent(agentId: string): Promise<void> {\n await this.agentDIDManager.deleteAgentDID(agentId)\n }\n\n /**\n * Resolve a DID to get DID Document\n */\n async resolve(did: string): Promise<DIDDocument> {\n // For did:jwk, we can resolve locally\n if (did.startsWith('did:jwk:')) {\n return this.resolveDidJwkLocally(did)\n }\n\n // Otherwise, call DID API\n try {\n const response = await fetch(getDidApiUrl(`/api/v1/did/${encodeURIComponent(did)}`), {\n headers: getApiHeaders('did'),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to resolve DID: ${response.statusText}`)\n }\n\n const data = (await response.json()) as any\n return data.didDocument\n } catch (error) {\n throw new Error(`Failed to resolve DID: ${error}`)\n }\n }\n\n /**\n * Export agent with private key (for backup)\n */\n async export(did: string): Promise<{ agent: Agent; privateKey: any }> {\n const didDocument = await this.resolve(did)\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error(`Private key not found for DID: ${did}`)\n }\n\n const agent: Agent = {\n did,\n didDocument,\n createdAt: new Date().toISOString(),\n }\n\n return { agent, privateKey }\n }\n\n /**\n * Import agent from backup\n */\n async import(agent: Agent, privateKey: any): Promise<void> {\n await this.keyManager.storeKey(agent.did, privateKey)\n }\n\n /**\n * List all locally stored agents\n */\n async list(): Promise<Array<Agent & { id: string }>> {\n const agentDIDs = await this.agentDIDManager.listAgentDIDs()\n const agents: Array<Agent & { id: string }> = []\n\n for (const { agentId, did } of agentDIDs) {\n try {\n const didDocument = await this.resolve(did)\n agents.push({\n id: agentId,\n did,\n didDocument,\n createdAt: new Date().toISOString(), // TODO: Store actual creation time\n })\n } catch (error) {\n console.warn(`Failed to resolve Agent DID ${did}:`, error)\n }\n }\n\n return agents\n }\n\n private createDidDocument(did: string, publicKey: any): DIDDocument {\n const verificationMethodId = `${did}#0`\n\n return {\n '@context': ['https://www.w3.org/ns/did/v1', 'https://w3id.org/security/suites/jws-2020/v1'],\n id: did,\n verificationMethod: [\n {\n id: verificationMethodId,\n type: 'JsonWebKey2020',\n controller: did,\n publicKeyJwk: publicKey,\n },\n ],\n authentication: [verificationMethodId],\n assertionMethod: [verificationMethodId],\n capabilityInvocation: [verificationMethodId],\n capabilityDelegation: [verificationMethodId],\n }\n }\n\n private resolveDidJwkLocally(did: string): DIDDocument {\n // Extract JWK from did:jwk\n const encoded = did.replace('did:jwk:', '')\n const publicJwk = JSON.parse(Buffer.from(encoded, 'base64url').toString())\n\n return this.createDidDocument(did, publicJwk)\n }\n\n private async registerDid(_agent: Agent): Promise<void> {\n // This would call the DID API to register the DID\n // Implementation depends on the actual API\n // For now, this is a placeholder\n }\n}\n","import { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { createDidJwk, extractPublicKey, extractPublicKeyFromDid } from '../did/did-utils'\nimport { DIDDocument } from '../types'\n\n/**\n * User Identity Manager\n * Manages DID generation and lifecycle for Users (Issuers) specifically\n * Separate from Agent management to avoid confusion\n */\nexport class UserIdentityManager {\n private keyManager: KeyManager\n private currentUserDID: string | null = null\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n }\n\n /**\n * Get or create current user DID\n * This represents the user who will be the issuer of VCs\n */\n async getCurrentUserDID(): Promise<string> {\n if (this.currentUserDID) {\n return this.currentUserDID\n }\n\n // Try to load existing user DID\n const existingDID = await this.loadUserDID()\n if (existingDID) {\n this.currentUserDID = existingDID\n return existingDID\n }\n\n // Create new user DID if none exists\n return await this.createUserDID()\n }\n\n /**\n * Create a new user DID (for issuing VCs)\n */\n async createUserDID(): Promise<string> {\n // Generate key pair for user identity\n const keyPair = await SDJwtClient.generateKeyPair()\n\n // Create did:jwk\n const did = createDidJwk(keyPair.publicKey)\n\n // Store private key\n await this.keyManager.storeKey(did, keyPair.privateKey)\n\n // Save as current user DID\n await this.saveUserDID(did)\n this.currentUserDID = did\n\n return did\n }\n\n /**\n * Get user's key pair\n */\n async getUserKeyPair(): Promise<any> {\n const did = await this.getCurrentUserDID()\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error('User private key not found')\n }\n\n return {\n privateKey,\n publicKey: extractPublicKey(privateKey),\n }\n }\n\n /**\n * Resolve user DID to DID Document\n */\n async resolveUserDID(did?: string): Promise<DIDDocument> {\n const userDid = did || (await this.getCurrentUserDID())\n\n if (!userDid.startsWith('did:jwk:')) {\n throw new Error('Only did:jwk supported for user identity')\n }\n\n return this.resolveDidJwkLocally(userDid)\n }\n\n /**\n * Export user identity for backup\n */\n async exportUserIdentity(): Promise<{ did: string; privateKey: any; didDocument: DIDDocument }> {\n const did = await this.getCurrentUserDID()\n const privateKey = await this.keyManager.getKey(did)\n const didDocument = await this.resolveUserDID(did)\n\n if (!privateKey) {\n throw new Error('User private key not found')\n }\n\n return { did, privateKey, didDocument }\n }\n\n /**\n * Import user identity from backup\n */\n async importUserIdentity(backup: { did: string; privateKey: any }): Promise<void> {\n // Store the private key\n await this.keyManager.storeKey(backup.did, backup.privateKey)\n\n // Set as current user DID\n await this.saveUserDID(backup.did)\n this.currentUserDID = backup.did\n }\n\n /**\n * Reset user identity (create new DID)\n */\n async resetUserIdentity(): Promise<string> {\n // Clear current DID\n this.currentUserDID = null\n\n // Clear saved DID\n await this.clearUserDID()\n\n // Create new DID\n return await this.createUserDID()\n }\n\n\n /**\n * Resolve did:jwk locally\n */\n private resolveDidJwkLocally(did: string): DIDDocument {\n const publicJwk = extractPublicKeyFromDid(did)\n return this.createDidDocument(did, publicJwk)\n }\n\n /**\n * Create DID Document\n */\n private createDidDocument(did: string, publicKey: any): DIDDocument {\n const verificationMethodId = `${did}#0`\n\n return {\n '@context': ['https://www.w3.org/ns/did/v1', 'https://w3id.org/security/suites/jws-2020/v1'],\n id: did,\n verificationMethod: [\n {\n id: verificationMethodId,\n type: 'JsonWebKey2020',\n controller: did,\n publicKeyJwk: publicKey,\n },\n ],\n authentication: [verificationMethodId],\n assertionMethod: [verificationMethodId],\n capabilityInvocation: [verificationMethodId],\n capabilityDelegation: [verificationMethodId],\n }\n }\n\n /**\n * Save current user DID to persistent storage\n */\n private async saveUserDID(did: string): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const configDir = path.join(os.homedir(), '.vess-aidentity')\n await fs.mkdir(configDir, { recursive: true })\n\n const userDIDFile = path.join(configDir, 'user-did.txt')\n await fs.writeFile(userDIDFile, did, 'utf-8')\n }\n\n /**\n * Load current user DID from persistent storage\n */\n private async loadUserDID(): Promise<string | null> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const userDIDFile = path.join(os.homedir(), '.vess-aidentity', 'user-did.txt')\n\n try {\n return await fs.readFile(userDIDFile, 'utf-8')\n } catch {\n return null\n }\n }\n\n /**\n * Clear saved user DID\n */\n private async clearUserDID(): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const userDIDFile = path.join(os.homedir(), '.vess-aidentity', 'user-did.txt')\n\n try {\n await fs.unlink(userDIDFile)\n } catch {\n // File might not exist, ignore\n }\n }\n}\n","import {\n DelegationVC,\n ToolPermissionVC,\n DataAccessVC,\n VCTemplate,\n} from '../types'\nimport { getIssuerApiUrl, getApiHeaders } from '../config'\nimport { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { AgentManager } from '../did/agent'\nimport { UserIdentityManager } from '../identity/user-identity-manager'\nimport type { DisclosureFrame } from '@sd-jwt/types'\n\nexport class VCManager {\n private keyManager: KeyManager\n private templates: Map<string, VCTemplate> = new Map()\n private agentManager: AgentManager\n private userIdentityManager: UserIdentityManager\n\n constructor(\n keyManager?: KeyManager,\n agentManager?: AgentManager,\n userIdentityManager?: UserIdentityManager\n ) {\n this.keyManager = keyManager || new KeyManager()\n this.agentManager = agentManager || new AgentManager(this.keyManager)\n this.userIdentityManager = userIdentityManager || new UserIdentityManager(this.keyManager)\n this.registerDefaultTemplates()\n }\n\n /**\n * Get fields that should be selectively disclosable based on VC type\n */\n private getSelectivelyDisclosableFields(template: string): string[] {\n switch (template) {\n case 'ToolPermissionVC':\n return ['tool', 'action', 'scope', 'conditions']\n case 'DataAccessVC':\n return ['resource', 'actions', 'scope', 'conditions']\n case 'OrganizationVC':\n return ['organizationId', 'employeeId', 'department', 'role', 'permissions']\n default:\n return []\n }\n }\n\n /**\n * Issue a Verifiable Credential as SD-JWT VC\n * Enhanced to support User/Agent DID separation\n */\n async issue(\n template: string,\n claims: any,\n options: {\n issuerDid?: string // User DID (if not provided, uses current user)\n subjectDid?: string // Subject DID (if not provided, uses issuer DID for backward compatibility)\n agentId?: string // Agent ID (auto-resolves to agent DID as subject)\n expiresIn?: string // e.g., '1h', '30d'\n }\n ): Promise<string> {\n const vcTemplate = this.templates.get(template)\n if (!vcTemplate) {\n throw new Error(`Unknown VC template: ${template}`)\n }\n\n // Determine issuer DID (User Identity)\n const issuerDid = options.issuerDid || (await this.userIdentityManager.getCurrentUserDID())\n\n // Determine subject DID\n let subjectDid: string\n if (options.agentId) {\n // Agent ID provided - resolve to agent DID\n subjectDid = await this.agentManager.getAgentDID(options.agentId)\n } else if (options.subjectDid) {\n // Explicit subject DID provided\n subjectDid = options.subjectDid\n } else {\n // Backward compatibility: use issuer DID as subject\n subjectDid = issuerDid\n }\n\n // Build VC payload according to SD-JWT VC spec\n const now = new Date()\n const iat = Math.floor(now.getTime() / 1000)\n\n // Prepare credential subject with claims\n const credentialSubject = {\n id: subjectDid,\n ...claims,\n }\n\n // Apply template defaults\n if (vcTemplate.defaults) {\n Object.assign(credentialSubject, vcTemplate.defaults)\n }\n\n // Build the VC payload for SD-JWT VC\n const vcPayload: any = {\n // SD-JWT VC specific fields\n vct: vcTemplate.type,\n iss: issuerDid,\n iat,\n cnf: {\n // Confirmation method - binding to subject's key\n jwk: await this.getSubjectPublicKey(subjectDid),\n },\n // Standard VC fields\n credentialSubject,\n }\n\n if (options.expiresIn) {\n const expDate = this.calculateExpirationDate(options.expiresIn)\n vcPayload.exp = Math.floor(expDate.getTime() / 1000)\n }\n\n // Validate with template\n const vc = {\n ...vcPayload,\n '@context': ['https://www.w3.org/ns/credentials/v2'],\n issuer: issuerDid,\n validFrom: now.toISOString(),\n } as DelegationVC\n\n if (vcTemplate.validate && !vcTemplate.validate(vc as any)) {\n throw new Error('VC validation failed')\n }\n\n // Set up SDJwtClient with KeyManager\n SDJwtClient.setKeyManager(this.keyManager)\n\n // Get SD-JWT VC instance for this issuer\n const sdjwtInstance = await SDJwtClient.getIssuerInstance(issuerDid)\n\n // Get selectively disclosable fields for this VC type\n const selectivelyDisclosableFields = this.getSelectivelyDisclosableFields(template)\n\n // Create disclosure frame for the entire payload\n // The credentialSubject should have its own _sd array\n const credentialSubjectFrame = SDJwtClient.createDisclosureFrame(\n credentialSubject,\n selectivelyDisclosableFields\n )\n\n // Create the main disclosure frame that targets credentialSubject\n const disclosureFrame = {\n credentialSubject: credentialSubjectFrame,\n }\n\n // Issue the SD-JWT VC\n //@ts-ignore\n const sdjwtVc = await sdjwtInstance.issue(\n vcPayload,\n disclosureFrame as DisclosureFrame<typeof vcPayload>\n )\n\n return sdjwtVc\n }\n\n /**\n * Get subject's public key for cnf claim\n */\n private async getSubjectPublicKey(subjectDid: string): Promise<any> {\n // Extract JWK from did:jwk DID\n if (!subjectDid.startsWith('did:jwk:')) {\n throw new Error(`Unsupported DID method. Expected did:jwk, got: ${subjectDid}`)\n }\n\n try {\n // Extract the base64url-encoded JWK from the DID\n const jwkEncoded = subjectDid.replace('did:jwk:', '')\n const jwkJson = Buffer.from(jwkEncoded, 'base64url').toString('utf-8')\n const jwk = JSON.parse(jwkJson)\n\n // Return only the public key components (remove private key 'd' if present)\n const { d, key_ops, ...publicJwk } = jwk\n\n // Ensure it has the correct key operations for verification\n const publicKeyForCnf = {\n ...publicJwk,\n // Remove key_ops entirely for cnf claim as it's not needed there\n }\n\n return publicKeyForCnf\n } catch (error) {\n throw new Error(\n `Failed to extract JWK from did:jwk: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n }\n }\n\n /**\n * Issue using existing Issuer API (OID4VCI)\n */\n async issueViaAPI(\n credentialType: string,\n claims: any,\n options: {\n issuerDid: string\n subjectDid: string\n }\n ): Promise<string> {\n // First get credential offer\n const offerResponse = await fetch(getIssuerApiUrl('/api/v1/credential/offer'), {\n method: 'POST',\n headers: getApiHeaders('issuer'),\n body: JSON.stringify({\n credentialType,\n claims,\n subjectDid: options.subjectDid,\n }),\n })\n\n if (!offerResponse.ok) {\n throw new Error(`Failed to get credential offer: ${offerResponse.statusText}`)\n }\n\n const offer = (await offerResponse.json()) as { id: string }\n\n // Then acquire credential\n const acquireResponse = await fetch(getIssuerApiUrl('/api/v1/credential/acquire'), {\n method: 'POST',\n headers: getApiHeaders('issuer'),\n body: JSON.stringify({\n offerId: offer.id,\n holderDid: options.subjectDid,\n }),\n })\n\n if (!acquireResponse.ok) {\n throw new Error(`Failed to acquire credential: ${acquireResponse.statusText}`)\n }\n\n const credential = (await acquireResponse.json()) as { jwt: string }\n return credential.jwt\n }\n\n /**\n * Verify a SD-JWT VC\n */\n async verify(\n sdjwtVc: string,\n options?: {\n expectedIssuer?: string\n expectedSubject?: string\n requiredClaims?: string[] // Claims that must be disclosed\n }\n ): Promise<any> {\n // Parse to get issuer from the SD-JWT\n const parts = sdjwtVc.split('~')\n const jwt = parts[0]\n const jwtParts = jwt.split('.')\n const payload = JSON.parse(Buffer.from(jwtParts[1], 'base64url').toString())\n\n const issuerDid = payload.iss\n if (!issuerDid) {\n throw new Error('Issuer DID not found in SD-JWT VC')\n }\n\n // Validate expected issuer if provided\n if (options?.expectedIssuer && issuerDid !== options.expectedIssuer) {\n throw new Error(`Issuer mismatch: expected ${options.expectedIssuer}, got ${issuerDid}`)\n }\n\n // Set up SDJwtClient\n SDJwtClient.setKeyManager(this.keyManager)\n\n // Get SD-JWT VC instance for this issuer\n const sdjwtInstance = await SDJwtClient.getIssuerInstance(issuerDid)\n\n // Verify the SD-JWT VC\n const { payload: verifiedPayload } = await sdjwtInstance.verify(\n sdjwtVc,\n options?.requiredClaims ? { requiredClaimKeys: options?.requiredClaims } : undefined\n )\n\n const disclosures = await sdjwtInstance.getClaims(sdjwtVc)\n\n // Validate expected subject if provided\n const subjectId = (verifiedPayload?.credentialSubject as any)?.id || verifiedPayload.sub\n if (options?.expectedSubject) {\n if (subjectId !== options.expectedSubject) {\n throw new Error(`Subject mismatch: expected ${options.expectedSubject}, got ${subjectId}`)\n }\n }\n\n // Return the verified payload and disclosures\n return {\n payload: verifiedPayload,\n disclosures,\n issuer: issuerDid,\n subject: subjectId,\n issuedAt: verifiedPayload?.iat && new Date(verifiedPayload.iat * 1000),\n expiresAt: verifiedPayload.exp ? new Date(verifiedPayload.exp * 1000) : null,\n }\n }\n\n /**\n * Revoke a Verifiable Credential\n */\n async revoke(_vcId: string, _issuerDid: string): Promise<void> {\n // TODO: Call StatusList API to revoke\n throw new Error('VC revocation not yet implemented')\n }\n\n /**\n * Register a custom VC template\n */\n registerTemplate(template: VCTemplate): void {\n this.templates.set(template.name, template)\n }\n\n private registerDefaultTemplates(): void {\n // ToolPermissionVC template\n this.templates.set('ToolPermissionVC', {\n type: 'ToolPermissionVC',\n name: 'ToolPermissionVC',\n description: 'Permission to use a specific tool',\n validate: (vc: DelegationVC) => {\n const toolVc = vc as ToolPermissionVC\n return !!(toolVc.credentialSubject.tool && toolVc.credentialSubject.aud)\n },\n })\n\n // DataAccessVC template\n this.templates.set('DataAccessVC', {\n type: 'DataAccessVC',\n name: 'DataAccessVC',\n description: 'Permission to access data resources',\n validate: (vc: DelegationVC) => {\n const dataVc = vc as DataAccessVC\n return !!(\n dataVc.credentialSubject.resource &&\n dataVc.credentialSubject.actions &&\n dataVc.credentialSubject.actions.length > 0\n )\n },\n })\n }\n\n private calculateExpirationDate(expiresIn: string): Date {\n const now = new Date()\n const match = expiresIn.match(/^(\\d+)([hdm])$/)\n\n if (!match) {\n throw new Error(`Invalid expiresIn format: ${expiresIn}`)\n }\n\n const value = parseInt(match[1])\n const unit = match[2]\n\n switch (unit) {\n case 'h':\n now.setHours(now.getHours() + value)\n break\n case 'd':\n now.setDate(now.getDate() + value)\n break\n case 'm':\n now.setMinutes(now.getMinutes() + value)\n break\n default:\n throw new Error(`Unknown time unit: ${unit}`)\n }\n\n return now\n }\n}\n","import { VerifiablePresentation, VPRequest } from '../types'\nimport { generateNonce } from '../utils/crypto'\nimport { KeyManager } from '../did/key-manager'\nimport { getVerifierApiUrl, getApiHeaders } from '../config'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { digest } from '@sd-jwt/crypto-nodejs'\nimport { buildKbJwtPayload } from './kb-jwt-builder'\n\nexport class VPManager {\n private keyManager: KeyManager\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n // Initialize SDJwtClient with KeyManager\n SDJwtClient.setKeyManager(this.keyManager)\n }\n\n /**\n * Create a SD-JWT presentation using the present() method\n * This properly binds the holder's key to the SD-JWT VC\n */\n async create(\n vcs: string[], // Array of SD-JWT VC strings\n options: {\n holderDid: string\n challenge: string // nonce\n domain: string\n purpose?: string\n }\n ): Promise<string> {\n if (vcs.length === 0) {\n throw new Error('At least one SD-JWT VC is required for presentation')\n }\n\n // Get SDJwtClient instance for the holder DID\n const sdJwtInstance = await SDJwtClient.getHolderInstance(options.holderDid)\n\n // Use the first SD-JWT VC for presentation\n const sdJwtVC = vcs[0]\n\n try {\n // First decode the SD-JWT VC to get available claims\n const decodedVC = await sdJwtInstance.decode(sdJwtVC)\n\n // Get all presentable keys (we'll present all available claims)\n const presentableKeys = await decodedVC.presentableKeys(digest)\n\n // Create presentation frame to present ALL available claims\n // This is a simplified approach - in production you'd be selective\n const presentationFrame: Record<string, boolean> = {}\n presentableKeys.forEach((key: string) => {\n presentationFrame[key] = true\n })\n\n const kbJwtPayload = buildKbJwtPayload({\n holderDid: options.holderDid,\n audience: options.domain,\n nonce: options.challenge,\n vcCredential: sdJwtVC,\n })\n\n // Create a presentation using the issued credential and the presentation frame\n // The third parameter is the KB-JWT payload for holder binding\n const presentation = await sdJwtInstance.present(sdJwtVC, presentationFrame, {\n kb: { payload: kbJwtPayload },\n })\n\n return presentation\n } catch (error: any) {\n console.error('ERROR: Error creating SD-JWT presentation:', error)\n throw new Error(`Failed to create SD-JWT presentation: ${error.message}`)\n }\n }\n\n /**\n * Verify a Verifiable Presentation\n */\n async verify(\n vpJwt: string,\n options: {\n expectedChallenge: string\n expectedDomain: string\n expectedHolder?: string\n }\n ): Promise<VerifiablePresentation> {\n // Call Verifier API\n const response = await fetch(getVerifierApiUrl('/api/v1/vp/verify'), {\n method: 'POST',\n headers: getApiHeaders('verifier'),\n body: JSON.stringify({\n vp: vpJwt,\n challenge: options.expectedChallenge,\n domain: options.expectedDomain,\n }),\n })\n\n if (!response.ok) {\n throw new Error(`VP verification failed: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n\n if (!result?.valid) {\n throw new Error(`VP verification failed: ${result?.error}`)\n }\n\n // Additional local verification\n const vp = result?.verifiablePresentation as VerifiablePresentation\n\n if (options.expectedHolder && vp.holder !== options.expectedHolder) {\n throw new Error(`Holder mismatch. Expected: ${options.expectedHolder}, Got: ${vp.holder}`)\n }\n\n if (vp.proof?.challenge !== options.expectedChallenge) {\n throw new Error('Challenge mismatch')\n }\n\n if (vp.proof?.domain !== options.expectedDomain) {\n throw new Error('Domain mismatch')\n }\n\n return vp\n }\n\n /**\n * Create a VP request\n */\n createRequest(\n domain: string,\n query?: {\n type?: string\n credentialQuery?: any\n }\n ): VPRequest {\n return {\n challenge: generateNonce(),\n domain,\n query,\n }\n }\n\n /**\n * Submit VP to a verifier\n */\n async submit(\n vpJwt: string,\n verifierEndpoint: string\n ): Promise<{ verified: boolean; result?: any }> {\n const response = await fetch(verifierEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ vp: vpJwt }),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to submit VP: ${response.statusText}`)\n }\n\n return response.json() as any\n }\n}\n","/**\n * Single source of truth for Key Binding JWT (KB-JWT) issuance shared across\n * the AIdentity stack. Four production code paths build KB-JWTs and they\n * MUST stay byte-for-byte equivalent so a presentation built on one side is\n * accepted by the verifier on the other:\n *\n * - SDK clients via `VPManager.create()` (this package)\n * - API service via `packages/api/src/vp/vp-creation.service.ts`\n * - Remote MCP via `packages/remote-mcp/src/services/vp-creation.service.ts`\n * - agentd (`@vess-id/vess`) via `VPBuilder.buildVP()`\n * (`packages/agentd/src/wallet/vp-builder.ts`)\n *\n * Historically each path had its own copy of this logic. PR #391 (the\n * commit that made `exp` REQUIRED on the verifier side) updated only two of\n * the three issuer paths known at the time; the SDK was missed and every\n * SDK-built VP started failing at verification time. The follow-up\n * consolidation (commit 02b169aa) brought the SDK in line, but agentd —\n * which had its own KB-JWT literal in `wallet/vp-builder.ts` — was not\n * recognized as a fourth issuer. Staging then rejected every VP from\n * `@vess-id/vess` agentd alpha builds with `KB-JWT missing exp` until the\n * agentd hotfix (this commit's cohort) wired its VPBuilder through\n * `buildKbJwtPayload()`. This module exists so that a future verifier\n * change cannot drift from the issuer side: any update lands in one place\n * and all four paths inherit it.\n */\n\n/**\n * Default KB-JWT lifetime in seconds. Mirrors the cap enforced by the API's\n * `KeyBindingVerifierService.MAX_KB_JWT_LIFETIME_SECONDS` (also 300).\n *\n * The KB-JWT `exp` is the smaller of:\n * - `iat + KB_JWT_DEFAULT_LIFETIME_SECONDS`\n * - the parent VC's `exp` (so the bearer's freshness window cannot outlive\n * the underlying credential's validity, which is itself bounded by\n * `grant.expiresAt` at issuance time).\n */\nexport const KB_JWT_DEFAULT_LIFETIME_SECONDS = 300\n\nexport interface KbJwtPayload {\n iss: string\n aud: string\n nonce: string\n iat: number\n exp: number\n}\n\nexport interface BuildKbJwtPayloadArgs {\n /** Holder DID — becomes the KB-JWT `iss` claim. */\n holderDid: string\n /** Verifier audience (URL or hostname). Will be normalized via {@link normalizeDomain}. */\n audience: string\n /** Verifier-supplied nonce / challenge. */\n nonce: string\n /** The parent SD-JWT VC string. Its `exp` (if any) caps the KB-JWT lifetime. */\n vcCredential: string\n}\n\nexport interface BuildKbJwtPayloadDeps {\n /** Returns the current time in milliseconds. Defaults to `Date.now`. */\n now?: () => number\n}\n\n/**\n * Build a Key Binding JWT payload for an SD-JWT VC presentation.\n *\n * Throws when the parent VC is already expired (`vc.exp <= now`). The error\n * message intentionally contains the substring `\"VC has expired\"` so that\n * downstream catchers (notably remote-mcp's `isCredentialInvalidError`) can\n * detect a stale-credential condition and trigger a re-approval flow rather\n * than surface an opaque issuance failure to the user.\n */\nexport function buildKbJwtPayload(\n args: BuildKbJwtPayloadArgs,\n deps: BuildKbJwtPayloadDeps = {},\n): KbJwtPayload {\n const now = deps.now ?? Date.now\n // deps.now() is milliseconds (per Date.now contract); KB-JWT iat is seconds.\n const iatSeconds = Math.floor(now() / 1000)\n const kbExpCap = iatSeconds + KB_JWT_DEFAULT_LIFETIME_SECONDS\n const vcExp = readVcExpSeconds(args.vcCredential)\n const expSeconds = vcExp !== undefined ? Math.min(kbExpCap, vcExp) : kbExpCap\n\n if (expSeconds <= iatSeconds) {\n throw new Error(\n `VC has expired: cannot issue KB-JWT (vc.exp=${vcExp}, now=${iatSeconds})`,\n )\n }\n\n return {\n iss: args.holderDid,\n aud: normalizeDomain(args.audience),\n nonce: args.nonce,\n iat: iatSeconds,\n exp: expSeconds,\n }\n}\n\n/**\n * Best-effort read of the VC's `exp` claim from the SD-JWT outer payload.\n * Returns undefined when the VC is malformed, missing exp, or the field is\n * not a number — callers fall back to {@link KB_JWT_DEFAULT_LIFETIME_SECONDS}\n * in that case so issuance does not break for VCs without an explicit expiry.\n */\nexport function readVcExpSeconds(sdJwtVc: string): number | undefined {\n try {\n const jwtPart = sdJwtVc.split('~')[0]\n const payloadB64 = jwtPart.split('.')[1]\n if (!payloadB64) return undefined\n const payload = JSON.parse(Buffer.from(payloadB64, 'base64url').toString())\n return typeof payload.exp === 'number' ? payload.exp : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Normalize a domain string for consistent use as a JWT `aud` claim.\n *\n * The API verifier compares the KB-JWT `aud` against the expected domain by\n * exact string match, so issuer and verifier must agree on the canonical\n * form. We delegate to the URL parser, which strips paths and lowercases\n * the host, then return the resulting `origin`.\n *\n * Inputs without a scheme are assumed to be hostnames; `localhost` (with or\n * without a port) defaults to `http://`, everything else to `https://`. If\n * URL parsing fails, the input is returned unchanged so a caller can still\n * detect the mismatch downstream rather than silently swallowing a typo.\n */\nexport function normalizeDomain(domain: string): string {\n if (!domain) return domain\n\n let urlStr: string\n if (/^https?:\\/\\//i.test(domain)) {\n urlStr = domain\n } else {\n const scheme = /^localhost(:\\d+)?$/i.test(domain) ? 'http' : 'https'\n urlStr = `${scheme}://${domain}`\n }\n\n try {\n return new URL(urlStr).origin\n } catch {\n return domain\n }\n}\n","import { ConnectorResponse } from '../types'\nimport { VPManager } from '../vp/vp-manager'\nimport { getConfig } from '../config'\n\nexport interface ToolDefinition {\n name: string\n description: string\n actions: {\n name: string\n description: string\n parameters: Record<string, any>\n }[]\n}\n\nexport class ToolManager {\n private vpManager: VPManager\n private tools: Map<string, ToolDefinition> = new Map()\n private proxyApiUrl: string\n\n constructor(vpManager?: VPManager) {\n this.vpManager = vpManager || new VPManager()\n const config = getConfig()\n this.proxyApiUrl = config.proxyApi?.baseUrl || 'http://localhost:3000'\n this.registerDefaultTools()\n }\n\n /**\n * Invoke a tool action with VC authorization\n */\n async invoke<T = any>(\n tool: string,\n action: string,\n params: Record<string, any>,\n options: {\n vcs: string[] // VC JWTs authorizing this action\n holderDid: string\n }\n ): Promise<ConnectorResponse<T>> {\n // Validate tool exists\n const toolDef = this.tools.get(tool)\n if (!toolDef) {\n throw new Error(`Unknown tool: ${tool}`)\n }\n\n // Validate action exists\n const actionDef = toolDef.actions.find(a => a.name === action)\n if (!actionDef) {\n throw new Error(`Unknown action ${action} for tool ${tool}`)\n }\n\n // Create VP for this invocation\n const domain = new URL(this.proxyApiUrl).hostname\n const challenge = this.generateChallenge()\n\n const vpJwt = await this.vpManager.create(options.vcs, {\n holderDid: options.holderDid,\n challenge,\n domain,\n purpose: 'invocation',\n })\n\n // Mock mode for demo - avoid API calls\n if (this.proxyApiUrl === 'mock://demo') {\n // Return mock response for demo purposes\n const mockResponse: ConnectorResponse<T> = {\n success: true,\n data: {\n message: 'Mock Slack response - message posted successfully!',\n channel: params.channel || '#general',\n text: params.text || 'Hello from AIdentity!',\n ts: Date.now().toString(),\n ok: true,\n } as T,\n metadata: {\n tool,\n action,\n holder: options.holderDid,\n timestamp: new Date().toISOString(),\n mock: true,\n },\n }\n\n // Simulate API delay\n await new Promise(resolve => setTimeout(resolve, 500))\n return mockResponse\n }\n\n // Call Proxy API - check if we need to send VCs separately\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${vpJwt}`,\n 'X-Holder-DID': options.holderDid,\n 'X-Auth-Challenge': challenge,\n }\n\n // Only send X-VCs header if vpJwt doesn't contain ~ (not a full SD-JWT presentation)\n if (!vpJwt.includes('~')) {\n headers['X-VCs'] = JSON.stringify(options.vcs)\n }\n\n const response = await fetch(`${this.proxyApiUrl}/api/v1/tool/invoke`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n tool,\n action,\n params,\n challenge,\n }),\n })\n\n if (!response.ok) {\n // Try to parse JSON error response first to preserve metadata (e.g., reauthRequired)\n const contentType = response.headers.get('content-type')\n if (contentType && contentType.includes('application/json')) {\n try {\n const errorResponse = await response.json() as any\n // If the error response already has the ConnectorResponse structure, return it\n if (errorResponse.success === false) {\n return errorResponse as ConnectorResponse<T>\n }\n // Otherwise, wrap it\n return {\n success: false,\n error: errorResponse.message || errorResponse.error || 'Tool invocation failed',\n metadata: errorResponse.metadata,\n }\n } catch (parseError) {\n // If JSON parsing fails, fall back to text\n const error = await response.text()\n return {\n success: false,\n error: `Tool invocation failed: ${error}`,\n }\n }\n } else {\n // Non-JSON response, use text\n const error = await response.text()\n return {\n success: false,\n error: `Tool invocation failed: ${error}`,\n }\n }\n }\n\n const result = await response.json()\n return result as ConnectorResponse<T>\n }\n\n /**\n * List available tools\n */\n list(): ToolDefinition[] {\n return Array.from(this.tools.values())\n }\n\n /**\n * Get a specific tool definition\n */\n getTool(name: string): ToolDefinition | undefined {\n return this.tools.get(name)\n }\n\n /**\n * Register a custom tool\n */\n registerTool(tool: ToolDefinition): void {\n this.tools.set(tool.name, tool)\n }\n\n /**\n * Check if VCs authorize a tool action\n */\n async checkAuthorization(\n vcs: string[],\n tool: string,\n action: string,\n resourceScope?: Record<string, any>\n ): Promise<boolean> {\n // Parse VCs and check permissions\n // This is a simplified check - real implementation would verify signatures\n for (const vcJwt of vcs) {\n try {\n const parts = vcJwt.split('.')\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString())\n\n if (payload.credentialSubject?.tool === `${tool}.${action}`) {\n // Check resource scope if provided\n if (resourceScope) {\n const vcScope = payload.credentialSubject.resourceScope\n if (!this.matchScope(vcScope, resourceScope)) {\n continue\n }\n }\n return true\n }\n } catch {\n continue\n }\n }\n return false\n }\n\n private matchScope(vcScope: Record<string, any>, requiredScope: Record<string, any>): boolean {\n // Simple scope matching - can be enhanced\n for (const [key, value] of Object.entries(requiredScope)) {\n if (vcScope[key] !== value && vcScope[key] !== '*') {\n return false\n }\n }\n return true\n }\n\n private generateChallenge(): string {\n return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)\n }\n\n private registerDefaultTools(): void {\n // Slack tool\n this.tools.set('slack', {\n name: 'slack',\n description: 'Slack workspace operations',\n actions: [\n {\n name: 'slack.message.post',\n description: 'Post a message to a channel',\n parameters: {\n channel: 'string',\n text: 'string',\n thread_ts: 'string?',\n },\n },\n {\n name: 'slack.channel.read',\n description: 'List channels',\n parameters: {},\n },\n {\n name: 'slack.user.read',\n description: 'Get user information',\n parameters: {\n userId: 'string',\n },\n },\n {\n name: 'slack.message.read',\n description: 'Get channel history',\n parameters: {\n channel: 'string',\n latest: 'string?',\n oldest: 'string?',\n limit: 'number?',\n inclusive: 'boolean?',\n },\n },\n ],\n })\n\n // GitHub tool\n this.tools.set('github', {\n name: 'github',\n description: 'GitHub repository operations',\n actions: [\n {\n name: 'github.issue.create',\n description: 'Create a new issue',\n parameters: {\n owner: 'string',\n repo: 'string',\n title: 'string',\n body: 'string',\n labels: 'string[]?',\n },\n },\n {\n name: 'github.issue.list',\n description: 'List repository issues',\n parameters: {\n owner: 'string',\n repo: 'string',\n state: 'string?',\n },\n },\n {\n name: 'github.repo.read',\n description: 'Get repository information',\n parameters: {\n owner: 'string',\n repo: 'string',\n },\n },\n ],\n })\n\n // Gmail tool\n this.tools.set('gmail', {\n name: 'gmail',\n description: 'Gmail operations',\n actions: [\n {\n name: 'gmail.message.send',\n description: 'Send an email message',\n parameters: {\n to: 'string',\n subject: 'string',\n body: 'string',\n cc: 'string[]?',\n bcc: 'string[]?',\n format: 'string?',\n },\n },\n {\n name: 'gmail.message.list',\n description: 'Get email messages',\n parameters: {\n query: 'string?',\n maxResults: 'number?',\n pageToken: 'string?',\n labelIds: 'string[]?',\n },\n },\n {\n name: 'gmail.message.read',\n description: 'Get a specific email message',\n parameters: {\n messageId: 'string',\n format: 'string?',\n },\n },\n {\n name: 'gmail.label.read',\n description: 'Get available labels',\n parameters: {},\n },\n {\n name: 'gmail.message.search',\n description: 'Search email messages',\n parameters: {\n query: 'string',\n maxResults: 'number?',\n pageToken: 'string?',\n },\n },\n {\n name: 'gmail.message.update',\n description: 'Modify message labels',\n parameters: {\n messageId: 'string',\n addLabelIds: 'string[]?',\n removeLabelIds: 'string[]?',\n },\n },\n {\n name: 'gmail.draft.create',\n description: 'Create a draft email',\n parameters: {\n to: 'string',\n subject: 'string',\n body: 'string',\n cc: 'string[]?',\n bcc: 'string[]?',\n format: 'string?',\n },\n },\n ],\n })\n\n // Jira tool\n this.tools.set('jira', {\n name: 'jira',\n description: 'Jira project and issue management',\n actions: [\n {\n name: 'jira.project.read',\n description: 'List all Jira projects',\n parameters: {\n recent: 'number?',\n },\n },\n {\n name: 'jira.board.read',\n description: 'Get Jira board details',\n parameters: {\n boardId: 'number',\n },\n },\n {\n name: 'jira.board.list',\n description: 'List all Jira boards',\n parameters: {\n projectKeyOrId: 'string?',\n type: 'string?',\n },\n },\n {\n name: 'jira.sprint.read',\n description: 'Get sprints for a Jira board',\n parameters: {\n boardId: 'number',\n state: 'string?',\n },\n },\n {\n name: 'jira.issue.list',\n description: 'Get issues in a specific sprint',\n parameters: {\n sprintId: 'number',\n maxResults: 'number?',\n },\n },\n {\n name: 'jira.issue.search',\n description: 'Search for Jira issues using JQL',\n parameters: {\n jql: 'string',\n maxResults: 'number?',\n startAt: 'number?',\n },\n },\n {\n name: 'jira.issue.read',\n description: 'Get a specific Jira issue',\n parameters: {\n issueIdOrKey: 'string',\n },\n },\n {\n name: 'jira.worklog.read',\n description: 'Get worklogs for a specific issue',\n parameters: {\n issueKey: 'string',\n },\n },\n {\n name: 'jira.issue.create',\n description: 'Create a new Jira issue',\n parameters: {\n projectKey: 'string',\n summary: 'string',\n description: 'string?',\n issueTypeName: 'string',\n priority: 'string?',\n assignee: 'string?',\n },\n },\n ],\n })\n }\n}\n","import { VPManager } from '../vp/vp-manager'\nimport { getDidApiUrl } from '../config'\nimport {\n Grant,\n GrantStatus,\n CreateGrantRequest,\n UpdateGrantRequest,\n CheckGrantPermissionRequest,\n CheckGrantPermissionResult,\n} from '../types'\n\n/**\n * Grant提案レスポンス\n */\nexport interface GrantSuggestion {\n id: string\n oauthTokenId: string\n userId?: string\n projectId: string\n provider: string\n suggestedActions: string[]\n suggestedResources: Array<{\n type: string\n id?: string\n pattern?: string\n name?: string\n }>\n metadata: {\n providerInfo: any\n scopes: string[]\n }\n createdAt: string\n}\n\n/**\n * Grant提案確認リクエスト\n */\nexport interface ConfirmGrantRequest {\n suggestionId: string\n selectedActions: string[]\n selectedResources: Array<{\n type: string\n id?: string\n pattern?: string\n name?: string\n selected: boolean\n }>\n constraints: {\n maxInvocations?: number\n expiresAt?: string\n timeWindow?: {\n start: string\n end: string\n timezone: string\n daysOfWeek: number[]\n }\n }\n name?: string\n description?: string\n}\n\n/**\n * GrantManager\n * Grants APIを操作するSDKクライアント\n */\nexport class GrantManager {\n constructor(_vpManager: VPManager) {\n // vpManager might be used in future for VP creation\n }\n\n /**\n * Grant提案を取得\n * @param options - 提案オプション\n * @param options.oauthTokenId - OAuthトークンID\n * @param options.userId - 対象ユーザーID\n * @param options.projectId - プロジェクトID\n * @param authOptions - 認証オプション(VP or issuerDid)\n */\n async suggest(\n options: {\n oauthTokenId: string\n userId: string\n projectId: string\n },\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<GrantSuggestion> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl('/api/v1/grants/suggest'), {\n method: 'POST',\n headers,\n body: JSON.stringify(options),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to get grant suggestion: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grant提案を確認して作成\n * @param request - 確認リクエスト\n * @param authOptions - 認証オプション\n */\n async confirm(\n request: ConfirmGrantRequest,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl('/api/v1/grants/confirm'), {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to confirm grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grantを直接作成\n * @param request - Grant作成リクエスト\n * @param authOptions - 認証オプション\n */\n async create(\n request: CreateGrantRequest,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl('/api/v1/grants'), {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to create grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * ユーザー用のGrant一覧を取得\n * @param userId - ユーザーID\n * @param status - フィルタするステータス(オプション)\n */\n async listForUser(\n userId: string,\n status?: GrantStatus\n ): Promise<{ grants: Grant[]; total: number }> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const encodedUserId = encodeURIComponent(userId)\n const url = status\n ? getDidApiUrl(`/api/v1/grants/user/${encodedUserId}?status=${status}`)\n : getDidApiUrl(`/api/v1/grants/user/${encodedUserId}`)\n\n const response = await fetch(url, {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to list grants for user: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Issuer用のGrant一覧を取得\n * @param issuerDid - IssuerのDID\n * @param status - フィルタするステータス(オプション)\n */\n async listForIssuer(\n issuerDid: string,\n status?: GrantStatus\n ): Promise<{ grants: Grant[]; total: number }> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const encodedDid = encodeURIComponent(issuerDid)\n const url = status\n ? getDidApiUrl(`/api/v1/grants/issuer/${encodedDid}?status=${status}`)\n : getDidApiUrl(`/api/v1/grants/issuer/${encodedDid}`)\n\n const response = await fetch(url, {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to list grants for issuer: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grantを取得\n * @param grantId - GrantのID\n */\n async get(grantId: string): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const response = await fetch(getDidApiUrl(`/api/v1/grants/${grantId}`), {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to get grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grantを取り消し\n * @param grantId - GrantのID\n * @param reason - 取り消し理由\n * @param authOptions - 認証オプション\n */\n async revoke(\n grantId: string,\n reason: string,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl(`/api/v1/grants/${grantId}`), {\n method: 'DELETE',\n headers,\n body: JSON.stringify({ reason }),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to revoke grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grant権限をチェック\n * @param request - 権限チェックリクエスト\n */\n async checkPermission(\n request: CheckGrantPermissionRequest\n ): Promise<CheckGrantPermissionResult> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const response = await fetch(getDidApiUrl('/api/v1/grants/check'), {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to check grant permission: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grant更新\n * @param grantId - GrantのID\n * @param request - 更新リクエスト\n * @param authOptions - 認証オプション\n */\n async update(\n grantId: string,\n request: UpdateGrantRequest,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl(`/api/v1/grants/${grantId}`), {\n method: 'PUT',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to update grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n}\n","import { AIdentityConfig, configure } from './config'\nimport { AgentManager } from './did/agent'\nimport { KeyManager } from './did/key-manager'\nimport { UserIdentityManager } from './identity/user-identity-manager'\nimport { VCManager } from './vc/vc-manager'\nimport { VPManager } from './vp/vp-manager'\nimport { ToolManager } from './tool/tool-manager'\nimport { GrantManager } from './grant/grant-manager'\nimport { Agent, ConnectorResponse } from './types'\n\nexport class AIdentityClient {\n public readonly agent: AgentManager\n public readonly user: UserIdentityManager\n public readonly vc: VCManager\n public readonly vp: VPManager\n public readonly tool: ToolManager\n public readonly grant: GrantManager\n\n private keyManager: KeyManager\n private currentAgent?: Agent\n\n constructor(config?: AIdentityConfig, password?: string) {\n if (config) {\n configure(config)\n }\n\n // Initialize key manager with optional password for encryption\n this.keyManager = new KeyManager(password)\n\n // Initialize managers\n this.agent = new AgentManager(this.keyManager)\n this.user = new UserIdentityManager(this.keyManager)\n this.vc = new VCManager(this.keyManager, this.agent, this.user)\n this.vp = new VPManager(this.keyManager)\n this.tool = new ToolManager(this.vp)\n this.grant = new GrantManager(this.vp)\n }\n\n /**\n * Quick setup: Create or load an agent\n */\n async setup(did?: string): Promise<Agent> {\n if (did) {\n // Load existing agent\n this.currentAgent = await this.agent.export(did).then(({ agent }) => agent)\n } else {\n // Create new agent\n this.currentAgent = await this.agent.create()\n }\n return this.currentAgent\n }\n\n /**\n * Get current agent\n */\n getCurrentAgent(): Agent | undefined {\n return this.currentAgent\n }\n\n /**\n * Get current user DID\n */\n async getCurrentUserDID(): Promise<string> {\n return this.user.getCurrentUserDID()\n }\n\n /**\n * Create or reset user identity\n */\n async resetUserIdentity(): Promise<string> {\n return this.user.resetUserIdentity()\n }\n\n /**\n * Issue a VC for tool permission\n * Enhanced to support User → Agent delegation pattern\n */\n async issueToolPermission(\n tool: string,\n action: string,\n options: {\n subjectDid?: string\n agentId?: string\n issuerDid?: string\n resourceScope?: Record<string, any>\n expiresIn?: string\n }\n ): Promise<string> {\n return this.vc.issue(\n 'ToolPermissionVC',\n {\n tool: `${tool}.${action}`,\n resourceScope: options.resourceScope,\n aud: tool,\n },\n {\n issuerDid: options.issuerDid,\n subjectDid: options.subjectDid,\n agentId: options.agentId,\n expiresIn: options.expiresIn || '1h',\n }\n )\n }\n\n /**\n * Issue a VC for data access\n * Enhanced to support User → Agent delegation pattern\n */\n async issueDataAccess(\n resource: string,\n actions: ('read' | 'write' | 'delete')[],\n options: {\n subjectDid?: string\n agentId?: string\n issuerDid?: string\n expiresIn?: string\n }\n ): Promise<string> {\n return this.vc.issue(\n 'DataAccessVC',\n {\n resource,\n actions,\n },\n {\n issuerDid: options.issuerDid,\n subjectDid: options.subjectDid,\n agentId: options.agentId,\n expiresIn: options.expiresIn || '24h',\n }\n )\n }\n\n /**\n * Invoke a tool with automatic VP creation\n */\n async invokeTool<T = any>(\n tool: string,\n action: string,\n params: Record<string, any>,\n vcs: string[]\n ): Promise<ConnectorResponse<T>> {\n const holderDid = this.currentAgent?.did\n if (!holderDid) {\n throw new Error('No current agent available')\n }\n\n return this.tool.invoke<T>(tool, action, params, {\n vcs,\n holderDid,\n })\n }\n\n}\n\n// Export singleton instance for convenience\nlet defaultClient: AIdentityClient | undefined\n\nexport function getClient(config?: AIdentityConfig, password?: string): AIdentityClient {\n if (!defaultClient) {\n defaultClient = new AIdentityClient(config, password)\n }\n return defaultClient\n}\n\nexport { configure, AIdentityConfig } from './config'\n","import { SDJwtClient } from '../utils/sdjwt-client'\nimport { createDidJwk, extractPublicKeyFromDid } from '../did/did-utils'\nimport type { JWK } from 'jose'\n\nexport interface KeyPairGenerationResult {\n did: string\n publicKey: JWK\n privateKey: JWK\n}\n\n/**\n * Manages key pair generation for remote user issuer.\n * Generates ES256 key pairs and creates did:jwk DIDs.\n */\nexport class UserKeyPairManager {\n /**\n * Generate a new key pair and create a did:jwk DID\n */\n async generateKeyPair(): Promise<KeyPairGenerationResult> {\n const keyPair = await SDJwtClient.generateKeyPair()\n const did = createDidJwk(keyPair.publicKey)\n\n return {\n did,\n publicKey: keyPair.publicKey as JWK,\n privateKey: keyPair.privateKey as JWK,\n }\n }\n\n /**\n * Extract public key info from a did:jwk DID\n * @throws Error if the DID is not in did:jwk format\n */\n extractPublicKeyInfo(did: string): JWK {\n if (!did.startsWith('did:jwk:')) {\n throw new Error('Only did:jwk format is supported')\n }\n return extractPublicKeyFromDid(did)\n }\n}\n","/**\n * Device Enrollment Manager\n *\n * Handles the device code flow for registering a User Root DID\n * without requiring an API key. Supports two modes:\n *\n * Client-generated (local mode):\n * 1. Client calls startDeviceEnrollment() with rootDid + publicKeyJwk\n * 2. Client presents user_code and verification_url to the user\n * 3. User approves in browser\n * 4. Client polls until approved, receives device_session_token\n *\n * Server-generated (remote mode):\n * 1. Client calls startServerSideEnrollment() with clientInfo only\n * 2. Server returns user_code + verification_url (DID generated on approval)\n * 3. User approves in browser\n * 4. Client polls until approved, receives rootDid + device_session_token\n */\n\nexport interface DeviceEnrollStartParams {\n rootDid: string\n publicKeyJwk: {\n kty: string\n crv: string\n x: string\n y?: string\n use?: string\n alg?: string\n }\n clientInfo?: {\n deviceName?: string\n os?: string\n appVersion?: string\n hostname?: string\n [key: string]: any\n }\n purpose?: string\n}\n\nexport interface DeviceEnrollServerSideParams {\n clientInfo?: {\n deviceName?: string\n os?: string\n appVersion?: string\n hostname?: string\n [key: string]: any\n }\n purpose?: string\n}\n\nexport interface DeviceEnrollStartResult {\n requestId: string\n userCode: string\n verificationUrl: string\n expiresAt: string\n}\n\nexport interface DeviceEnrollPollResult {\n status: 'pending' | 'approved' | 'expired' | 'denied'\n deviceSessionToken?: string\n expiresAt?: string\n rootDid?: string // Returned on approval\n}\n\nexport class DeviceEnrollManager {\n private baseUrl: string\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\n }\n\n /**\n * Build common headers for all API requests.\n * Includes User-Agent and ngrok-skip-browser-warning to avoid\n * ngrok free-tier interstitial pages blocking programmatic access.\n */\n private buildHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'User-Agent': 'vess-sdk/1.0',\n 'ngrok-skip-browser-warning': 'true',\n }\n }\n\n /**\n * Start the device enrollment flow.\n * Sends the root DID public key to the Gateway and gets a user code.\n *\n * @param params - Root DID public info and client metadata\n * @returns Request ID, user code, and verification URL\n */\n async startDeviceEnrollment(\n params: DeviceEnrollStartParams\n ): Promise<DeviceEnrollStartResult> {\n const response = await fetch(`${this.baseUrl}/api/v1/device/start`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n rootDid: params.rootDid,\n publicKeyJwk: params.publicKeyJwk,\n clientInfo: params.clientInfo,\n purpose: params.purpose || 'root_did_enrollment',\n }),\n })\n\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(\n `Failed to start device enrollment: ${response.status} - ${errorBody}`\n )\n }\n\n const body = (await response.json()) as { success: boolean; data: DeviceEnrollStartResult }\n if (!body.success) {\n throw new Error(`Failed to start device enrollment: ${JSON.stringify(body)}`)\n }\n\n return body.data\n }\n\n /**\n * Start the device enrollment flow with server-side DID generation.\n * The server generates the real key pair on approval (not at start time).\n * Use this for remote/cloud-managed mode.\n *\n * @param params - Client metadata (no DID or key needed)\n * @returns Request ID, user code, and verification URL\n */\n async startServerSideEnrollment(\n params: DeviceEnrollServerSideParams\n ): Promise<DeviceEnrollStartResult> {\n const response = await fetch(`${this.baseUrl}/api/v1/device/start`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n generateServerSide: true,\n clientInfo: params.clientInfo,\n purpose: params.purpose || 'root_did_enrollment',\n }),\n })\n\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(\n `Failed to start device enrollment: ${response.status} - ${errorBody}`\n )\n }\n\n const body = (await response.json()) as { success: boolean; data: DeviceEnrollStartResult }\n if (!body.success) {\n throw new Error(`Failed to start device enrollment: ${JSON.stringify(body)}`)\n }\n\n return body.data\n }\n\n /**\n * Poll for enrollment status.\n * Call this periodically after startDeviceEnrollment() to check if\n * the user has approved the enrollment in the web UI.\n *\n * @param requestId - The request ID from startDeviceEnrollment()\n * @returns Current status and token if approved\n */\n async pollDeviceEnrollment(requestId: string): Promise<DeviceEnrollPollResult> {\n const response = await fetch(`${this.baseUrl}/api/v1/device/poll`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({ requestId }),\n })\n\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(\n `Failed to poll device enrollment: ${response.status} - ${errorBody}`\n )\n }\n\n const body = (await response.json()) as { success: boolean; data: DeviceEnrollPollResult }\n if (!body.success) {\n throw new Error(`Failed to poll device enrollment: ${JSON.stringify(body)}`)\n }\n\n return body.data\n }\n\n /**\n * Convenience method: Start enrollment and poll until completion.\n * Returns the final result (approved, expired, or denied).\n *\n * @param params - Enrollment parameters (client-generated mode)\n * @param onUserCode - Callback when user code is available (present to user)\n * @param pollIntervalMs - Polling interval in ms (default: 3000)\n * @param maxPolls - Maximum number of poll attempts (default: 120)\n */\n async enrollAndWait(\n params: DeviceEnrollStartParams,\n onUserCode: (info: DeviceEnrollStartResult) => void,\n pollIntervalMs: number = 3000,\n maxPolls: number = 120\n ): Promise<DeviceEnrollPollResult> {\n const startResult = await this.startDeviceEnrollment(params)\n return this.pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls)\n }\n\n /**\n * Convenience method: Start server-side enrollment and poll until completion.\n * Returns the final result including the server-generated rootDid on approval.\n *\n * @param params - Client metadata (server-generated mode)\n * @param onUserCode - Callback when user code is available (present to user)\n * @param pollIntervalMs - Polling interval in ms (default: 3000)\n * @param maxPolls - Maximum number of poll attempts (default: 120)\n */\n async enrollServerSideAndWait(\n params: DeviceEnrollServerSideParams,\n onUserCode: (info: DeviceEnrollStartResult) => void,\n pollIntervalMs: number = 3000,\n maxPolls: number = 120\n ): Promise<DeviceEnrollPollResult> {\n const startResult = await this.startServerSideEnrollment(params)\n return this.pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls)\n }\n\n private async pollUntilComplete(\n startResult: DeviceEnrollStartResult,\n onUserCode: (info: DeviceEnrollStartResult) => void,\n pollIntervalMs: number,\n maxPolls: number\n ): Promise<DeviceEnrollPollResult> {\n onUserCode(startResult)\n\n for (let i = 0; i < maxPolls; i++) {\n await new Promise(resolve => setTimeout(resolve, pollIntervalMs))\n\n const pollResult = await this.pollDeviceEnrollment(startResult.requestId)\n\n if (pollResult.status !== 'pending') {\n return pollResult\n }\n }\n\n return { status: 'expired' }\n }\n}\n","import { DIDDocument } from './did'\n\n/**\n * Agent Status enumeration\n */\nexport enum AgentStatus {\n ACTIVE = 'active',\n SUSPENDED = 'suspended', // @deprecated — kept for backward compatibility with existing DB rows\n REVOKED = 'revoked', // @deprecated — kept for backward compatibility with existing DB rows\n DELETED = 'deleted',\n}\n\n/**\n * Agent Type enumeration\n */\nexport enum AgentType {\n AUTONOMOUS = 'autonomous', // Independent AI Agent\n SUB_AGENT = 'sub_agent', // Part of multi-agent system\n TOOL_AGENT = 'tool_agent', // Tool-specific agent\n ASSISTANT = 'assistant', // AI Assistant (Claude Code etc.)\n PROXY = 'proxy' // Proxy for external systems\n}\n\n/**\n * AI Agent Identity representation\n * Agents are AI entities that need identity for permission delegation\n */\nexport interface Agent {\n /** The DID associated with this agent */\n did: string\n /** DID Document for the agent's identity */\n didDocument: DIDDocument\n /** ISO 8601 timestamp of when the agent was created */\n createdAt: string\n /** Optional metadata for the agent */\n metadata?: Record<string, any>\n}\n\n/**\n * Extended Agent interface matching API entity structure\n */\nexport interface APIAgent {\n /** Unique identifier */\n id: string\n /** Agent's DID (Decentralized Identifier) */\n did: string\n /** Agent's display name */\n name: string\n /** Agent type */\n type: AgentType\n /** Agent status */\n status: AgentStatus\n /** Agent information */\n agentInfo: {\n model?: string // AI model (claude-3, gpt-4, etc)\n capabilities?: string[] // Agent capabilities\n configuration?: Record<string, any>\n [key: string]: any\n }\n /** Additional metadata */\n metadata?: Record<string, any>\n /** Owner user ID */\n ownerId?: string\n /** Parent agent ID for hierarchical agents */\n parentAgentId?: string\n /** Whether agent is currently active */\n isActive: boolean\n /** Last activity timestamp */\n lastActiveAt?: Date\n /** Creation timestamp */\n createdAt: Date\n /** Update timestamp */\n updatedAt: Date\n}\n\n/**\n * Agent with unique identifier\n * Used for managing multiple agents with distinct identities\n */\nexport interface AgentWithId extends Agent {\n /** Unique identifier for this agent instance */\n id: string\n}\n\n/**\n * User Identity representation\n * Users are human entities who issue VCs to agents\n */\nexport interface UserIdentity {\n /** The DID associated with this user */\n did: string\n /** DID Document for the user's identity */\n didDocument: DIDDocument\n /** ISO 8601 timestamp of when the user identity was created */\n createdAt: string\n /** Optional metadata for the user */\n metadata?: Record<string, any>\n}\n\n/**\n * Configuration for Agent DID generation\n */\nexport interface AgentDIDConfig {\n /** Whether to auto-generate DID for new agents */\n generateDID: boolean\n /** DID method to use (currently only 'jwk' supported) */\n didMethod: 'jwk'\n /** Key type for cryptographic operations */\n keyType: 'ES256'\n /** Whether agent DIDs are ephemeral (deleted with agent) */\n ephemeral: boolean\n}\n\n/**\n * Configuration for User Identity management\n */\nexport interface UserIdentityConfig {\n /** Whether to auto-create user identity if none exists */\n autoCreate: boolean\n /** DID method to use (currently only 'jwk' supported) */\n didMethod: 'jwk'\n /** Key type for cryptographic operations */\n keyType: 'ES256'\n /** Whether to support external DIDs (future feature) */\n allowExternalDID: boolean\n}\n\n/**\n * Agent creation options\n */\nexport interface AgentCreateOptions {\n /** Optional name for the agent */\n name?: string\n /** Optional metadata to associate with the agent */\n metadata?: Record<string, any>\n /** Override default DID generation behavior */\n generateDID?: boolean\n}\n\n/**\n * User identity creation options\n */\nexport interface UserIdentityCreateOptions {\n /** Optional metadata to associate with the user */\n metadata?: Record<string, any>\n /** Force creation of new identity (replace existing) */\n force?: boolean\n}","/**\n * Credential Type enumeration\n * Used for general credential classification\n */\nexport enum CredentialType {\n PROJECT_ACCESS = 'ProjectAccessCredential',\n TOOL_ACCESS = 'ToolAccessCredential',\n DEVELOPER = 'DeveloperCredential',\n TEMPORARY = 'TemporaryCredential',\n ADMIN = 'AdminCredential',\n RECEIPT = 'ReceiptCredential'\n}\n\n/**\n * Credential Status enumeration\n * Used for general credential status tracking\n */\nexport enum CredentialStatus {\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REVOKED = 'revoked',\n SUSPENDED = 'suspended'\n}\n\n/**\n * VC Type enumeration (for Grant-based VCs)\n * Used specifically for VerifiableCredential entity in the database\n *\n * Maps to:\n * - ACCESS_CREDENTIAL: Pre-execution authorization (similar to TOOL_ACCESS)\n * - RECEIPT: Post-execution proof (similar to ReceiptCredential)\n */\nexport enum VCType {\n ACCESS_CREDENTIAL = 'AccessCredential',\n RECEIPT = 'Receipt'\n}\n\n/**\n * VC Status enumeration (for Grant-based VCs)\n * Used specifically for VerifiableCredential entity in the database\n *\n * Maps to CredentialStatus:\n * - VALID = ACTIVE\n * - EXPIRED = EXPIRED\n * - REVOKED = REVOKED\n * - SUSPENDED = SUSPENDED (temporary revocation, can be reactivated)\n * - EXHAUSTED = Grant invocation limit reached\n */\nexport enum VCStatus {\n VALID = 'valid',\n EXPIRED = 'expired',\n REVOKED = 'revoked',\n SUSPENDED = 'suspended',\n EXHAUSTED = 'exhausted'\n}\n\n/**\n * Utility functions for mapping between CredentialStatus and VCStatus\n */\nexport function credentialStatusToVCStatus(status: CredentialStatus): VCStatus {\n switch (status) {\n case CredentialStatus.ACTIVE:\n return VCStatus.VALID\n case CredentialStatus.EXPIRED:\n return VCStatus.EXPIRED\n case CredentialStatus.REVOKED:\n return VCStatus.REVOKED\n case CredentialStatus.SUSPENDED:\n return VCStatus.SUSPENDED\n default:\n // Type-safe exhaustiveness check\n const _exhaustiveCheck: never = status\n throw new Error(`Unknown CredentialStatus: ${_exhaustiveCheck}`)\n }\n}\n\nexport function vcStatusToCredentialStatus(status: VCStatus): CredentialStatus {\n switch (status) {\n case VCStatus.VALID:\n return CredentialStatus.ACTIVE\n case VCStatus.EXPIRED:\n return CredentialStatus.EXPIRED\n case VCStatus.REVOKED:\n case VCStatus.EXHAUSTED:\n return CredentialStatus.REVOKED\n case VCStatus.SUSPENDED:\n return CredentialStatus.SUSPENDED\n default:\n // Type-safe exhaustiveness check\n const _exhaustiveCheck: never = status\n throw new Error(`Unknown VCStatus: ${_exhaustiveCheck}`)\n }\n}\n\n/**\n * SD-JWT Verifiable Credential interface\n */\nexport interface DelegationVC {\n '@context': string[]\n vct: string\n issuer: string\n iss: string\n iat: number\n exp?: number\n validFrom: string\n validUntil?: string\n name?: string\n description?: string\n credentialSubject: {\n id: string // Subject DID\n [key: string]: any\n }\n credentialStatus?: {\n id: string\n type: string\n statusListIndex: string\n statusListCredential: string\n }\n}\n\n/**\n * API Credential entity interface\n */\nexport interface APICredential {\n /** Unique identifier */\n id: string\n /** Issuer DID */\n issuer: string\n /** Subject DID */\n subject: string\n /** Credential type */\n type: CredentialType\n /** Credential claims */\n claims: {\n permissions?: string[]\n projectId?: string\n tools?: string[]\n authorizedBy?: string\n deviceBinding?: string\n [key: string]: any\n }\n /** Credential status */\n status: CredentialStatus\n /** Raw SD-JWT credential */\n rawCredential?: string\n /** Cryptographic signature */\n signature?: string\n /** Associated project ID */\n projectId?: string\n /** Associated agent ID */\n agentId?: string\n /** Issuance timestamp */\n issuedAt: Date\n /** Expiration timestamp */\n expiresAt?: Date\n /** Revocation timestamp */\n revokedAt?: Date\n /** Revocation reason */\n revocationReason?: string\n /** Creation timestamp */\n createdAt: Date\n /** Update timestamp */\n updatedAt: Date\n}\n\n/**\n * SD-JWT Credential issuance request\n */\nexport interface IssueSDJWTVCRequest {\n /** Issuer DID */\n issuer: string\n /** Subject DID */\n subject: string\n /** Credential type */\n type?: CredentialType\n /** Claims to include */\n claims: Record<string, any>\n /** Expiration date */\n expirationDate?: Date\n /** Project ID */\n projectId?: string\n /** Agent ID */\n agentId?: string\n /** Fields to make selectively disclosable */\n selectiveDisclosureFields?: string[]\n}\n\n/**\n * SD-JWT Credential verification result\n */\nexport interface VerifySDJWTVCResult {\n /** Whether the credential is valid */\n valid: boolean\n /** Decoded payload if valid */\n payload?: {\n iss: string\n sub: string\n vct: string // IETF SD-JWT VC credential type\n exp?: number\n iat?: number\n // Additional claims can be present (dynamic properties)\n [key: string]: any\n }\n /** Error message if invalid */\n error?: string\n}\n\n/**\n * SD-JWT Credential issuance result\n */\nexport interface IssueSDJWTVCResult {\n /** The complete SD-JWT VC */\n credential: string\n /** Issuer DID */\n issuer: string\n /** Subject DID */\n subject: string\n /** Credential type */\n type: CredentialType\n /** Expiration timestamp */\n expiresAt?: Date\n}\n\nexport interface ToolPermissionVC extends DelegationVC {\n credentialSubject: {\n id: string\n tool: string // e.g., \"slack.message.post\"\n resourceScope?: Record<string, any> // e.g., { channel: \"C123\" }\n aud: string // e.g., \"slack\"\n }\n}\n\nexport interface DataAccessVC extends DelegationVC {\n credentialSubject: {\n id: string\n resource: string // e.g., \"agent/did:agent:abc/*\"\n actions: ('read' | 'write' | 'delete')[]\n }\n}\n\nexport interface VCTemplate<T extends DelegationVC = DelegationVC> {\n type: string\n name: string\n description?: string\n defaults?: Partial<T>\n validate?: (vc: T) => boolean\n}\n","export class AIdentityError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: any\n ) {\n super(message)\n this.name = this.constructor.name\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class VCExpiredError extends AIdentityError {\n constructor(message = 'Verifiable Credential has expired', details?: any) {\n super(message, 'VC_EXPIRED', details)\n }\n}\n\nexport class ScopeUnmatchedError extends AIdentityError {\n constructor(message = 'Scope does not match required permissions', details?: any) {\n super(message, 'SCOPE_UNMATCHED', details)\n }\n}\n\nexport class VCRevokedError extends AIdentityError {\n constructor(message = 'Verifiable Credential has been revoked', details?: any) {\n super(message, 'VC_REVOKED', details)\n }\n}\n\nexport class InvalidVPError extends AIdentityError {\n constructor(message = 'Verifiable Presentation is invalid', details?: any) {\n super(message, 'INVALID_VP', details)\n }\n}\n\nexport class AuthenticationError extends AIdentityError {\n constructor(message = 'Authentication failed', details?: any) {\n super(message, 'AUTH_FAILED', details)\n }\n}\n\nexport class NetworkError extends AIdentityError {\n constructor(message = 'Network request failed', details?: any) {\n super(message, 'NETWORK_ERROR', details)\n }\n}","/**\n * Permission VC Claims Schema v2\n *\n * This is the CANONICAL format for Permission Verifiable Credential claims.\n * All VC issuance paths MUST produce claims conforming to this schema.\n * The PolicyEvaluator consumes this schema directly.\n *\n * Design principles:\n * - Grant data is normalized into this format during VC issuance\n * - PermissionRule is the atomic unit of authorization\n * - Resource representation uses provider + type + id/pattern (OPA-compatible)\n * - Constraints are carried per-rule for fine-grained control\n * - Future OPA integration: this schema maps directly to OPA input document\n */\n\n// ---------------------------------------------------------------------------\n// Resource Representation (unified across Grant, VC, and Policy)\n// ---------------------------------------------------------------------------\n\n/**\n * Service provider identifier.\n * @deprecated Import { CanonicalProvider, AnyProvider } from '@vess-id/ai-identity' registry instead.\n * Kept for backward compatibility with existing code.\n */\nexport type Provider = 'slack' | 'github' | 'google' | 'drive' | 'gmail' | 'jira'\n\n/**\n * Resource target within a permission rule.\n *\n * Separates provider from resource type (unlike Grant's combined \"slack:channel\").\n * This enables cleaner OPA policy evaluation and avoids string-parsing at runtime.\n *\n * @example\n * ```typescript\n * // Specific channel\n * { type: 'channel', id: 'C123456' }\n *\n * // Pattern match\n * { type: 'channel', pattern: 'public-*' }\n *\n * // All resources of a type\n * { type: 'channel', id: '*' }\n *\n * // All resource types for a provider\n * { type: '*', id: '*' }\n * ```\n */\nexport interface PermissionResource {\n /** Resource type (e.g., 'channel', 'repo', 'file', 'issue') */\n type: string\n /** Specific resource ID. Use '*' for all resources of this type. */\n id?: string\n /** Glob pattern for resource ID matching (e.g., 'public-*', 'team-?-dev') */\n pattern?: string\n /** Tenant reference (e.g., workspace ID, org ID) */\n tenant_ref?: string\n}\n\n// ---------------------------------------------------------------------------\n// Constraint Representation (unified across Grant, VC, and Policy)\n// ---------------------------------------------------------------------------\n\n/**\n * Time window constraint.\n *\n * Supports both:\n * - Recurring windows (start/end HH:mm with daysOfWeek) - from Grant model\n * - Absolute windows (not_before/not_after unix timestamps) - for VC-level\n *\n * The VC issuance layer converts Grant's recurring windows into the\n * appropriate format based on context.\n */\nexport interface PermissionTimeConstraint {\n /** Absolute not-before (unix timestamp) */\n not_before?: number\n /** Absolute not-after (unix timestamp) */\n not_after?: number\n /** Recurring: allowed time start (HH:mm, UTC unless timezone specified) */\n recurring_start?: string\n /** Recurring: allowed time end (HH:mm, UTC unless timezone specified) */\n recurring_end?: string\n /** Recurring: allowed days of week (0=Sun, 1=Mon...6=Sat) */\n days_of_week?: number[]\n /** Timezone for recurring constraints (default: 'UTC') */\n timezone?: string\n}\n\n/**\n * Rule-level constraints embedded in each PermissionRule.\n *\n * These are evaluated at policy decision time and support both\n * Grant-originated constraints and VC-specific constraints.\n */\nexport interface PermissionConstraints {\n /** Time constraints */\n time?: PermissionTimeConstraint\n /** Maximum invocations for this specific rule */\n max_invocations?: number\n /** Rate limiting (requests per minute) */\n rate_limit_per_min?: number\n /** Allowed IP ranges (CIDR notation) */\n ip_allowlist?: string[]\n /** Maximum risk score threshold (0-100) */\n risk_threshold?: number\n /** Purpose description (for audit trail) */\n purpose?: string\n /** Scope constraints (provider-specific, e.g., { thread_id: 'T123' }) */\n scope?: Record<string, unknown>\n /**\n * Target constraints for secondary destinations (cc, attendees, etc.).\n * Alpha: defined but NOT evaluated by ConstraintEvaluator.\n * Future: evaluated against PolicyInput.request.targets.\n */\n targets?: import('./target-binding').TargetConstraint[]\n}\n\n// ---------------------------------------------------------------------------\n// Policy Reference (Phase 1: Cedar policy binding)\n// ---------------------------------------------------------------------------\n\n/**\n * Inline policy mode — full Cedar policy embedded in the VC.\n *\n * Used for sub-agent re-delegation where the verifier cannot reach the\n * Policy Registry over the network. The inline policy is authoritative;\n * `policy_hash` is a sanity check for tamper-evidence.\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.2\n */\nexport interface PolicyRefInline {\n mode: 'inline'\n /** Full Cedar policy source (PolicySet text, UTF-8). */\n policy_inline: string\n /** sha256 of `policy_inline` (hex), prefixed `sha256-` for tamper-evidence. */\n policy_hash: string\n /**\n * Cedar schema fragment id. **Phase 1 unused** (Cedar wasm schema-less\n * evaluation, Implementation plan §1.1). **Phase 2+ で per-policy schema\n * 切替時に inline モードでは REQUIRED 化** (reference モードは Registry\n * resolve で取得できるため optional のまま).\n */\n schema_id?: string\n}\n\n/**\n * Reference policy mode — policy lives in the Policy Registry.\n *\n * The verifier fetches `policy_uri` (must match the issuer's\n * `/.well-known/policy-registry/:policy_id`), validates `policy_hash`,\n * and evaluates the fetched Cedar policy.\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.2\n */\nexport interface PolicyRefReference {\n mode: 'reference'\n /** Policy Registry id. Format: `pol_<project_id>_<uuidv7>`. */\n policy_id: string\n /** Absolute URL to `/.well-known/policy-registry/:policy_id`. */\n policy_uri: string\n /** sha256 of the served Cedar policy text (hex), prefixed `sha256-`. */\n policy_hash: string\n /**\n * Cedar schema fragment id. Phase 1 unused (Registry resolve で取得可能、\n * schema-less evaluation を使う簡易構成)。Phase 2+ で per-policy schema を\n * 導入したときも reference モードは引き続き OPTIONAL — VC payload に\n * 同梱せず Registry 側で resolve する方針。\n */\n schema_id?: string\n}\n\n/**\n * Tagged union of policy reference shapes. Discriminator: `mode`.\n *\n * Use {@link isPolicyRefInline} / {@link isPolicyRefReference} for runtime\n * narrowing.\n */\nexport type PolicyRef = PolicyRefInline | PolicyRefReference\n\n/** Type guard for {@link PolicyRefInline}. */\nexport function isPolicyRefInline(ref: PolicyRef): ref is PolicyRefInline {\n return ref.mode === 'inline'\n}\n\n/** Type guard for {@link PolicyRefReference}. */\nexport function isPolicyRefReference(ref: PolicyRef): ref is PolicyRefReference {\n return ref.mode === 'reference'\n}\n\n// ---------------------------------------------------------------------------\n// Permission Rule (atomic authorization unit)\n// ---------------------------------------------------------------------------\n\n/**\n * Permission Rule - the atomic unit of authorization.\n *\n * Each rule grants specific actions on specific resources for a specific provider.\n * Rules are evaluated independently during policy evaluation.\n *\n * Phase 1 (Cedar + RAR redesign) extensions:\n * - `effect` widened from `'allow'` only to the 3-valued\n * `'allow' | 'deny' | 'require_approval'` (spec §5).\n * Existing call-sites that only used `'allow'` remain source-compatible.\n * - `priority` field added (optional, used for deterministic ordering when\n * multiple rules match the same request).\n * - `policy_ref` field added (optional in Phase 1 for backward-compat\n * during migration; Phase 2+ will bump the schema to v3.1 and make it\n * required — see spec §3.1 reconciliation note).\n *\n * OPA mapping (legacy `'allow'`-only path, still used while\n * `CEDAR_POLICY_ENABLED != enforce`):\n * ```rego\n * allow {\n * some rule in input.credentials.delegates\n * rule.effect == \"allow\"\n * rule.provider == input.request.provider\n * glob.match(rule.resource.type, [], input.request.resource.type)\n * resource_id_matches(rule.resource, input.request.resource.id)\n * action_matches(rule.actions, input.request.action)\n * constraints_satisfied(rule.constraints, input.environment)\n * }\n * ```\n */\nexport interface PermissionRule {\n /** Rule identifier (for audit trail and matched_rule_id) */\n id?: string\n /**\n * Effect. Phase 1 widens this beyond legacy `'allow'`-only:\n * - `'allow'` — permit the action (legacy default).\n * - `'deny'` — explicit deny (override precedence over allow).\n * - `'require_approval'` — pause and request human approval.\n */\n effect: 'allow' | 'deny' | 'require_approval'\n /**\n * Optional priority for deterministic ordering when multiple rules match.\n * Higher priority wins. Phase 1 evaluator behaviour is unchanged when\n * `priority` is absent.\n */\n priority?: number\n /** Service provider */\n provider: Provider | string\n /** Target resource */\n resource: PermissionResource\n /** Allowed actions (e.g., ['post_message', 'read_history']). '*' for all. */\n actions: string[]\n /** Rule-level constraints */\n constraints?: PermissionConstraints\n /**\n * Cedar policy binding (Phase 1).\n *\n * When present, the policy engine evaluates this delegate via the\n * referenced / inlined Cedar policy in addition to the static constraint\n * check. Optional in Phase 1 for backward-compat during migration; Phase\n * 2+ will bump the schema to v3.1 and make it required.\n */\n policy_ref?: PolicyRef\n /**\n * Cedar policy bindings (複数) — 1 つの委任スコープに複数の policy が AND/OR\n * で適用されるケース (例: calendarDomain 宛先制約 + timeWindow forbid)。\n * 後方互換のため単数 `policy_ref` は維持し、発行時は `policy_refs[0]` を\n * ミラーする。読み手は policy_refs を優先し、無ければ policy_ref を単要素配列に\n * 正規化する。Cedar 評価では全 ref を 1 つの PolicySet に集約 (permit=OR,\n * forbid=override で AND)。\n */\n policy_refs?: PolicyRef[]\n}\n\n// ---------------------------------------------------------------------------\n// Permission VC Claims (the canonical VC payload)\n// ---------------------------------------------------------------------------\n\n/**\n * Permission VC Claims v2 — the pre-Cedar canonical credential claims format.\n *\n * This is what gets signed into the SD-JWT VC. All VC issuance paths\n * (VCService, RemoteVCIssuerService, PermissionVCManager) MUST produce\n * claims conforming to either this interface or {@link PermissionVcClaims_V3}.\n *\n * The Grant → VC normalization layer converts:\n * - GrantResource[] + actions[] → PermissionRule[]\n * - GrantConstraints → PermissionConstraints (per-rule)\n * - Grant metadata → top-level claims fields\n *\n * @remarks Phase 1 Step 2 renamed the original `PermissionVcClaims` to\n * `PermissionVcClaims_V2`. The exported alias {@link PermissionVcClaims}\n * is now a union of V2 + {@link PermissionVcClaims_V3}, preserving\n * existing import sites (they will accept both shapes).\n */\nexport interface PermissionVcClaims_V2 {\n /** Schema version */\n v: '2'\n /** Credential type discriminator */\n type: 'PermissionCredential'\n /** Issuer DID (user who granted permission) */\n iss: string\n /** Subject DID (agent receiving permission) */\n sub: string\n /** Issued at (unix timestamp) */\n iat: number\n /** Not before (unix timestamp) */\n nbf?: number\n /** Expiration (unix timestamp) */\n exp: number\n /** JWT ID (unique credential identifier) */\n jti: string\n /** Project ID */\n project_id: string\n /** User ID (grant owner) */\n user_id?: string\n /** User DID (grant owner) */\n user_did?: string\n /** Source grant IDs (supports multiple grants aggregated into one VC) */\n grant_ids: string[]\n /**\n * Primary grant ID (derived from grant_ids[0]).\n * @deprecated Use grant_ids instead. Kept for backward-compat JWT claims.\n * Always set via {@link buildGrantIdFields} to keep both fields in sync.\n */\n grant_id: string\n /** Session ID (binds VC to specific session) */\n session_id: string\n /** Parent JWT ID for re-delegation chain (not supported in MVP) */\n parent_jti?: string\n /** Confirmation (Proof of Possession binding) */\n cnf?: {\n /** JWK for Proof of Possession (SD-JWT KB-JWT standard) */\n jwk: Record<string, unknown>\n }\n /** Delegated permission rules (the core authorization data) */\n delegates: PermissionRule[]\n}\n\n/**\n * Permission VC Claims v3 — Cedar + RAR Phase 1 schema.\n *\n * Inherits all V2 fields and adds two Phase-1-aware extensions:\n * - `cedar_schema_ref?` — pointer to the Cedar schema fragment the\n * delegates were authored against. **Phase 1 unused** (the SDK ships a\n * single global schema fragment generated by connector-plugin codegen,\n * per Implementation plan §1.1). Reserved for Phase 2+ per-policy schema\n * switching.\n * - `layer?` — chain hierarchy layer. **Phase 2+ only**; Phase 1 issuance\n * pins this to `'agent_permission'` via {@link buildPhase1VcClaims}.\n * Direct assignment is discouraged (ESLint rule planned in Step 5).\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.1\n * - docs/specs/2026-05-23-cedar-rar-implementation-plan-phase1.md Task 2.1 / 2.5\n */\n/**\n * Bug B 真因修正 (β, 2026-05-28) — VC=mandate semantic を invoke 時 Cedar も\n * 信じるため、approval の事実 (誰がいつ何を approve したか) を VC に焼き込む\n * signed self-attestation。SD-protected (`_sd` 経由 disclosure)、SD-JWT 署名で\n * 改竄不可。invoke 時 Cedar context.approval の最優先 source として採用。\n *\n * Forward compat: A2A AP2 Mandate (IntentMandate / CartMandate / PaymentMandate)\n * との projection は Phase 2 spec で別途定義。本 field 名は内部\n * ApprovalContext (snake_case) と一貫。\n *\n * Spec ref: docs/superpowers/plans/2026-05-28-bug-b-fix-beta-vc-embed-approval.md\n */\nexport interface VcApprovalClaim {\n /** `req_<uuid>` — 元 approval-request id (claimVC 元 request の id)。 */\n request_id: string\n /** `outcome_<uuid>` — APPROVAL_OUTCOME audit event id (§11.1 join key)。 */\n outcome_id: string\n /** approver の user id、または 'system' (auto-approve 経路)。最大 128 chars。 */\n granted_by: string\n /** ISO-8601 timestamp of the approval action. */\n granted_at: string\n}\n\nexport interface PermissionVcClaims_V3 extends Omit<PermissionVcClaims_V2, 'v'> {\n /** Schema version — v3 adds Cedar policy_ref support and chain hierarchy fields. */\n v: '3'\n /**\n * Cedar schema fragment reference (Phase 2+ per-policy schema switching).\n * Phase 1: unused; SDK uses connector-plugin codegen global schema.\n */\n cedar_schema_ref?: {\n /** e.g. `cedar_schema_2026_05_23_v1`. */\n schema_id: string\n /** sha256 of the schema fragment (hex). */\n schema_hash: string\n }\n /**\n * 4-layer chain (Org Policy → User Grant → Agent Permission → Sub-Agent Delegation).\n * Phase 1 では `buildPhase1VcClaims()` factory 経由で `'agent_permission'` が固定セットされる。\n * Phase 2+ では本フィールドを **required** に格上げする予定 (V3.1 schema)。\n * 直接代入は禁止 (Phase 1 では factory を使うこと、Phase 2+ では ESLint rule で強制)。\n * 詳細: design spec §3.1, §6.1 / Phase 1 plan Task 2.5。\n */\n layer?: 'org_policy' | 'user_grant' | 'agent_permission' | 'sub_agent_delegation'\n /**\n * Bug B 真因修正 (β, 2026-05-28) — approval メタを VC に焼き込む。\n * VC=mandate なので「この VC が発行されたこと自体が approve の証拠」だが、\n * invoke 時 Cedar に `context.approval.granted == true` を渡せるよう\n * back-ref を明示。本 field 不在 = base path (legacy 互換、Cedar は token-\n * ledger 経由 fallback)。{@link VcApprovalClaim} 参照。\n */\n approval?: VcApprovalClaim\n}\n\n/**\n * Permission VC Claims (canonical union of v2 + v3).\n *\n * All existing import sites referencing `PermissionVcClaims` continue to\n * compile because:\n * - Code that only produced V2 still produces a value assignable to the\n * union.\n * - Code that consumes the union can narrow on `claims.v === '3'` to\n * access V3-only fields.\n */\nexport type PermissionVcClaims = PermissionVcClaims_V2 | PermissionVcClaims_V3\n\n/**\n * Build synchronized grant_id / grant_ids fields for PermissionVcClaims.\n * Guarantees grant_id === grant_ids[0].\n */\nexport function buildGrantIdFields(grantIds: string[]): { grant_ids: string[]; grant_id: string } {\n if (grantIds.length === 0) {\n throw new Error('grantIds must contain at least one element')\n }\n return { grant_ids: grantIds, grant_id: grantIds[0] }\n}\n\n// ---------------------------------------------------------------------------\n// Policy Evaluation Types (OPA-compatible input/output)\n// ---------------------------------------------------------------------------\n\n/**\n * Policy evaluation input document.\n *\n * Designed to map 1:1 to OPA input document for future integration:\n * ```rego\n * package aidentity.authz\n *\n * default allow = false\n *\n * allow {\n * some rule in input.credentials.delegates\n * rule_matches(rule, input.request)\n * constraints_ok(rule.constraints, input.environment)\n * }\n * ```\n */\nexport interface PolicyInput {\n /** Subject (who is requesting) */\n subject: {\n /** Agent DID */\n agent_did: string\n /** Session ID */\n session_id: string\n /** User DID (delegator) */\n user_did?: string\n }\n /** Tenant context */\n tenant: {\n /** Project ID */\n project_id: string\n }\n /** Request details (what is being requested) */\n request: {\n /** Service provider */\n provider: string\n /** Action to perform */\n action: string\n /** Target resource */\n resource: {\n type: string\n id: string\n /** Tenant/workspace reference for multi-account disambiguation (future) */\n tenant_ref?: string\n }\n /** Secondary targets extracted from tool parameters via TargetResolver */\n targets?: import('./target-binding').PolicyTarget[]\n /** Raw tool parameters (for OPA custom policies) */\n params?: Record<string, unknown>\n }\n /** Credential information (from VC) */\n credentials: {\n /** JWT ID */\n jti: string\n /** Source grant IDs */\n grant_ids: string[]\n /** Primary grant ID */\n grant_id: string\n /** Issued at timestamp */\n issued_at: number\n /** Expiration timestamp */\n expires_at: number\n /** Delegated permission rules from VC */\n delegates: PermissionRule[]\n }\n /** Environment context (evaluated at request time) */\n environment: {\n /** Current timestamp (unix) */\n now: number\n /** Client IP address */\n ip_address?: string\n /** Risk score (0-100) */\n risk_score?: number\n /** Current invocation count for the grant */\n invocation_count?: number\n }\n}\n\n/**\n * Policy evaluation result\n */\nexport interface PolicyEvaluationResult {\n /** Whether the action is allowed */\n allowed: boolean\n /** Denial reason if not allowed */\n reason?: string\n /** Error code for programmatic handling */\n reason_code?: string\n /** Matched rule ID (if allowed) */\n matched_rule_id?: string\n /** Which evaluation step failed (for debugging) */\n step_failed?: string\n}\n\n// ---------------------------------------------------------------------------\n// External Action Request (normalized tool invocation request)\n// ---------------------------------------------------------------------------\n\n/**\n * External Action Request - normalized format for tool invocations.\n * Used as the bridge between MCP tool calls and policy evaluation.\n */\nexport interface ExternalActionRequest {\n /** Request ID for idempotency */\n request_id: string\n /** Service provider */\n provider: Provider | string\n /** Action to perform */\n action: string\n /** Target resource */\n resource: {\n type: string\n id: string\n }\n /** Project ID */\n project_id: string\n /** Session ID */\n session_id: string\n /** Action parameters (sanitized) */\n params?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Grant → VC Normalization Utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Parsed provider and resource type from a Grant's combined resource type string.\n *\n * Grant uses \"slack:channel\" format, but VC uses separate provider + resource.type.\n * This interface represents the parsed result.\n */\nexport interface ParsedResourceType {\n provider: string\n resourceType: string\n}\n\n/**\n * Parse a Grant resource type string into provider and resource type.\n *\n * @example\n * parseGrantResourceType('slack:channel') // { provider: 'slack', resourceType: 'channel' }\n * parseGrantResourceType('github:repo') // { provider: 'github', resourceType: 'repo' }\n * parseGrantResourceType('slack') // { provider: 'slack', resourceType: '*' }\n * parseGrantResourceType('*') // { provider: '*', resourceType: '*' }\n */\nexport function parseGrantResourceType(grantType: string): ParsedResourceType {\n if (grantType === '*') {\n return { provider: '*', resourceType: '*' }\n }\n const colonIndex = grantType.indexOf(':')\n if (colonIndex === -1) {\n return { provider: grantType, resourceType: '*' }\n }\n return {\n provider: grantType.substring(0, colonIndex),\n resourceType: grantType.substring(colonIndex + 1),\n }\n}\n\n/**\n * Parse a Grant action string into provider and action.\n *\n * Grant actions use \"provider.resource.operation\" (dot format, canonical) or\n * legacy \"provider:resource.operation\" (colon format).\n * This extracts the provider prefix and the action name.\n *\n * @example\n * parseGrantAction('slack.message.read') // { provider: 'slack', action: 'message.read' }\n * parseGrantAction('slack:channel.post_message') // { provider: 'slack', action: 'channel.post_message' }\n * parseGrantAction('*') // { provider: '*', action: '*' }\n */\nexport function parseGrantAction(grantAction: string): { provider: string; action: string } {\n if (grantAction === '*') {\n return { provider: '*', action: '*' }\n }\n // Try colon format first (legacy): \"slack:channel.post_message\"\n const colonIndex = grantAction.indexOf(':')\n if (colonIndex > 0) {\n return {\n provider: grantAction.substring(0, colonIndex),\n action: grantAction.substring(colonIndex + 1),\n }\n }\n // Try dot format (canonical): \"slack.message.read\"\n const dotIndex = grantAction.indexOf('.')\n if (dotIndex > 0) {\n return {\n provider: grantAction.substring(0, dotIndex),\n action: grantAction.substring(dotIndex + 1),\n }\n }\n return { provider: '*', action: grantAction }\n}\n\n// ---------------------------------------------------------------------------\n// Phase 1 VC issuance factory (layer pinning)\n// ---------------------------------------------------------------------------\n\n/**\n * The single layer value Phase 1 VC issuance is allowed to emit.\n *\n * companion design spec §3.1 defines a 4-layer enum\n * (`'org_policy' | 'user_grant' | 'agent_permission' | 'sub_agent_delegation'`),\n * but Phase 1 only issues at the `agent_permission` layer. The other 3\n * layers unlock in Phase 2+.\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-implementation-plan-phase1.md Task 2.5 (rev 5)\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.1 Phase 1 layer 固定 note\n */\nexport const PHASE_1_VC_LAYER = 'agent_permission' as const\n\n/** Literal type of {@link PHASE_1_VC_LAYER}. */\nexport type Phase1VcLayer = typeof PHASE_1_VC_LAYER\n\n/**\n * Build a {@link PermissionVcClaims_V3} object with `layer` pinned to\n * {@link PHASE_1_VC_LAYER} (`'agent_permission'`).\n *\n * **This factory is mandatory for Phase 1 VC issuance.** Direct assignment\n * of `layer` on a V3 claims literal is discouraged and will be guarded by\n * an ESLint rule once Step 5 wires usage in\n * `packages/api/src/grant/services/remote-vc-issuer.service.ts`. Phase 2+\n * will relax or delete this factory when the other 3 layers unlock.\n *\n * The input `base` type explicitly omits `layer` so passing it is a\n * compile-time error — guaranteeing call-sites cannot accidentally\n * smuggle a non-Phase-1 layer value through.\n *\n * @example\n * ```ts\n * import { buildPhase1VcClaims } from '@vess-id/ai-identity'\n *\n * const claims = buildPhase1VcClaims({\n * v: '3',\n * type: 'PermissionCredential',\n * iss: userDid,\n * sub: agentDid,\n * iat: now,\n * exp: now + 3600,\n * jti,\n * project_id,\n * grant_ids,\n * grant_id,\n * session_id,\n * delegates,\n * })\n * // claims.layer is type-narrowed to 'agent_permission'\n * ```\n */\nexport function buildPhase1VcClaims(\n base: Omit<PermissionVcClaims_V3, 'layer'>,\n): PermissionVcClaims_V3 & { layer: Phase1VcLayer } {\n return { ...base, layer: PHASE_1_VC_LAYER }\n}\n","/**\n * Grant(許可)関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\n/**\n * Grant(許可)の状態\n */\nexport enum GrantStatus {\n PENDING = 'pending', // Agent未確定(OAuth後、Agent接続前)\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REVOKED = 'revoked',\n SUSPENDED = 'suspended',\n EXHAUSTED = 'exhausted' // 回数上限到達\n}\n\n/**\n * Grant(許可)のスコープ\n *\n * - PROJECT: プロジェクト全体に適用される Grant(全メンバーが継承)\n * - USER: 特定ユーザーのみに適用される Grant\n */\nexport enum GrantScope {\n PROJECT = 'project', // Project-level Grant (全メンバーに適用)\n USER = 'user' // User-level Grant (特定ユーザーのみ)\n}\n\n/**\n * リソースタイプ\n */\nexport enum GrantResourceType {\n // Slack\n SLACK_CHANNEL = 'slack:channel',\n SLACK_USER = 'slack:user',\n SLACK_WORKSPACE = 'slack:workspace',\n // GitHub\n GITHUB_REPO = 'github:repo',\n GITHUB_ORG = 'github:org',\n GITHUB_ISSUE = 'github:issue',\n // Google Drive\n GOOGLE_DRIVE_FILE = 'google:drive:file',\n GOOGLE_DRIVE_FOLDER = 'google:drive:folder',\n // Gmail\n GMAIL_THREAD = 'gmail:thread',\n GMAIL_LABEL = 'gmail:label',\n // JIRA\n JIRA_PROJECT = 'jira:project',\n JIRA_BOARD = 'jira:board',\n JIRA_ISSUE = 'jira:issue',\n // OS (local)\n OS_SECRET = 'os:secret',\n // Generic\n ANY = '*'\n}\n\n/**\n * 許可されたリソース範囲\n *\n * Grant(許可)で指定するリソースの範囲を定義します。\n * type、id、patternの組み合わせにより、柔軟なアクセス制御を実現します。\n *\n * @example 基本的な使用例\n * ```typescript\n * // 1. 完全一致: 特定のリソースIDのみ許可\n * const resource1: GrantResource = {\n * type: \"slack:channel\",\n * id: \"C123456\",\n * name: \"general\"\n * }\n *\n * // 2. タイプ全体: 特定タイプの全リソースを許可(セキュリティ注意)\n * const resource2: GrantResource = {\n * type: \"slack:channel\" // 全チャンネルへのアクセスを許可\n * }\n *\n * // 3. パターンマッチ: ワイルドカードを使用\n * const resource3: GrantResource = {\n * type: \"slack:channel\",\n * pattern: \"public-*\", // \"public-\"で始まる全チャンネル\n * name: \"Public channels\"\n * }\n * ```\n *\n * @example 階層的タイプマッチング\n * ```typescript\n * // ベースタイプは全サブタイプにマッチ(セキュリティ注意)\n * const baseType: GrantResource = {\n * type: \"slack\" // \"slack:channel\", \"slack:message\", \"slack:file\" など全てを許可\n * }\n *\n * // ワイルドカードサフィックス\n * const wildcardType: GrantResource = {\n * type: \"slack:*\" // \"slack:channel\", \"slack:message\" など slack: 配下の全タイプを許可\n * }\n *\n * // 具体的なタイプ(推奨)\n * const specificType: GrantResource = {\n * type: \"slack:channel\", // チャンネルのみ\n * pattern: \"team-*\" // さらにパターンで制約\n * }\n * ```\n *\n * @example セキュリティベストプラクティス\n * ```typescript\n * // ❌ 避けるべき設定\n * const bad1: GrantResource = {\n * type: \"*\" // 全リソースタイプへのアクセス(最高リスク)\n * }\n *\n * const bad2: GrantResource = {\n * type: \"slack\" // 全Slackリソースへのアクセス(高リスク)\n * }\n *\n * // ✅ 推奨される設定\n * const good1: GrantResource = {\n * type: \"slack:channel\",\n * id: \"C123456\" // 特定チャンネルのみ(最も安全)\n * }\n *\n * const good2: GrantResource = {\n * type: \"slack:channel\",\n * pattern: \"public-*\" // パターンで制約(比較的安全)\n * }\n *\n * const good3: GrantResource = {\n * type: \"github:repo\",\n * pattern: \"org-name/*\" // 特定組織のリポジトリのみ\n * }\n * ```\n *\n * @security セキュリティガイドライン\n *\n * 1. **最小権限の原則**: 必要最小限のアクセス権限のみを付与\n * - 可能な限り具体的な type を使用\n * - id または pattern で範囲を制限\n *\n * 2. **ベースタイプの危険性**:\n * - type: \"slack\" は \"slack:channel\", \"slack:message\" など全てを許可\n * - 意図しない広範なアクセスを与える可能性\n *\n * 3. **ワイルドカード使用の注意**:\n * - type: \"*\" は全リソースタイプにマッチ(本番環境では避ける)\n * - pattern: \"*\" は全IDにマッチ(極めて慎重に使用)\n *\n * 4. **パターン構文**:\n * - '*' = 0文字以上の任意の文字列(例: \"test-*\" → \"test-1\", \"test-abc\")\n * - '?' = 1文字の任意の文字(例: \"test-?\" → \"test-1\", \"test-a\")\n * - 正規表現として評価されるため、特殊文字のエスケープに注意\n *\n * 5. **ID/pattern未指定の影響**:\n * - id も pattern も未指定の場合、そのタイプの全リソースへのアクセスを許可\n * - 必ず適切な制約を設定することを推奨\n */\nexport interface GrantResource {\n /**\n * リソースタイプ\n *\n * リソースの種類を指定します。階層的な記法をサポート。\n *\n * 形式:\n * - 単純: \"slack\", \"github\"\n * - 階層的: \"slack:channel\", \"github:repo\", \"drive:file\"\n * - ワイルドカード: \"*\", \"slack:*\"\n *\n * @example\n * - \"slack\" → 全Slackリソース(channel, message, file等)\n * - \"slack:channel\" → Slackチャンネルのみ\n * - \"slack:*\" → slack:配下の全タイプ\n * - \"*\" → 全リソースタイプ\n */\n type: GrantResourceType | string\n\n /**\n * 特定リソースID(省略時はそのタイプの全リソースを許可)\n *\n * 具体的なリソースの識別子を指定します。\n * 最も厳格なアクセス制御方法です。\n *\n * @example\n * - \"C123456\" → 特定のSlackチャンネルID\n * - \"repo123\" → 特定のGitHubリポジトリ\n * - undefined → タイプの全リソースを許可(セキュリティ注意)\n */\n id?: string\n\n /**\n * パターンマッチ(例: \"general-*\", \"team-?\")\n *\n * ワイルドカードを使用したパターンマッチングを指定します。\n * id よりも柔軟ですが、より広範なアクセスを許可します。\n *\n * パターン構文:\n * - '*' = 0文字以上の任意の文字列\n * - '?' = 1文字の任意の文字\n *\n * @example\n * - \"public-*\" → \"public-general\", \"public-test\" など\n * - \"team-*-dev\" → \"team-frontend-dev\", \"team-backend-dev\" など\n * - \"C??????\" → Cで始まる6文字のID\n * - \"*\" → 全ID(極めて慎重に使用)\n */\n pattern?: string\n\n /**\n * 表示用名称\n *\n * UIなどでの表示に使用される人間が読める名前です。\n * アクセス制御には影響しません。\n *\n * @example\n * - \"General channel\"\n * - \"Public channels\"\n * - \"Production repositories\"\n */\n name?: string\n\n /**\n * テナント/ワークスペース参照\n *\n * 同一プロバイダーの複数アカウントを区別するための識別子。\n * 例: SlackのworkspaceId, JiraのcloudId, GitHubのorg名\n *\n * Alpha: 定義のみ、評価ロジックなし。\n * 将来のマルチアカウント対応で使用。\n */\n tenant_ref?: string\n}\n\n/**\n * 時間帯制約\n */\nexport interface TimeWindowConstraint {\n /** 許可時間帯開始(HH:mm形式) */\n start?: string\n /** 許可時間帯終了(HH:mm形式) */\n end?: string\n /** タイムゾーン(デフォルト: UTC) */\n timezone?: string\n /** 許可曜日(0=日, 1=月...6=土) */\n daysOfWeek?: number[]\n}\n\n/**\n * 自動承認設定\n * low-riskアクションをapprove.htmlなしで自動的にVC発行する\n */\nexport interface AutoApproveConfig {\n /** 自動承認を有効にするか */\n enabled: boolean\n /** 自動承認を許可するリスクレベル上限 (default: 'low') */\n maxRiskLevel?: 'low' | 'medium'\n /** 自動発行VCの最大有効期間(時間) (default: 24) */\n maxDurationHours?: number\n}\n\n/**\n * Grant制約\n */\nexport interface GrantConstraints {\n /** 最大実行回数 */\n maxInvocations?: number\n /** 時間帯制約 */\n timeWindow?: TimeWindowConstraint\n /** 有効期限(ISO 8601) - constraintsレベルでも指定可能 */\n expiresAt?: string\n /** 許可IPレンジ(CIDR表記) */\n ipAllowlist?: string[]\n /** 許容リスクスコア上限(0-100) */\n riskThreshold?: number\n /** Target constraints for secondary destinations (alpha: type only) */\n targets?: import('./target-binding').TargetConstraint[]\n /** 自動承認設定 */\n autoApprove?: AutoApproveConfig\n /**\n * Cedar 一元化 Step 4 — data-in-policy 許可パターン (Cedar `like` wildcard).\n *\n * 例: `[\"*@vess.id\", \"*@vesslabs.ai\"]` → 各 recipient.address に対し\n * `like \"*@vess.id\" || like \"*@vesslabs.ai\"` の Cedar permit rule が emit される.\n *\n * Spec: docs/specs/2026-05-24-cedar-unification-design.md §4.1 / §13 Step 4\n *\n * Phase 1 では primarily Gmail recipient address のために使う (recipient.address).\n * Phase 2+ で per-target-binding な格納先 (channel.id 等) に拡張する.\n */\n allow_patterns?: string[]\n /**\n * Cedar 一元化 Step 4 — data-in-policy 拒否パターン (Cedar `like` wildcard).\n *\n * 例: `[\"*@competitor.com\"]` → 該当 recipient で Cedar `forbid` rule が emit される.\n * Cedar forbid-overrides-permit semantics により approval があっても denied.\n *\n * Spec: docs/specs/2026-05-24-cedar-unification-design.md §4.1 / §4.2 / §13 Step 4\n */\n deny_patterns?: string[]\n}\n\n/**\n * Grant作成リクエスト\n */\nexport interface CreateGrantRequest {\n /** 許可名(表示用) */\n name: string\n /** 説明 */\n description?: string\n /** Grantのスコープ (project or user) */\n grantScope?: GrantScope\n /** 対象ユーザーID(USER scopeの場合は必須、PROJECT scopeの場合はnull) */\n userId?: string\n /** 許可するリソース範囲 */\n resources: GrantResource[]\n /** 許可するアクション(例: slack:channel.post_message) */\n actions: string[]\n /** 制約 */\n constraints: GrantConstraints\n /** 関連プロジェクトID */\n projectId?: string\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Grant更新リクエスト\n */\nexport interface UpdateGrantRequest {\n /** 許可名 */\n name?: string\n /** 説明 */\n description?: string\n /** リソース範囲 */\n resources?: GrantResource[]\n /** アクション */\n actions?: string[]\n /** 制約 */\n constraints?: GrantConstraints\n /** ステータス */\n status?: GrantStatus\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Grant\n */\nexport interface Grant {\n /** 一意識別子 */\n id: string\n /** 許可名 */\n name: string\n /** 説明 */\n description?: string\n /** 許可を与えた人のDID */\n issuerDid: string\n /** 許可を与えた人の名前 */\n issuerName?: string\n /** Grantのスコープ (project or user) */\n grantScope: GrantScope\n /** 対象ユーザーID(USER scopeの場合のみ、PROJECT scopeの場合はnull) */\n userId?: string\n /** ステータス */\n status: GrantStatus\n /** リソース範囲 */\n resources: GrantResource[]\n /** 許可アクション */\n actions: string[]\n /** 制約 */\n constraints: GrantConstraints\n /** 現在の実行回数 */\n currentInvocations: number\n /** 関連プロジェクトID */\n projectId?: string\n /** 関連プロジェクト名 */\n projectName?: string\n /** 作成日時 */\n createdAt: string\n /** 更新日時 */\n updatedAt: string\n /** 有効期限 */\n expiresAt?: string\n /** 失効日時 */\n revokedAt?: string\n /** 失効理由 */\n revocationReason?: string\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Grant使用状況\n */\nexport interface GrantUsage {\n /** GrantのID */\n grantId: string\n /** 実行回数 */\n invocationCount: number\n /** 最終使用日時 */\n lastUsedAt?: string\n /** 残り実行回数(maxInvocationsが設定されている場合) */\n remainingInvocations?: number\n}\n\n/**\n * Grant権限チェックリクエスト\n */\nexport interface CheckGrantPermissionRequest {\n /** チェック対象のAgent DID */\n agentDid: string\n /** チェックするアクション */\n action: string\n /** チェックするリソース */\n resource?: {\n type: string\n id?: string\n }\n /** 評価コンテキスト */\n context?: {\n ipAddress?: string\n timestamp?: string\n }\n}\n\n/**\n * Grant権限チェック結果\n */\nexport interface CheckGrantPermissionResult {\n /** 許可されているか */\n allowed: boolean\n /** マッチしたGrantのID */\n grantId?: string\n /** 拒否理由(allowedがfalseの場合) */\n reason?: string\n /** 残り実行回数 */\n remainingInvocations?: number\n /** 警告メッセージ */\n warnings?: string[]\n}\n\n// ---------------------------------------------------------------------------\n// Grant → PermissionRule normalization\n// ---------------------------------------------------------------------------\n\nimport {\n PermissionRule,\n PermissionConstraints,\n PermissionResource,\n parseGrantResourceType,\n parseGrantAction,\n} from './permission-vc'\n\n/**\n * Convert Grant's GrantConstraints to PermissionConstraints format.\n *\n * Maps Grant-level constraints to per-rule PermissionConstraints:\n * - maxInvocations → max_invocations\n * - timeWindow → time (recurring)\n * - ipAllowlist → ip_allowlist\n * - riskThreshold → risk_threshold\n */\nexport function grantConstraintsToPermissionConstraints(\n constraints: GrantConstraints\n): PermissionConstraints | undefined {\n const result: PermissionConstraints = {}\n let hasValue = false\n\n if (constraints.maxInvocations !== undefined) {\n result.max_invocations = constraints.maxInvocations\n hasValue = true\n }\n\n if (constraints.timeWindow) {\n result.time = {}\n if (constraints.timeWindow.start) {\n result.time.recurring_start = constraints.timeWindow.start\n }\n if (constraints.timeWindow.end) {\n result.time.recurring_end = constraints.timeWindow.end\n }\n if (constraints.timeWindow.daysOfWeek) {\n result.time.days_of_week = constraints.timeWindow.daysOfWeek\n }\n if (constraints.timeWindow.timezone) {\n result.time.timezone = constraints.timeWindow.timezone\n }\n hasValue = true\n }\n\n if (constraints.ipAllowlist && constraints.ipAllowlist.length > 0) {\n result.ip_allowlist = constraints.ipAllowlist\n hasValue = true\n }\n\n if (constraints.riskThreshold !== undefined) {\n result.risk_threshold = constraints.riskThreshold\n hasValue = true\n }\n\n if (constraints.targets && constraints.targets.length > 0) {\n result.targets = constraints.targets\n hasValue = true\n }\n\n return hasValue ? result : undefined\n}\n\n/**\n * Normalize Grant data into PermissionRule[] for VC claims.\n *\n * This is the core normalization function that bridges the Grant model\n * (user-facing, \"slack:channel\" combined format) to the VC model\n * (machine-evaluated, separated provider + resource.type format).\n *\n * Algorithm:\n * 1. Group actions by provider prefix (slack:*, github:*, etc.)\n * 2. For each provider, create rules combining resources of that provider\n * 3. Attach normalized constraints to each rule\n *\n * @example\n * ```typescript\n * const grant = {\n * resources: [{ type: 'slack:channel', id: 'C123' }],\n * actions: ['slack:channel.post_message', 'slack:channel.read_history'],\n * constraints: { maxInvocations: 100, timeWindow: { start: '09:00', end: '18:00' } }\n * }\n *\n * const rules = grantToPermissionRules(grant.resources, grant.actions, grant.constraints)\n * // Result:\n * // [{\n * // effect: 'allow',\n * // provider: 'slack',\n * // resource: { type: 'channel', id: 'C123' },\n * // actions: ['channel.post_message', 'channel.read_history'],\n * // constraints: { max_invocations: 100, time: { recurring_start: '09:00', ... } }\n * // }]\n * ```\n */\nexport function grantToPermissionRules(\n resources: GrantResource[],\n actions: string[],\n constraints: GrantConstraints,\n grantId?: string\n): PermissionRule[] {\n const permConstraints = grantConstraintsToPermissionConstraints(constraints)\n\n // Group actions by provider\n const actionsByProvider = new Map<string, string[]>()\n for (const action of actions) {\n const parsed = parseGrantAction(action)\n const existing = actionsByProvider.get(parsed.provider) || []\n existing.push(parsed.action)\n actionsByProvider.set(parsed.provider, existing)\n }\n\n // Group resources by provider\n const resourcesByProvider = new Map<string, PermissionResource[]>()\n for (const resource of resources) {\n const parsed = parseGrantResourceType(resource.type as string)\n const existing = resourcesByProvider.get(parsed.provider) || []\n const permResource: PermissionResource = {\n type: parsed.resourceType,\n }\n if (resource.id) {\n permResource.id = resource.id\n }\n if (resource.pattern) {\n permResource.pattern = resource.pattern\n }\n if (resource.tenant_ref) {\n permResource.tenant_ref = resource.tenant_ref\n }\n existing.push(permResource)\n resourcesByProvider.set(parsed.provider, existing)\n }\n\n // Create rules: for each provider, combine its actions with its resources.\n // Wildcard ('*') entries are NOT emitted as standalone rules; they serve as\n // fallbacks for concrete providers that lack their own actions/resources.\n const rules: PermissionRule[] = []\n let ruleIndex = 0\n\n // Collect concrete (non-wildcard) providers from both maps\n const concreteProviders = new Set<string>()\n for (const key of actionsByProvider.keys()) {\n if (key !== '*') concreteProviders.add(key)\n }\n for (const key of resourcesByProvider.keys()) {\n if (key !== '*') concreteProviders.add(key)\n }\n\n // If there are NO concrete providers at all (everything is '*'), emit a\n // single wildcard rule so the grant still has effect.\n if (concreteProviders.size === 0) {\n concreteProviders.add('*')\n }\n\n for (const provider of concreteProviders) {\n const providerActions = actionsByProvider.get(provider) || actionsByProvider.get('*') || ['*']\n const providerResources = resourcesByProvider.get(provider) || resourcesByProvider.get('*') || [{ type: '*', id: '*' }]\n\n for (const resource of providerResources) {\n ruleIndex++\n const rule: PermissionRule = {\n id: grantId ? `${grantId}:r${ruleIndex}` : `r${ruleIndex}`,\n effect: 'allow',\n provider,\n resource,\n actions: providerActions,\n }\n if (permConstraints) {\n rule.constraints = permConstraints\n }\n rules.push(rule)\n }\n }\n\n return rules\n}\n\n/**\n * ApprovalContext — Cedar 一元化 Step 3.5.\n *\n * Spec refs:\n * - docs/specs/2026-05-24-cedar-unification-design.md §6 (approvalContext\n * DTO + token ledger)\n * - docs/specs/2026-05-24-cedar-unification-design.md §7.2 (Cedar\n * context.approval shape)\n * - docs/specs/2026-05-24-cedar-unification-design.md §11.1\n * (`via_approval` event lifecycle)\n *\n * Carried in the body of the VC issuance API on the **retry path** (i.e.\n * after a user clicked 承認 in the approval UI). The server consumes the\n * single-use `token` against the approval-token ledger atomically and then\n * injects `{ granted: true, request_id, outcome_id }` into the Cedar\n * `context.approval` so a policy that previously returned `auth_required`\n * now returns `permit`.\n *\n * Identifier formats (canonical, enforced upstream):\n * - `request_id` : `'req_' + uuid`\n * - `outcome_id` : `'outcome_' + uuid`\n * - `token` : `'tok_' + uuid`\n * - `granted_at` : ISO-8601 timestamp\n * - `granted_by` : user id, or the literal `'system'` for auto-approve\n *\n * Replay protection invariant (spec §6):\n * The `token` is **single-use**. Once consumed by the ledger, a second\n * submission MUST be rejected as `denied_by_user` (ephemeral — does not\n * poison subsequent fresh requests; §5.1 OpenQ-D1 resolution).\n */\nexport interface ApprovalContext {\n /** `req_<uuid>` — the approval-request id embedded in the initial\n * `auth_required` audit event. Used to reverse-link the outcome to the\n * triggering invocation. */\n request_id: string\n /** `outcome_<uuid>` — the approval_outcome event id (Step 6 surfaces this\n * as a first-class row, Step 3.5 only carries it through the ledger). */\n outcome_id: string\n /** `tok_<uuid>` — single-use token. Consumed atomically. */\n token: string\n /** True for 承認, false for 拒否. Step 3.5 only honors `true` (the `false`\n * path is handled by emitting `denied_by_user` directly in the UI). */\n granted: boolean\n /** ISO-8601 timestamp of the approval action. */\n granted_at: string\n /** user id or `'system'` for auto-approve. */\n granted_by: string\n}\n","/**\n * Receipt(証跡)関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\nimport { Grant } from './grant'\n\n/**\n * Receipt(証跡)の状態\n */\nexport enum ReceiptStatus {\n VALID = 'valid',\n EXPIRED = 'expired',\n REVOKED = 'revoked'\n}\n\n/**\n * 実行結果\n */\nexport type ReceiptOutcome = 'success' | 'failure' | 'denied'\n\n/**\n * Receipt(証跡)\n * 許可に基づく実行であることを示す検証可能な記録\n */\nexport interface Receipt {\n /** 一意識別子 */\n id: string\n /** 基となったGrantのID */\n grantId: string\n /** Grant名(参照用) */\n grantName?: string\n /** 対応するAuditEventのID */\n auditEventId: string\n /** Intent内容のハッシュ(SHA-256) */\n intentHash: string\n /** 実行結果 */\n outcome: ReceiptOutcome\n /** 発行者による署名(JWS形式) */\n signature: string\n /** 署名者DID */\n issuerDid: string\n /** 実行したAgent/User DID */\n executorDid: string\n /** 実行アクション */\n action: string\n /** 対象リソース */\n resource?: string\n /** 発行日時 */\n issuedAt: string\n /** 検証日時 */\n verifiedAt?: string\n /** ステータス */\n status: ReceiptStatus\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Receipt作成リクエスト\n */\nexport interface CreateReceiptRequest {\n /** GrantのID */\n grantId: string\n /** AuditEventのID */\n auditEventId: string\n /** Intent内容 */\n intent: {\n action: string\n resource?: string\n parameters?: Record<string, unknown>\n }\n /** 実行結果 */\n outcome: ReceiptOutcome\n /** 実行者DID */\n executorDid: string\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Receipt検証リクエスト\n */\nexport interface VerifyReceiptRequest {\n /** ReceiptのID(署名から検証する場合は省略可) */\n receiptId?: string\n /** 署名(IDから検証する場合は省略可) */\n signature?: string\n}\n\n/**\n * Receipt検証結果\n */\nexport interface VerifyReceiptResult {\n /** 検証結果 */\n valid: boolean\n /** Receipt情報 */\n receipt?: Receipt\n /** 関連Grant情報 */\n grant?: Grant\n /** エラーメッセージ */\n error?: string\n /** 検証日時 */\n verifiedAt?: string\n}\n\n/**\n * Receipt検索クエリ\n */\nexport interface ReceiptSearchQuery {\n /** GrantのIDでフィルタ */\n grantId?: string\n /** 実行者DIDでフィルタ */\n executorDid?: string\n /** アクションでフィルタ */\n action?: string\n /** 結果でフィルタ */\n outcome?: ReceiptOutcome\n /** 開始日時 */\n startDate?: string\n /** 終了日時 */\n endDate?: string\n /** 取得件数上限 */\n limit?: number\n /** オフセット */\n offset?: number\n}\n\n/**\n * Receipt一覧結果\n */\nexport interface ReceiptListResult {\n /** Receipt一覧 */\n receipts: Receipt[]\n /** 総件数 */\n total: number\n /** 取得件数上限 */\n limit: number\n /** オフセット */\n offset: number\n}\n","/**\n * Intent(操作意図)関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\n/**\n * リソース情報\n */\nexport interface IntentResource {\n /** リソースタイプ(SlackChannel, DriveFile等) */\n type: string\n /** リソース識別子 */\n id?: string\n /** ワークスペース/フォルダ等の範囲 */\n scope?: string\n /** 追加のリソース属性 */\n attributes?: Record<string, unknown>\n}\n\n/**\n * Intent(操作意図)\n * SaaS依存を最小化した「操作意図」の正規化表現\n */\nexport interface Intent {\n /** 権限主体のDID(誰の代わりに実行するか) */\n subject: string\n /** 実行者のDID(Agent/User) */\n actor: string\n /** 正規化アクション名(例: slack:channel.post_message) */\n action: string\n /** リソース情報 */\n resource: IntentResource\n /** パラメータ */\n parameters: Record<string, unknown>\n /** タイムスタンプ(ISO 8601) */\n timestamp: string\n /** 相関ID(トレース用) */\n traceId?: string\n}\n\n/**\n * 正規化されたIntent\n */\nexport interface NormalizedIntent extends Intent {\n /** 元のツール名 */\n originalToolName: string\n /** 元のアクション名 */\n originalAction: string\n /** 正規化後のアクション名 */\n normalizedAction: string\n /** コネクタ固有データ(SaaS固有情報を隔離) */\n connectorSpecificData?: Record<string, unknown>\n}\n\n/**\n * Intent正規化リクエスト\n */\nexport interface NormalizeIntentRequest {\n /** ツール名(slack, github, drive等) */\n toolName: string\n /** アクション名(postMessage, createIssue等) */\n action: string\n /** パラメータ */\n parameters: Record<string, unknown>\n /** 実行者DID */\n actorDid: string\n /** 権限主体DID(省略時はactorDid) */\n subjectDid?: string\n /** 相関ID */\n traceId?: string\n}\n\n/**\n * アクションマッピング\n * 各コネクタのアクションを正規化アクションにマッピング\n */\nexport interface ActionMapping {\n /** コネクタ名 */\n connector: string\n /** 元のアクション名 */\n originalAction: string\n /** 正規化アクション名 */\n normalizedAction: string\n /** リソースタイプ */\n resourceType: string\n /** 説明 */\n description?: string\n}\n\n/**\n * Intent評価結果\n */\nexport interface IntentEvaluationResult {\n /** 許可されているか */\n allowed: boolean\n /** マッチしたGrantのID */\n matchedGrantId?: string\n /** 拒否理由 */\n reason?: string\n /** Obligations(追加要件) */\n obligations?: IntentObligation[]\n /** 警告 */\n warnings?: string[]\n}\n\n/**\n * Obligation(追加要件)\n */\nexport interface IntentObligation {\n /** Obligationタイプ */\n type: 'audit_enhanced' | 'mask_data' | 'require_approval' | 'rate_limit' | 'notify'\n /** 詳細設定 */\n config?: Record<string, unknown>\n /** 説明 */\n description?: string\n}\n\n/**\n * 標準アクション定義\n * 各コネクタで共通して使用可能なアクションカテゴリ\n */\nexport enum StandardActionCategory {\n READ = 'read',\n WRITE = 'write',\n DELETE = 'delete',\n LIST = 'list',\n SEARCH = 'search',\n SHARE = 'share',\n ADMIN = 'admin'\n}\n\n/**\n * 標準アクションプレフィックス\n */\nexport const ACTION_PREFIXES = {\n SLACK: 'slack',\n GITHUB: 'github',\n GMAIL: 'gmail',\n CALENDAR: 'calendar',\n JIRA: 'jira',\n} as const\n","/**\n * OAuth関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\n/**\n * OAuthプロバイダー\n */\nexport enum OAuthProvider {\n SLACK = 'slack',\n GITHUB = 'github',\n GOOGLE = 'google',\n JIRA = 'jira'\n}\n\n/**\n * OAuthトークン情報\n */\nexport interface OAuthToken {\n /** アクセストークン */\n accessToken: string\n /** リフレッシュトークン */\n refreshToken?: string\n /** トークンタイプ(通常 'Bearer') */\n tokenType: string\n /** 有効期限(秒) */\n expiresIn?: number\n /** 有効期限(ISO 8601) */\n expiresAt?: string\n /** スコープ */\n scope?: string[]\n}\n\n/**\n * OAuth接続状態\n */\nexport interface OAuthConnection {\n /** プロバイダー */\n provider: OAuthProvider\n /** 接続済みか */\n connected: boolean\n /** 接続日時 */\n connectedAt?: string\n /** ユーザー情報(プロバイダー固有) */\n userInfo?: Record<string, unknown>\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * OAuth認可リクエスト\n */\nexport interface OAuthAuthorizeRequest {\n /** プロバイダー */\n provider: OAuthProvider\n /** リダイレクトURI */\n redirectUri: string\n /** スコープ */\n scope?: string[]\n /** 状態パラメータ */\n state?: string\n}\n\n/**\n * OAuthコールバックパラメータ\n */\nexport interface OAuthCallbackParams {\n /** 認可コード */\n code: string\n /** 状態パラメータ */\n state?: string\n /** エラー */\n error?: string\n /** エラー詳細 */\n errorDescription?: string\n}\n","/**\n * Invitation - User invitation to a project\n */\n\n/**\n * Status of an invitation\n */\nexport enum InvitationStatus {\n PENDING = 'pending',\n ACCEPTED = 'accepted',\n EXPIRED = 'expired',\n REVOKED = 'revoked'\n}\n\n/**\n * Role assigned to an invited user\n */\nexport type InvitationRole = 'admin' | 'member' | 'viewer'\n\n/**\n * Represents a user invitation to a project\n */\nexport interface Invitation {\n /** Unique identifier for the invitation */\n id: string\n /** Unique token used for accepting the invitation */\n token: string\n /** ID of the project the user is invited to */\n projectId: string\n /** Name of the project (optional) */\n projectName?: string\n /** Email address of the invited user */\n email: string\n /** Role assigned to the user upon accepting */\n role: InvitationRole\n /** User ID of the person who sent the invitation */\n invitedBy: string\n /** Name of the person who sent the invitation (optional) */\n invitedByName?: string\n /** Current status of the invitation */\n status: InvitationStatus\n /** Date when the invitation expires */\n expiresAt: Date\n /** Date when the invitation was accepted (if accepted) */\n acceptedAt?: Date\n /** Date when the invitation was created */\n createdAt: Date\n /** Date when the invitation was last updated */\n updatedAt: Date\n /** Additional metadata associated with the invitation */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Request payload for creating a new invitation\n */\nexport interface CreateInvitationRequest {\n /** ID of the project to invite the user to */\n projectId: string\n /** Email address of the user to invite */\n email: string\n /** Role to assign to the user (defaults to 'member') */\n role?: InvitationRole\n /** Number of hours until the invitation expires */\n expiresInHours?: number\n /** Additional metadata to attach to the invitation */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Request payload for accepting an invitation\n */\nexport interface AcceptInvitationRequest {\n /** Invitation token from the invitation link */\n token: string\n /** Email address of the user accepting the invitation */\n email: string\n /** Password for the new user account */\n password: string\n /** First name of the user (optional) */\n firstName?: string\n /** Last name of the user (optional) */\n lastName?: string\n}\n\n/**\n * Response returned when verifying an invitation token\n */\nexport interface VerifyInvitationResponse {\n /** Email address the invitation was sent to */\n email: string\n /** ID of the project the user is invited to */\n projectId: string\n /** Name of the project (optional) */\n projectName?: string\n /** Role that will be assigned upon accepting */\n role: InvitationRole\n /** Name of the person who sent the invitation (optional) */\n invitedBy?: string\n /** Date when the invitation expires */\n expiresAt: Date\n}\n","/**\n * Permission Mode Types\n * プロジェクトのGrant管理モード定義\n */\n\n/**\n * パーミッションモード\n * - strict: 全て明示的Grant必要(デフォルト・現在の動作)\n * - assisted: OAuth認証後に推奨Grantを提案、ユーザーが承認\n * - permissive: デフォルト権限有効(警告付き)\n */\nexport type PermissionMode = 'strict' | 'assisted' | 'permissive'\n\n/**\n * Grant提案用のリスクレベル(action-registryと整合)\n */\nexport type SuggestionRiskLevel = 'low' | 'medium' | 'high' | 'critical'\n\n/**\n * 推奨アクション(リスクレベル付き)\n */\nexport interface SuggestedAction {\n /** アクション名 (例: slack:channel.post_message) */\n action: string\n /** リスクレベル */\n riskLevel: SuggestionRiskLevel\n /** 表示用説明 */\n description?: string\n /** 必要なOAuthスコープ */\n requiredScopes: string[]\n /** 含まれるcapability */\n capability?: string\n /** 推奨されたかどうか(ユーザーが調整可能) */\n selected: boolean\n}\n\n/**\n * 推奨リソース\n */\nexport interface SuggestedResource {\n /** リソースタイプ */\n type: string\n /** 特定リソースID */\n id?: string\n /** パターンマッチ */\n pattern?: string\n /** 表示用名称 */\n name?: string\n /** 選択されているか */\n selected: boolean\n}\n\n/**\n * 推奨制約\n */\nexport interface SuggestedConstraints {\n /** 最大実行回数 */\n maxInvocations?: number\n /** 有効期限(日数) */\n expiresInDays?: number\n /** 時間帯制約 */\n timeWindow?: {\n start: string\n end: string\n timezone: string\n daysOfWeek: number[]\n }\n}\n\n/**\n * 推奨Grant\n */\nexport interface SuggestedGrant {\n /** 一時ID(セッション内で識別) */\n suggestionId: string\n /** 推奨Grant名 */\n name: string\n /** 説明 */\n description?: string\n /** 対象ユーザーID */\n userId?: string\n /** プロジェクトID */\n projectId: string\n /** OAuthプロバイダー */\n provider: string\n /** 推奨アクション一覧 */\n suggestedActions: SuggestedAction[]\n /** 推奨リソース */\n suggestedResources: SuggestedResource[]\n /** 推奨制約 */\n suggestedConstraints: SuggestedConstraints\n /** OAuthトークンID参照 */\n oauthTokenId: string\n /** 元のOAuthスコープ */\n originalScopes: string[]\n /** 有効期限(この提案自体の) */\n expiresAt: string\n /** 作成日時 */\n createdAt: string\n /** 作成されたGrant ID(createPending時) */\n grantId?: string\n}\n\n/**\n * Grant提案リクエスト\n */\nexport interface SuggestGrantRequest {\n /** OAuthトークンID */\n oauthTokenId: string\n /** 対象ユーザーID(必須) */\n userId: string\n /** プロジェクトID */\n projectId: string\n}\n\n/**\n * Grant提案確認リクエスト\n */\nexport interface ConfirmGrantSuggestionRequest {\n /** 推奨Grant ID */\n suggestionId: string\n /** 選択したアクション */\n selectedActions: string[]\n /** 選択したリソース */\n selectedResources: SuggestedResource[]\n /** 調整した制約 */\n constraints: {\n maxInvocations?: number\n expiresAt?: string\n timeWindow?: {\n start: string\n end: string\n timezone: string\n daysOfWeek: number[]\n }\n }\n /** カスタムGrant名 */\n name?: string\n /** カスタム説明 */\n description?: string\n}\n\n/**\n * リスクレベルに基づくデフォルト制約マッピング\n */\nexport const DEFAULT_CONSTRAINTS_BY_RISK: Record<SuggestionRiskLevel, SuggestedConstraints> = {\n low: {\n maxInvocations: 1000,\n expiresInDays: 90,\n },\n medium: {\n maxInvocations: 200,\n expiresInDays: 30,\n },\n high: {\n maxInvocations: 50,\n expiresInDays: 7,\n timeWindow: {\n start: '09:00',\n end: '18:00',\n timezone: 'UTC',\n daysOfWeek: [1, 2, 3, 4, 5], // 平日のみ\n },\n },\n critical: {\n maxInvocations: 10,\n expiresInDays: 1,\n timeWindow: {\n start: '09:00',\n end: '17:00',\n timezone: 'UTC',\n daysOfWeek: [1, 2, 3, 4, 5], // 平日のみ\n },\n },\n}\n","export type UserTier = 'free' | 'pro' | 'team'\n\nexport interface TierLimits {\n maxProjects: number\n maxWritesPerMonth: number\n maxWriteVcTtlMinutes: number\n readAutoApproveMaxRiskLevel: 'low' | 'medium' | 'none'\n readAutoApproveTtlMinutes: number\n writeAutoApproveEnabled: boolean\n auditRetentionDays: number\n auditExportEnabled: boolean\n}\n\nexport const TIER_LIMITS: Record<UserTier, TierLimits> = {\n free: {\n maxProjects: 1,\n // GTM doc §3 Tier 構成: Free = 100 writes/月. Raised from 50 to 100\n // (2026-05-14 tier drift fix) so Aha 到達前にユーザーを枯渇させない。\n maxWritesPerMonth: 100,\n maxWriteVcTtlMinutes: 5,\n readAutoApproveMaxRiskLevel: 'low',\n readAutoApproveTtlMinutes: 30,\n writeAutoApproveEnabled: false,\n auditRetentionDays: 7,\n auditExportEnabled: false,\n },\n pro: {\n maxProjects: 3,\n // GTM doc §3 Tier 構成: Pro = 2,000 writes/月. Raised from 300 to 2,000\n // (2026-05-14 tier drift fix) — backend was 6.7x below the published GTM\n // commitment. Overage billing ($0.07 / action) kicks in beyond 2,000.\n maxWritesPerMonth: 2000,\n maxWriteVcTtlMinutes: 1440, // 24h\n readAutoApproveMaxRiskLevel: 'medium',\n readAutoApproveTtlMinutes: 1440, // 24h\n writeAutoApproveEnabled: true, // SESSION_GRANT for low-risk\n auditRetentionDays: 30,\n auditExportEnabled: true,\n },\n team: {\n maxProjects: -1, // unlimited\n // GTM doc §3 Tier 構成: Team = 10,000 writes/月 (team 合計). Per-user\n // enforcement is intentionally unlimited (-1) in M1 Closed Beta; the\n // team-aggregate 10K cap is deferred to M2 (requires team-scoped quota\n // ledger). Documented in GTM doc §3 annotation.\n maxWritesPerMonth: -1, // unlimited (M1 fair use; M2 enforces 10K team total)\n maxWriteVcTtlMinutes: 10080, // 168h\n readAutoApproveMaxRiskLevel: 'medium',\n readAutoApproveTtlMinutes: 10080, // 168h\n writeAutoApproveEnabled: true,\n // GTM doc §3 commits to 90-day audit retention for Team; implementation\n // exceeds this with 365 days as a customer-favorable bonus (documented\n // in GTM doc §3 annotation).\n auditRetentionDays: 365,\n auditExportEnabled: true,\n },\n}\n","import { CredentialType } from '../types'\n\nexport interface DisclosureFields {\n selectiveFields: string[]\n mandatoryFields: string[]\n neverDisclose: string[]\n decoyCount: number\n}\n\nconst DEFAULT_NEVER_DISCLOSE = ['privateKey', 'secret']\n\nconst DEFAULT_DISCLOSURE_CONFIGS: Record<CredentialType, Omit<DisclosureFields, 'decoyCount'>> = {\n [CredentialType.PROJECT_ACCESS]: {\n selectiveFields: ['permissions', 'projectId'],\n mandatoryFields: ['role'],\n neverDisclose: DEFAULT_NEVER_DISCLOSE,\n },\n [CredentialType.TOOL_ACCESS]: {\n selectiveFields: ['actions', 'tool', 'resourceScope'],\n mandatoryFields: [],\n neverDisclose: DEFAULT_NEVER_DISCLOSE,\n },\n [CredentialType.ADMIN]: {\n selectiveFields: ['adminLevel', 'scope'],\n mandatoryFields: ['authorizedBy'],\n neverDisclose: [...DEFAULT_NEVER_DISCLOSE, 'internalId'],\n },\n [CredentialType.DEVELOPER]: {\n selectiveFields: ['skills', 'experience', 'projects'],\n mandatoryFields: ['name'],\n neverDisclose: ['salary', 'privateInfo'],\n },\n [CredentialType.TEMPORARY]: {\n selectiveFields: [],\n mandatoryFields: [],\n neverDisclose: DEFAULT_NEVER_DISCLOSE,\n },\n [CredentialType.RECEIPT]: {\n selectiveFields: ['action', 'resource', 'outcome', 'amount', 'description', 'date', 'transactionId'],\n mandatoryFields: ['grantId', 'auditEventId', 'receiptType'],\n neverDisclose: [...DEFAULT_NEVER_DISCLOSE, 'signature', 'internalReference'],\n },\n}\n\n/**\n * Get selective disclosure fields for a given credential type.\n * If requestedFields is provided, they are filtered against the neverDisclose list.\n */\nexport function getDefaultDisclosureFields(\n credentialType: CredentialType,\n requestedFields?: string[]\n): DisclosureFields {\n const config = DEFAULT_DISCLOSURE_CONFIGS[credentialType] || DEFAULT_DISCLOSURE_CONFIGS[CredentialType.TEMPORARY]\n\n let selectiveFields = requestedFields || config.selectiveFields\n selectiveFields = selectiveFields.filter(field => !config.neverDisclose.includes(field))\n\n return {\n selectiveFields,\n mandatoryFields: config.mandatoryFields,\n neverDisclose: config.neverDisclose,\n decoyCount: 0,\n }\n}\n","import {\n IssueSDJWTVCRequest,\n IssueSDJWTVCResult,\n VerifySDJWTVCResult,\n CredentialType\n} from '../types'\nimport { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { getDefaultDisclosureFields } from '../utils/sdjwt-disclosure'\n\n/**\n * API-focused VC Manager for server-side operations\n * Provides stateless SD-JWT operations without local persistence\n */\nexport class APIVCManager {\n private keyManager: KeyManager\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n // Set the KeyManager for SDJwtClient static methods\n SDJwtClient.setKeyManager(this.keyManager)\n }\n\n /**\n * Issue an SD-JWT VC with selective disclosure\n */\n async issueSDJWTVC(request: IssueSDJWTVCRequest): Promise<IssueSDJWTVCResult> {\n // Validate request\n if (!request.issuer || !request.subject) {\n throw new Error('Issuer and subject DIDs are required')\n }\n\n // Get issuer's private key\n const privateKey = await this.keyManager.getKey(request.issuer)\n if (!privateKey) {\n throw new Error(`Private key not found for issuer: ${request.issuer}`)\n }\n\n // Prepare credential payload\n const now = new Date()\n const iat = Math.floor(now.getTime() / 1000)\n\n // Set expiration: use provided date, or default to 24 hours from now\n const expirationDate = request.expirationDate || new Date(now.getTime() + 24 * 60 * 60 * 1000)\n const exp = Math.floor(expirationDate.getTime() / 1000)\n\n // Build IETF SD-JWT VC payload (no W3C VC wrapper)\n const vcPayload = {\n iss: request.issuer,\n sub: request.subject,\n iat,\n exp,\n vct: request.type || CredentialType.TEMPORARY, // IETF SD-JWT VC credential type\n // Direct claims (can be selectively disclosed)\n ...request.claims\n }\n\n // Get selective disclosure configuration based on credential type\n const disclosureConfig = getDefaultDisclosureFields(\n request.type || CredentialType.TEMPORARY,\n request.selectiveDisclosureFields\n )\n\n // Issue SD-JWT VC with selective disclosure\n const credential = await SDJwtClient.issueSDJWT(\n vcPayload,\n privateKey,\n disclosureConfig.selectiveFields\n )\n\n return {\n credential,\n issuer: request.issuer,\n subject: request.subject,\n type: request.type || CredentialType.TEMPORARY,\n expiresAt: expirationDate\n }\n }\n\n /**\n * Verify an SD-JWT VC\n */\n async verifySDJWTVC(credential: string): Promise<VerifySDJWTVCResult> {\n try {\n // Basic format validation\n if (!credential || typeof credential !== 'string') {\n return {\n valid: false,\n error: 'Invalid credential format'\n }\n }\n\n // Verify the SD-JWT VC\n const result = await SDJwtClient.verifySDJWT(credential)\n\n if (!result.valid || !result.payload) {\n return {\n valid: false,\n error: result.error || 'Verification failed'\n }\n }\n\n return {\n valid: true,\n payload: {\n iss: result.payload.iss,\n sub: result.payload.sub,\n vct: result.payload.vct,\n exp: result.payload.exp,\n iat: result.payload.iat,\n // Include any other claims from the payload\n ...Object.fromEntries(\n Object.entries(result.payload).filter(([key]) =>\n !['iss', 'sub', 'vct', 'exp', 'iat'].includes(key)\n )\n )\n }\n }\n } catch (error) {\n return {\n valid: false,\n error: `Verification error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n }\n }\n\n /**\n * Issue a project access credential\n */\n async issueProjectAccessCredential(\n agentDid: string,\n projectId: string,\n permissions: string[],\n issuerDid: string,\n expirationHours = 24\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.PROJECT_ACCESS,\n claims: {\n projectId,\n permissions,\n role: 'developer'\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['permissions']\n })\n }\n\n /**\n * Issue a tool access credential\n */\n async issueToolAccessCredential(\n agentDid: string,\n toolName: string,\n actions: string[],\n projectId: string,\n issuerDid: string,\n expirationHours = 24\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.TOOL_ACCESS,\n claims: {\n tool: toolName,\n actions,\n projectId\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['actions', 'tool']\n })\n }\n\n /**\n * Issue a multi-tool access credential\n */\n async issueMultiToolCredential(\n agentDid: string,\n toolPermissions: Array<{ tool: string; actions: string[] }>,\n projectId: string,\n issuerDid: string,\n expirationHours = 24\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.TOOL_ACCESS,\n claims: {\n toolPermissions,\n projectId\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['toolPermissions']\n })\n }\n\n /**\n * Issue an admin credential\n */\n async issueAdminCredential(\n agentDid: string,\n scope: 'project' | 'global',\n projectId: string | undefined,\n issuerDid: string,\n expirationHours = 8\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.ADMIN,\n claims: {\n scope,\n projectId,\n adminLevel: scope === 'global' ? 'super' : 'project'\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['adminLevel', 'scope']\n })\n }\n}","/**\n * ConstraintEvaluator\n * Grant制約の評価ロジック\n */\n\nimport {\n GrantConstraints,\n TimeWindowConstraint,\n EvaluationContext,\n ConstraintEvaluationResult,\n ConstraintViolation,\n ConstraintWarning,\n PermissionConstraints,\n PermissionTimeConstraint,\n} from '../types'\n\nexport interface ConstraintEvaluatorOptions {\n /** 警告を発する残り実行回数の閾値 */\n invocationWarningThreshold?: number\n /** 警告を発するリスクスコアの閾値(riskThresholdに対する割合) */\n riskWarningRatio?: number\n /** デフォルトタイムゾーン */\n defaultTimezone?: string\n}\n\nconst DEFAULT_OPTIONS: ConstraintEvaluatorOptions = {\n invocationWarningThreshold: 5,\n riskWarningRatio: 0.8,\n defaultTimezone: 'UTC'\n}\n\n/**\n * 制約評価クラス\n */\nexport class ConstraintEvaluator {\n private options: ConstraintEvaluatorOptions\n\n constructor(options?: Partial<ConstraintEvaluatorOptions>) {\n this.options = { ...DEFAULT_OPTIONS, ...options }\n }\n\n /**\n * 制約を総合評価\n */\n evaluate(\n constraints: GrantConstraints,\n context: EvaluationContext,\n currentInvocations: number,\n expiresAt?: Date\n ): ConstraintEvaluationResult {\n const violations: ConstraintViolation[] = []\n const warnings: ConstraintWarning[] = []\n\n // 1. 期限チェック\n const expirationResult = this.checkExpiration(expiresAt, constraints.expiresAt)\n if (expirationResult.violation) {\n violations.push(expirationResult.violation)\n }\n\n // 2. 回数上限チェック\n const invocationResult = this.checkInvocationLimit(\n constraints.maxInvocations,\n currentInvocations\n )\n if (invocationResult.violation) {\n violations.push(invocationResult.violation)\n }\n if (invocationResult.warning) {\n warnings.push(invocationResult.warning)\n }\n\n // 3. 時間帯チェック\n if (constraints.timeWindow) {\n const timeResult = this.checkTimeWindow(\n constraints.timeWindow,\n new Date(context.timestamp)\n )\n if (timeResult.violation) {\n violations.push(timeResult.violation)\n }\n if (timeResult.warning) {\n warnings.push(timeResult.warning)\n }\n }\n\n // 4. IPアドレスチェック\n if (constraints.ipAllowlist && constraints.ipAllowlist.length > 0 && context.ipAddress) {\n const ipResult = this.checkIpAllowlist(constraints.ipAllowlist, context.ipAddress)\n if (ipResult.violation) {\n violations.push(ipResult.violation)\n }\n }\n\n // 5. リスクスコアチェック\n if (constraints.riskThreshold !== undefined && context.riskScore !== undefined) {\n const riskResult = this.checkRiskThreshold(constraints.riskThreshold, context.riskScore)\n if (riskResult.violation) {\n violations.push(riskResult.violation)\n }\n if (riskResult.warning) {\n warnings.push(riskResult.warning)\n }\n }\n\n return {\n allowed: violations.length === 0,\n violations,\n warnings,\n evaluatedAt: new Date().toISOString(),\n context\n }\n }\n\n /**\n * 期限チェック\n */\n checkExpiration(\n grantExpiresAt?: Date,\n constraintExpiresAt?: string\n ): { violation?: ConstraintViolation } {\n const now = new Date()\n\n // Grantレベルの有効期限\n if (grantExpiresAt && new Date(grantExpiresAt) < now) {\n return {\n violation: {\n type: 'expired',\n message: `Grant expired at ${grantExpiresAt.toISOString()}`,\n details: { expiresAt: grantExpiresAt.toISOString(), now: now.toISOString() }\n }\n }\n }\n\n // Constraintレベルの有効期限\n if (constraintExpiresAt && new Date(constraintExpiresAt) < now) {\n return {\n violation: {\n type: 'expired',\n message: `Constraint expired at ${constraintExpiresAt}`,\n details: { expiresAt: constraintExpiresAt, now: now.toISOString() }\n }\n }\n }\n\n return {}\n }\n\n /**\n * 実行回数チェック\n */\n checkInvocationLimit(\n maxInvocations?: number,\n currentInvocations?: number\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n if (maxInvocations === undefined || currentInvocations === undefined) {\n return {}\n }\n\n const remaining = maxInvocations - currentInvocations\n\n if (remaining <= 0) {\n return {\n violation: {\n type: 'max_invocations',\n message: `Invocation limit reached (${maxInvocations} max, ${currentInvocations} used)`,\n details: { maxInvocations, currentInvocations, remaining: 0 }\n }\n }\n }\n\n if (remaining <= this.options.invocationWarningThreshold!) {\n return {\n warning: {\n type: 'approaching_limit',\n message: `Only ${remaining} invocations remaining out of ${maxInvocations}`,\n details: { maxInvocations, currentInvocations, remaining }\n }\n }\n }\n\n return {}\n }\n\n /**\n * 時間帯チェック\n */\n checkTimeWindow(\n timeWindow: TimeWindowConstraint,\n currentTime: Date\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n const timezone = timeWindow.timezone || this.options.defaultTimezone!\n\n // 曜日チェック\n if (timeWindow.daysOfWeek && timeWindow.daysOfWeek.length > 0) {\n const currentDay = this.getDayOfWeekInTimezone(currentTime, timezone)\n if (!timeWindow.daysOfWeek.includes(currentDay)) {\n return {\n violation: {\n type: 'time_window',\n message: `Current day (${this.getDayName(currentDay)}) is not in allowed days`,\n details: {\n currentDay,\n allowedDays: timeWindow.daysOfWeek,\n allowedDayNames: timeWindow.daysOfWeek.map((d: number) => this.getDayName(d))\n }\n }\n }\n }\n }\n\n // 時間帯チェック\n if (timeWindow.start && timeWindow.end) {\n const currentTimeStr = this.getTimeInTimezone(currentTime, timezone)\n\n // 通常の時間帯(例: 09:00-17:00)\n if (timeWindow.start <= timeWindow.end) {\n if (currentTimeStr < timeWindow.start || currentTimeStr > timeWindow.end) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time (${currentTimeStr}) is outside allowed window (${timeWindow.start}-${timeWindow.end})`,\n details: { currentTime: currentTimeStr, start: timeWindow.start, end: timeWindow.end, timezone }\n }\n }\n }\n } else {\n // 日をまたぐ時間帯(例: 22:00-06:00)\n if (currentTimeStr < timeWindow.start && currentTimeStr > timeWindow.end) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time (${currentTimeStr}) is outside allowed window (${timeWindow.start}-${timeWindow.end})`,\n details: { currentTime: currentTimeStr, start: timeWindow.start, end: timeWindow.end, timezone }\n }\n }\n }\n }\n\n // 営業時間外間近の警告(終了1時間前)\n const endMinutes = this.timeToMinutes(timeWindow.end)\n const currentMinutes = this.timeToMinutes(currentTimeStr)\n const minutesUntilEnd = endMinutes - currentMinutes\n\n if (minutesUntilEnd > 0 && minutesUntilEnd <= 60) {\n return {\n warning: {\n type: 'unusual_time',\n message: `Only ${minutesUntilEnd} minutes remaining in allowed time window`,\n details: { minutesUntilEnd, windowEnd: timeWindow.end }\n }\n }\n }\n }\n\n return {}\n }\n\n /**\n * IPアドレスチェック\n */\n checkIpAllowlist(\n allowlist: string[],\n ipAddress: string\n ): { violation?: ConstraintViolation } {\n // ワイルドカードチェック\n if (allowlist.includes('*')) {\n return {}\n }\n\n // 完全一致チェック\n if (allowlist.includes(ipAddress)) {\n return {}\n }\n\n // CIDRマッチングチェック\n for (const entry of allowlist) {\n if (entry.includes('/')) {\n if (this.isIpInCidr(ipAddress, entry)) {\n return {}\n }\n }\n }\n\n return {\n violation: {\n type: 'ip_allowlist',\n message: `IP address ${ipAddress} is not in the allowlist`,\n details: { ipAddress, allowlist }\n }\n }\n }\n\n /**\n * リスクスコアチェック\n */\n checkRiskThreshold(\n threshold: number,\n currentScore: number\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n if (currentScore > threshold) {\n return {\n violation: {\n type: 'risk_threshold',\n message: `Risk score ${currentScore} exceeds threshold ${threshold}`,\n details: { currentScore, threshold }\n }\n }\n }\n\n const warningThreshold = threshold * this.options.riskWarningRatio!\n if (currentScore > warningThreshold) {\n return {\n warning: {\n type: 'high_risk',\n message: `Risk score ${currentScore} is approaching threshold ${threshold}`,\n details: { currentScore, threshold, warningThreshold }\n }\n }\n }\n\n return {}\n }\n\n // ============================================================================\n // PermissionConstraints evaluation (VC-level constraints from PermissionRule)\n // ============================================================================\n\n /**\n * Evaluate PermissionConstraints from a PermissionRule.\n *\n * This is the VC-level constraint evaluator that works with the\n * normalized PermissionConstraints format (as opposed to GrantConstraints).\n *\n * Used by the PolicyEvaluator after rule matching to verify\n * rule-level constraints are satisfied.\n */\n evaluatePermissionConstraints(\n constraints: PermissionConstraints,\n context: {\n now: number\n ipAddress?: string\n riskScore?: number\n invocationCount?: number\n }\n ): { allowed: boolean; violations: ConstraintViolation[]; warnings: ConstraintWarning[] } {\n const violations: ConstraintViolation[] = []\n const warnings: ConstraintWarning[] = []\n\n // 1. Time constraints\n if (constraints.time) {\n const timeResult = this.checkPermissionTimeConstraint(\n constraints.time,\n new Date(context.now * 1000)\n )\n if (timeResult.violation) violations.push(timeResult.violation)\n if (timeResult.warning) warnings.push(timeResult.warning)\n }\n\n // 2. Invocation limit\n if (constraints.max_invocations !== undefined && context.invocationCount !== undefined) {\n const invResult = this.checkInvocationLimit(\n constraints.max_invocations,\n context.invocationCount\n )\n if (invResult.violation) violations.push(invResult.violation)\n if (invResult.warning) warnings.push(invResult.warning)\n }\n\n // 3. IP allowlist\n if (constraints.ip_allowlist && constraints.ip_allowlist.length > 0 && context.ipAddress) {\n const ipResult = this.checkIpAllowlist(constraints.ip_allowlist, context.ipAddress)\n if (ipResult.violation) violations.push(ipResult.violation)\n }\n\n // 4. Risk threshold\n if (constraints.risk_threshold !== undefined && context.riskScore !== undefined) {\n const riskResult = this.checkRiskThreshold(constraints.risk_threshold, context.riskScore)\n if (riskResult.violation) violations.push(riskResult.violation)\n if (riskResult.warning) warnings.push(riskResult.warning)\n }\n\n return {\n allowed: violations.length === 0,\n violations,\n warnings,\n }\n }\n\n /**\n * Check PermissionTimeConstraint (supports both absolute and recurring)\n */\n checkPermissionTimeConstraint(\n time: PermissionTimeConstraint,\n currentTime: Date\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n const nowUnix = Math.floor(currentTime.getTime() / 1000)\n\n // Absolute constraints\n if (time.not_before !== undefined && nowUnix < time.not_before) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time is before not_before (${new Date(time.not_before * 1000).toISOString()})`,\n details: { now: nowUnix, not_before: time.not_before }\n }\n }\n }\n if (time.not_after !== undefined && nowUnix > time.not_after) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time is after not_after (${new Date(time.not_after * 1000).toISOString()})`,\n details: { now: nowUnix, not_after: time.not_after }\n }\n }\n }\n\n // Recurring constraints\n const timezone = time.timezone || this.options.defaultTimezone!\n if (time.days_of_week && time.days_of_week.length > 0) {\n const currentDay = this.getDayOfWeekInTimezone(currentTime, timezone)\n if (!time.days_of_week.includes(currentDay)) {\n return {\n violation: {\n type: 'time_window',\n message: `Current day (${this.getDayName(currentDay)}) is not in allowed days`,\n details: { currentDay, allowedDays: time.days_of_week }\n }\n }\n }\n }\n\n if (time.recurring_start && time.recurring_end) {\n const tw: TimeWindowConstraint = {\n start: time.recurring_start,\n end: time.recurring_end,\n timezone,\n }\n return this.checkTimeWindow(tw, currentTime)\n }\n\n return {}\n }\n\n // ============================================================================\n // Helper Methods\n // ============================================================================\n\n private getDayOfWeekInTimezone(date: Date, timezone: string): number {\n try {\n const options: Intl.DateTimeFormatOptions = { weekday: 'short', timeZone: timezone }\n const dayStr = date.toLocaleDateString('en-US', options)\n const dayMap: Record<string, number> = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }\n return dayMap[dayStr] ?? date.getDay()\n } catch {\n return date.getDay()\n }\n }\n\n private getTimeInTimezone(date: Date, timezone: string): string {\n try {\n const options: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n timeZone: timezone\n }\n return date.toLocaleTimeString('en-US', options)\n } catch {\n return date.toISOString().slice(11, 16)\n }\n }\n\n private getDayName(day: number): string {\n const names = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n return names[day] || 'Unknown'\n }\n\n private timeToMinutes(time: string): number {\n const [hours, minutes] = time.split(':').map(Number)\n return hours * 60 + minutes\n }\n\n /**\n * Check if an IP address is within a CIDR range or matches exactly.\n * Uses unsigned 32-bit arithmetic to avoid sign-bit issues.\n * Public for reuse by other services (e.g., LocalPolicyEvaluatorService).\n */\n isIpInCidr(ip: string, cidr: string): boolean {\n try {\n if (!cidr.includes('/')) {\n return ip === cidr\n }\n const [range, bits] = cidr.split('/')\n const prefix = parseInt(bits, 10)\n if (isNaN(prefix)) return false\n\n const ipNum = this.ipToNumber(ip)\n const rangeNum = this.ipToNumber(range)\n if (ipNum === null || rangeNum === null) return false\n\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0\n return (ipNum & mask) === (rangeNum & mask)\n } catch {\n return false\n }\n }\n\n private ipToNumber(ip: string): number | null {\n const parts = ip.split('.')\n if (parts.length !== 4) return null\n let result = 0\n for (const part of parts) {\n const n = parseInt(part, 10)\n if (isNaN(n) || n < 0 || n > 255) return null\n result = (result << 8) | n\n }\n return result >>> 0\n }\n}\n\n/**\n * デフォルトのConstraintEvaluatorインスタンス\n */\nexport const defaultConstraintEvaluator = new ConstraintEvaluator()\n\n/**\n * 簡易評価関数\n */\nexport function evaluateConstraints(\n constraints: GrantConstraints,\n context: EvaluationContext,\n currentInvocations: number,\n expiresAt?: Date\n): ConstraintEvaluationResult {\n return defaultConstraintEvaluator.evaluate(constraints, context, currentInvocations, expiresAt)\n}\n","import * as fs from 'fs/promises'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { IStateStore } from './state-store.interface'\n\n/**\n * JSON file-based state store.\n * Stores state in ~/.vess/state.json by default.\n * Uses atomic write (temp file → rename) for safety.\n */\nexport class JsonStateStore implements IStateStore {\n private filePath: string\n private data: Record<string, unknown> | null = null\n\n constructor(filePath?: string) {\n this.filePath = filePath || path.join(os.homedir(), '.vess', 'state.json')\n }\n\n async get<T = unknown>(key: string): Promise<T | undefined> {\n const data = await this.load()\n return getNestedValue(data, key) as T | undefined\n }\n\n async set<T = unknown>(key: string, value: T): Promise<void> {\n const data = await this.load()\n setNestedValue(data, key, value)\n await this.save(data)\n }\n\n async delete(key: string): Promise<boolean> {\n const data = await this.load()\n const existed = getNestedValue(data, key) !== undefined\n if (existed) {\n deleteNestedValue(data, key)\n await this.save(data)\n }\n return existed\n }\n\n async has(key: string): Promise<boolean> {\n const data = await this.load()\n return getNestedValue(data, key) !== undefined\n }\n\n async getAll(): Promise<Record<string, unknown>> {\n return { ...(await this.load()) }\n }\n\n async clear(): Promise<void> {\n this.data = {}\n await this.save(this.data)\n }\n\n /**\n * Get the file path used by this store (useful for diagnostics)\n */\n getFilePath(): string {\n return this.filePath\n }\n\n private async load(): Promise<Record<string, unknown>> {\n if (this.data !== null) {\n return this.data\n }\n try {\n const raw = await fs.readFile(this.filePath, 'utf-8')\n this.data = JSON.parse(raw) as Record<string, unknown>\n } catch (err: any) {\n if (err.code === 'ENOENT') {\n this.data = {}\n } else if (err instanceof SyntaxError) {\n // Corrupted JSON — start fresh rather than crashing\n this.data = {}\n } else {\n throw err\n }\n }\n return this.data!\n }\n\n private async save(data: Record<string, unknown>): Promise<void> {\n this.data = data\n const dir = path.dirname(this.filePath)\n await fs.mkdir(dir, { recursive: true, mode: 0o700 })\n\n // Atomic write: write to temp file, then rename\n const tmpPath = this.filePath + '.tmp'\n await fs.writeFile(tmpPath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 })\n await fs.rename(tmpPath, this.filePath)\n }\n}\n\n// --- Nested key helpers ---\n\nfunction getNestedValue(obj: Record<string, unknown>, key: string): unknown {\n const parts = key.split('.')\n let current: unknown = obj\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined\n }\n current = (current as Record<string, unknown>)[part]\n }\n return current\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, key: string, value: unknown): void {\n const parts = key.split('.')\n let current: Record<string, unknown> = obj\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (current[part] === undefined || current[part] === null || typeof current[part] !== 'object') {\n current[part] = {}\n }\n current = current[part] as Record<string, unknown>\n }\n current[parts[parts.length - 1]] = value\n}\n\nfunction deleteNestedValue(obj: Record<string, unknown>, key: string): void {\n const parts = key.split('.')\n let current: Record<string, unknown> = obj\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (current[part] === undefined || typeof current[part] !== 'object') {\n return\n }\n current = current[part] as Record<string, unknown>\n }\n delete current[parts[parts.length - 1]]\n}\n","import { IStateStore } from '../state/state-store.interface'\n\n/**\n * Event returned from the Gateway /events endpoint\n */\nexport interface GatewayEvent {\n id: string\n type: string\n source: string\n timestamp: string\n data: Record<string, unknown>\n metadata?: Record<string, unknown>\n}\n\n/**\n * Response from getEvents\n */\nexport interface GetEventsResponse {\n events: GatewayEvent[]\n cursor?: string\n hasMore: boolean\n}\n\n/**\n * Response from ackEvent\n */\nexport interface AckEventResponse {\n success: boolean\n eventId: string\n}\n\n/**\n * Options for getEvents\n */\nexport interface GetEventsOptions {\n cursor?: string\n limit?: number\n /** Long-poll wait time in seconds (0 = no wait) */\n waitSeconds?: number\n}\n\n/**\n * Gateway API client for event-based communication.\n * Used by CLI (runner/daemon) and any other consumer that needs\n * to long-poll for events and acknowledge them.\n *\n * baseUrl should be the API root without trailing path segments\n * (e.g. \"https://api.aidentity.io\" or \"http://localhost:3000\").\n */\nexport class GatewayClient {\n private baseUrl: string\n private stateStore?: IStateStore\n private apiKey?: string\n private sessionToken?: string\n\n constructor(options: {\n baseUrl: string\n stateStore?: IStateStore\n apiKey?: string\n sessionToken?: string\n }) {\n // Strip trailing slashes and any trailing /v1 path so callers can pass\n // either \"https://api.aidentity.io\" or \"https://api.aidentity.io/v1\".\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '').replace(/\\/v1$/, '')\n this.stateStore = options.stateStore\n this.apiKey = options.apiKey\n this.sessionToken = options.sessionToken\n }\n\n /**\n * Set session token for authenticated requests\n */\n setSessionToken(token: string): void {\n this.sessionToken = token\n }\n\n /**\n * Fetch events from the Gateway.\n * If cursor is not provided, attempts to load it from StateStore.\n *\n * NOTE: The /events long-poll endpoint may not be implemented on the API server yet.\n * This client is designed to work once the endpoint is available.\n */\n async getEvents(options: GetEventsOptions = {}): Promise<GetEventsResponse> {\n // Load cursor from state if not provided\n let cursor = options.cursor\n if (!cursor && this.stateStore) {\n cursor = await this.stateStore.get<string>('events.cursor')\n }\n\n const params = new URLSearchParams()\n if (cursor) params.set('cursor', cursor)\n if (options.limit) params.set('limit', String(options.limit))\n if (options.waitSeconds !== undefined) params.set('wait', String(options.waitSeconds))\n\n const url = `${this.baseUrl}/api/v1/events?${params.toString()}`\n\n const response = await fetch(url, {\n method: 'GET',\n headers: this.buildHeaders(),\n })\n\n if (!response.ok) {\n const body = await response.text().catch(() => '')\n throw new GatewayError(\n `getEvents failed: ${response.status} ${response.statusText}`,\n response.status,\n body\n )\n }\n\n const result = (await response.json()) as GetEventsResponse\n\n // Persist cursor if stateStore is available\n if (result.cursor && this.stateStore) {\n await this.stateStore.set('events.cursor', result.cursor)\n }\n\n return result\n }\n\n /**\n * Acknowledge an event (mark as processed).\n *\n * NOTE: The /events/:id/ack endpoint may not be implemented on the API server yet.\n */\n async ackEvent(eventId: string): Promise<AckEventResponse> {\n const url = `${this.baseUrl}/api/v1/events/${encodeURIComponent(eventId)}/ack`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: this.buildHeaders(),\n })\n\n if (!response.ok) {\n const body = await response.text().catch(() => '')\n throw new GatewayError(\n `ackEvent failed: ${response.status} ${response.statusText}`,\n response.status,\n body\n )\n }\n\n return (await response.json()) as AckEventResponse\n }\n\n /**\n * Validate an API key against the Gateway.\n *\n * @param apiKey API key to validate\n * @param projectId Optional project scope\n * @param requiredScopes Scopes the caller needs — callers should pass the\n * scopes relevant to their context (e.g. MCP passes\n * ['mcp:tools:*', 'mcp:memory:*']).\n */\n async validateApiKey(\n apiKey: string,\n projectId?: string,\n requiredScopes?: string[]\n ): Promise<ApiKeyValidationResult> {\n const url = `${this.baseUrl}/api/mcp/api-keys/validate`\n\n const body: Record<string, unknown> = { projectId }\n if (requiredScopes && requiredScopes.length > 0) {\n body.requiredScopes = requiredScopes\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': apiKey,\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n return { valid: false }\n }\n\n return (await response.json()) as ApiKeyValidationResult\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n if (this.apiKey) {\n headers['X-API-Key'] = this.apiKey\n }\n if (this.sessionToken) {\n headers['Authorization'] = `Bearer ${this.sessionToken}`\n }\n return headers\n }\n}\n\n/**\n * Result of API key validation\n */\nexport interface ApiKeyValidationResult {\n valid: boolean\n userId?: string\n projectId?: string\n scopes?: string[]\n}\n\n/**\n * Error class for Gateway API errors\n */\nexport class GatewayError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody: string\n ) {\n super(message)\n this.name = 'GatewayError'\n }\n}\n","import { IStateStore } from '../state/state-store.interface'\nimport { GatewayClient, ApiKeyValidationResult } from '../gateway/gateway-client'\n\n/**\n * Authentication state persisted in the StateStore\n */\nexport interface AuthState {\n apiKey: string\n apiUrl: string\n userId?: string\n projectId?: string\n scopes?: string[]\n authenticatedAt: string\n}\n\n/**\n * Authentication provider that validates API keys and persists auth state.\n * Used by CLI and MCP to authenticate against the Gateway API.\n */\nexport class AuthProvider {\n private stateStore: IStateStore\n private gatewayClient: GatewayClient\n\n constructor(stateStore: IStateStore, gatewayClient: GatewayClient) {\n this.stateStore = stateStore\n this.gatewayClient = gatewayClient\n }\n\n /**\n * Authenticate with an API key. Validates against the Gateway and\n * persists the result in the StateStore.\n *\n * @returns The validation result\n */\n async login(apiKey: string, apiUrl: string, projectId?: string): Promise<ApiKeyValidationResult> {\n const result = await this.gatewayClient.validateApiKey(apiKey, projectId)\n\n if (result.valid) {\n const authState: AuthState = {\n apiKey,\n apiUrl,\n userId: result.userId,\n projectId: result.projectId || projectId,\n scopes: result.scopes,\n authenticatedAt: new Date().toISOString(),\n }\n await this.stateStore.set('auth', authState)\n }\n\n return result\n }\n\n /**\n * Get the current auth state from the StateStore.\n * Returns undefined if not authenticated.\n */\n async getAuthState(): Promise<AuthState | undefined> {\n return this.stateStore.get<AuthState>('auth')\n }\n\n /**\n * Check if we have stored auth credentials\n */\n async isAuthenticated(): Promise<boolean> {\n const auth = await this.getAuthState()\n return auth !== undefined && auth.apiKey !== undefined\n }\n\n /**\n * Clear auth state (logout)\n */\n async logout(): Promise<void> {\n await this.stateStore.delete('auth')\n }\n\n /**\n * Get the stored API key, or undefined if not authenticated\n */\n async getApiKey(): Promise<string | undefined> {\n const auth = await this.getAuthState()\n return auth?.apiKey\n }\n\n /**\n * Get the stored API URL, or undefined if not authenticated\n */\n async getApiUrl(): Promise<string | undefined> {\n const auth = await this.getAuthState()\n return auth?.apiUrl\n }\n}\n","// action-registry.ts\n// ------------------------------------------------------------\n// Action Registry 型定義 + Ajv バリデーション + ローダ\n// ------------------------------------------------------------\n\n/* ===== 1) 型定義 ===== */\n\nimport { RiskLevel } from '../types/context'\nimport { TargetBindings } from '../types/target-binding'\nexport type { RiskLevel }\nexport type Relation = 'viewer' | 'editor' | 'admin' | 'owner' | 'act_as'\n\n/** Resource type in canonical `provider:resource` format */\nexport type ResourceType = string\n\n/** JSON Schema を受け取るための型。Ajvで別途メタ検証します。 */\nexport type JsonSchema = Record<string, unknown>\n\nexport interface ActionMeta {\n action: string // e.g., \"slack:channel.post_message\"\n resource_type: ResourceType\n required_relations: Relation[] // OR解釈を想定(どれか1つ満たせばOK)\n required_scopes: string[] // プロバイダ生スコープ(例:chat:write, repo)\n capability?: string // 論理バンドル名\n input_schema?: JsonSchema // 入力JSONのSchema(任意)\n constraints?: Record<string, unknown> // rate_bucket, max_size_mb など任意\n effects?: string[] // 監査の説明用\n risk: RiskLevel // registry-driven risk resolution (§4.1); schema-required\n target_bindings?: TargetBindings // Declarative resource binding definitions\n version: string // \"1.0.0\" など\n}\n\nexport interface CapabilityMeta {\n capability: string // e.g., \"slack.messaging.basic\"\n description?: string\n includes: string[] // アクション名の配列\n version: string\n}\n\nexport interface ActionRegistry {\n registry_version: string // 例: \"2025-09-28\"\n actions: ActionMeta[]\n capabilities?: CapabilityMeta[]\n}\n\n/* ===== 2) Ajv スキーマ ===== */\n\nimport Ajv, { DefinedError } from 'ajv'\nimport addFormats from 'ajv-formats'\n\n/** 型定義に対応するJSON Schema(input_schema自体は別メタ検証) */\nconst actionMetaSchema = {\n $id: 'https://vess.ai/schemas/action-meta.json',\n type: 'object',\n additionalProperties: false,\n required: ['action', 'resource_type', 'required_relations', 'required_scopes', 'risk', 'version'],\n properties: {\n action: { type: 'string', minLength: 1 },\n resource_type: {\n type: 'string',\n minLength: 1,\n },\n required_relations: {\n type: 'array',\n minItems: 1,\n items: {\n type: 'string',\n enum: ['viewer', 'editor', 'admin', 'owner', 'act_as'],\n },\n },\n required_scopes: {\n type: 'array',\n minItems: 1,\n items: { type: 'string', minLength: 1 },\n },\n capability: { type: 'string' },\n input_schema: { type: 'object' }, // ← ここは後段で「JSON Schemaとして」別検証\n constraints: { type: 'object', additionalProperties: true },\n effects: {\n type: 'array',\n items: { type: 'string', minLength: 1 },\n },\n risk: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },\n target_bindings: { type: 'object' },\n version: { type: 'string', minLength: 1 },\n },\n} as const\n\nconst capabilityMetaSchema = {\n $id: 'https://vess.ai/schemas/capability-meta.json',\n type: 'object',\n additionalProperties: false,\n required: ['capability', 'includes', 'version'],\n properties: {\n capability: { type: 'string', minLength: 1 },\n description: { type: 'string' },\n includes: {\n type: 'array',\n minItems: 1,\n items: { type: 'string', minLength: 1 },\n },\n version: { type: 'string', minLength: 1 },\n },\n} as const\n\nconst registrySchema = {\n $id: 'https://vess.ai/schemas/action-registry.json',\n type: 'object',\n additionalProperties: false,\n required: ['registry_version', 'actions'],\n properties: {\n registry_version: { type: 'string', minLength: 1 },\n actions: {\n type: 'array',\n minItems: 1,\n items: { $ref: 'https://vess.ai/schemas/action-meta.json' },\n },\n capabilities: {\n type: 'array',\n items: { $ref: 'https://vess.ai/schemas/capability-meta.json' },\n },\n },\n} as const\n\n/* ===== 3) バリデータ構築(input_schemaのメタ検証込み) ===== */\n\n/**\n * Ajv インスタンスを作成。\n * - 本体スキーマ(registry/actions/capabilities)を登録\n * - formats 追加\n * - $id付きで利用\n */\nexport function createAjv(): Ajv {\n const ajv = new Ajv({\n allErrors: true,\n strict: true,\n allowUnionTypes: true,\n // draft-2020-12 デフォルト。input_schema のメタ検証に使う。\n })\n addFormats(ajv)\n\n ajv.addSchema(actionMetaSchema)\n ajv.addSchema(capabilityMetaSchema)\n ajv.addSchema(registrySchema)\n\n return ajv\n}\n\n/**\n * Registry全体の構文検証 + 各Actionの input_schema を「JSON Schemaとして」検証。\n * @returns { ok, errors } 失敗時は diag を含む\n */\nexport function validateRegistryObject(registry: unknown): {\n ok: boolean\n errors?: string[]\n} {\n const ajv = createAjv()\n\n // 1) レジストリ本体の検証\n const validate = ajv.getSchema<ActionRegistry>('https://vess.ai/schemas/action-registry.json')\n if (!validate) {\n return { ok: false, errors: ['Ajv schema not loaded'] }\n }\n const valid = validate(registry)\n if (!valid) {\n return {\n ok: false,\n errors: validate.errors ? formatAjvErrors(validate.errors as DefinedError[]) : [],\n }\n }\n\n const typed = registry as ActionRegistry\n\n // 2) 各action.input_schema を JSON Schema としてメタ検証\n // Ajv は meta-schema を内部保持しているので、compileで検証可能。\n const schemaErrors: string[] = []\n for (const a of typed.actions) {\n if (a.input_schema) {\n try {\n // 個別スキーマとしてコンパイル(不正なら例外 or errors)\n const local = new Ajv({ strict: true, allErrors: true })\n addFormats(local)\n const compiled = local.compile(a.input_schema)\n // コンパイルは成功しても errors が残ることはない想定\n if (compiled.errors?.length) {\n schemaErrors.push(\n `[${a.action}] input_schema errors: ${formatAjvErrors(\n compiled.errors as DefinedError[]\n ).join('; ')}`\n )\n }\n } catch (e: any) {\n schemaErrors.push(`[${a.action}] input_schema invalid: ${e?.message ?? String(e)}`)\n }\n }\n }\n\n if (schemaErrors.length) {\n return { ok: false, errors: schemaErrors }\n }\n\n // 3) capabilities.includes が存在する action に一致するか軽く検証\n if (typed.capabilities?.length) {\n const actionsSet = new Set(typed.actions.map(x => x.action))\n for (const c of typed.capabilities) {\n for (const act of c.includes) {\n if (!actionsSet.has(act)) {\n schemaErrors.push(`[capability:${c.capability}] includes unknown action: ${act}`)\n }\n }\n }\n }\n\n if (schemaErrors.length) {\n return { ok: false, errors: schemaErrors }\n }\n\n return { ok: true }\n}\n\nfunction formatAjvErrors(errors?: DefinedError[] | null): string[] {\n if (!errors?.length) return []\n return errors.map(e => {\n const instancePath = e.instancePath || '/'\n const msg = e.message || 'invalid'\n const params = e.params && Object.keys(e.params).length ? ` (${JSON.stringify(e.params)})` : ''\n return `${instancePath}: ${msg}${params}`\n })\n}\n\n/* ===== 4) ロード関数(ファイル/オブジェクト) ===== */\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * JSONファイルからAction Registryを読み込み、完全検証して返す。\n * @throws Error 検証エラー時は詳細メッセージ付きでthrow\n */\nexport async function loadActionRegistryFromFile(filePath: string): Promise<ActionRegistry> {\n const abs = path.resolve(filePath)\n const raw = await fs.readFile(abs, 'utf8')\n const json = JSON.parse(raw)\n\n const result = validateRegistryObject(json)\n if (!result.ok) {\n const errs = result.errors?.join('\\n - ') || ''\n throw new Error(`ActionRegistry validation failed:\\n - ${errs}`)\n }\n return json as ActionRegistry\n}\n\n/**\n * 既にパース済みのオブジェクトを検証して返す。\n * @throws Error 検証エラー時は詳細メッセージ付きでthrow\n */\nexport function loadActionRegistryFromObject(obj: unknown): ActionRegistry {\n const result = validateRegistryObject(obj)\n if (!result.ok) {\n const errs = result.errors?.join('\\n - ') || ''\n throw new Error(`ActionRegistry validation failed:\\n - ${errs}`)\n }\n return obj as ActionRegistry\n}\n\n/* ===== 5) ヘルパ ===== */\n\n/** アクション名→ActionMeta のルックアップを作成 */\nexport function indexActions(reg: ActionRegistry): Map<string, ActionMeta> {\n const map = new Map<string, ActionMeta>()\n for (const a of reg.actions) map.set(a.action, a)\n return map\n}\n\n/** Capability名→CapabilityMeta のルックアップを作成 */\nexport function indexCapabilities(reg: ActionRegistry): Map<string, CapabilityMeta> {\n const map = new Map<string, CapabilityMeta>()\n for (const c of reg.capabilities ?? []) map.set(c.capability, c)\n return map\n}\n\n/** 指定アクションの required_scopes を取得(無ければ空配列) */\nexport function getRequiredScopes(regIndex: Map<string, ActionMeta>, action: string): string[] {\n return regIndex.get(action)?.required_scopes ?? []\n}\n\n/** 指定アクションの required_relations(OR解釈)を取得(無ければ空配列) */\nexport function getRequiredRelations(\n regIndex: Map<string, ActionMeta>,\n action: string\n): Relation[] {\n return (regIndex.get(action)?.required_relations ?? []) as Relation[]\n}\n\n/* ===== 6) 使い方サンプル(コメント) =====\nimport { loadActionRegistryFromFile, indexActions, getRequiredScopes } from \"./action-registry\";\n\n(async () => {\n const reg = await loadActionRegistryFromFile(\"./action-registry.json\");\n const idx = indexActions(reg);\n\n const action = \"slack:channel.post_message\";\n console.log(\"required scopes:\", getRequiredScopes(idx, action));\n})();\n========================================================== */\n","/**\n * Canonical Provider definitions — single source of truth.\n *\n * All packages (API, remote-mcp, SDK) should import provider constants from here.\n */\n\n/** Canonical provider identifiers */\nexport type CanonicalProvider = 'slack' | 'github' | 'gmail' | 'calendar' | 'jira' | 'os'\n\n/** All valid provider identifiers */\nexport type AnyProvider = CanonicalProvider\n\n/** Ordered list of canonical providers */\nexport const CANONICAL_PROVIDERS: readonly CanonicalProvider[] = [\n 'slack',\n 'github',\n 'gmail',\n 'calendar',\n 'jira',\n 'os',\n] as const\n\n/** Provider alias → canonical provider mapping (empty — no aliases in new format) */\nexport const PROVIDER_ALIASES: Readonly<Record<string, CanonicalProvider>> = {} as const\n\n/**\n * Resolve any provider string to its canonical form.\n *\n * In the new `provider.resource.operation` format, each provider is its own\n * canonical name (e.g., 'gmail', 'calendar', 'github'). No aliases are used.\n *\n * @param provider - raw provider string\n * @param _resolveSubProviders - unused, kept for API compatibility\n */\nexport function resolveProvider(\n provider: string,\n _resolveSubProviders = false,\n): string {\n // Check aliases (currently empty — no aliases in new format)\n const aliased = PROVIDER_ALIASES[provider]\n if (aliased) return aliased\n\n return provider\n}\n\n/**\n * Check if a string is a valid canonical provider.\n */\nexport function isCanonicalProvider(value: string): value is CanonicalProvider {\n return (CANONICAL_PROVIDERS as readonly string[]).includes(value)\n}\n\n/**\n * Check if a string is a valid provider (canonical).\n */\nexport function isValidProvider(value: string): value is AnyProvider {\n return isCanonicalProvider(value)\n}\n","// access-orchestrator.ts\n// ------------------------------------------------------------\n// VC発行時:要求アクションの解決・絞り込み\n// VP時 :権限判定(ReBAC→Delegation(VC)→ABAC→Scope/Cred)\n// ------------------------------------------------------------\n\nimport {\n ActionRegistry,\n ActionMeta,\n CapabilityMeta,\n Relation,\n ResourceType,\n indexActions,\n indexCapabilities,\n getRequiredRelations,\n getRequiredScopes,\n} from './action-registry'\nimport { resolveProvider as _resolveProvider } from './providers'\n\n/* ========== 1) 依存インターフェース(差し替えポイント) ========== */\n\n/** ReBAC: 関係性チェック(SpiceDB/Zanzibar想定)。OR解釈で複数relationのいずれか成立でtrue */\nexport interface ReBACChecker {\n check(\n subjectDid: string, // User DID or Agent DID\n relations: Relation[], // [\"editor\",\"act_as\"] など\n resourceRef: ResourceRef // リソース参照\n ): Promise<boolean>\n}\n\n/** ABAC: 条件判定(Cerbos/OPA想定)。trueなら許可。 */\nexport interface ABACPolicyEngine {\n evaluate(input: AbacInput): Promise<AbacDecision>\n}\nexport interface AbacInput {\n principal: {\n id: string // DID(Agent/User)\n roles?: string[]\n claims?: Record<string, unknown> // VC由来クレームなど\n }\n resource: {\n kind: ResourceType\n id: string // プロバイダのリソースID\n attr?: Record<string, unknown>\n }\n action: string // 標準化アクション名\n context?: Record<string, unknown> // time/ip/riskなど\n}\nexport interface AbacDecision {\n allow: boolean\n ruleId?: string\n reason?: string\n}\n\n/** Credential選択:最小スコープを満たす外部トークンを取得(Bot/Installation/OAuth) */\nexport interface CredentialStore {\n pickMinimal(\n provider: Provider, // \"slack\" | \"github\" | \"gmail\" | \"calendar\" | \"jira\"\n iaId: string, // IntegrationAccount ID\n requiredScopes: string[],\n subjectDid: string // 実行主体(Agent/User)\n ): Promise<CredentialRef | null>\n}\nexport type { CanonicalProvider as Provider } from './providers'\nimport type { CanonicalProvider as Provider } from './providers'\nexport interface CredentialRef {\n id: string\n provider: Provider\n scopes: string[]\n // DPoP/MTLSの鍵バインド対応していれば JWK Thumbprint等も\n}\n\n/** VP検証(SD-JWT/ISO 23220/mdoc/OID4VP):成功時にVCクレームを返す */\nexport interface VpVerifier {\n verifyAndExtractClaims(vpToken: string): Promise<VerifiedVcClaims>\n}\n/** 発行した Delegation VC に含めることを想定した最小構造 */\nexport interface VerifiedVcClaims {\n // 権限表明\n allowed_actions: string[] // 標準化アクション名\n resource_scope: ResourceScope[] // 対象スコープ(Workspace/Resource/IA 単位など)\n expires_at?: string // ISO日時\n actor?: string // on_behalf_of 等(任意)\n assurance_level?: number // ABACで使う\n // キー・バインド(DPoP等)\n cnf?: { jwk_thumbprint?: string }\n // 追加クレーム\n [k: string]: unknown\n}\n\n/* ========== 2) ドメイン補助型 ========== */\n\nexport interface ResourceRef {\n /** プロバイダ別のリソース識別子(例:Slack channel id, GitHub repo full_name, Drive file id) */\n id: string\n type: ResourceType\n /** 紐づくIntegrationAccountのID(どのSlackワークスペース/どのGitHub Orgか) */\n iaId: string\n /** 追加属性(機密度など) */\n attr?: Record<string, unknown>\n}\n\n/** VCに刻む「スコープ」表現の一例(最小定義) */\nexport type ResourceScope =\n | { kind: 'Workspace'; id: string }\n | { kind: 'IntegrationAccount'; id: string }\n | { kind: 'Resource'; type: ResourceType; id: string }\n\n/** 監査用の判定理由 */\nexport interface DecisionTrace {\n rebac?: { ok: boolean; relations: Relation[] }\n delegation?: {\n ok: boolean\n matched_action?: boolean\n in_scope?: boolean\n notExpired?: boolean\n }\n abac?: { ok: boolean; ruleId?: string; reason?: string }\n scope?: { ok: boolean; required: string[]; chosenCredentialId?: string }\n}\n\n/* ========== 3) アクション解決ユーティリティ ========== */\n\n/** Capability名やAction名(混在OK)から、実アクション配列に解決 */\nexport function resolveActionsFromSelection(\n registry: ActionRegistry,\n selection: string[] // [\"slack.messaging.basic\", \"github:repo.create_issue\", ...]\n): string[] {\n const aIndex = indexActions(registry)\n const cIndex = indexCapabilities(registry)\n\n const out = new Set<string>()\n for (const item of selection) {\n if (aIndex.has(item)) {\n out.add(item)\n continue\n }\n const cap = cIndex.get(item)\n if (cap) {\n for (const act of cap.includes) out.add(act)\n continue\n }\n // 未知の名前はスキップ(ログには出してよい)\n }\n return [...out]\n}\n\n/* ========== 4) VC発行計画(発行前チェック & 絞り込み) ========== */\n\nexport interface PlanDelegationInput {\n registry: ActionRegistry\n issuerUserDid: string // 委任元(人間)のDID\n delegateAgentDid: string // 委任先(AI Agent)のDID\n /** ユーザーが UI 等で選んだアクション/ケイパビリティ */\n requested: string[] // action or capability\n /** この委任が及ぶスコープ(Workspace/IA/Resource) */\n resourceScope: ResourceScope[]\n /** 有効期限(ISO) */\n expiresAt?: string\n /** ABAC前提で要求する最小アシュアランス等(必要なら) */\n minAssuranceLevel?: number\n /** ABAC/Cerbos用のruntime context(時間帯/場所/リスク等) */\n context?: Record<string, unknown>\n /** Provider 推測のためのヒント(Credential選択時に使う) */\n providerByIa?: Record<string, Provider> // iaId -> provider\n /** 実行時に用いるReBAC/ABAC/Credentialのハンドラ */\n rebac: ReBACChecker\n abac: ABACPolicyEngine\n creds: CredentialStore\n}\n\nexport interface PlanDelegationResult {\n granted_actions: string[] // VCに刻める実アクション(最終)\n rejected_actions: string[] // 却下されたアクション(理由はtraceで)\n traceByAction: Record<string, DecisionTrace>\n}\n\n/**\n * VC発行前に、リクエストされたアクション群を\n * - Registryに存在\n * - ReBAC(委任元=issuerUserDid が十分な関係を持つ)\n * - ABACポリシー適合\n * - 必要スコープを満たすクレデンシャルが存在\n * の観点で絞り込み、発行して良いものだけ返す。\n */\nexport async function planDelegationForVC(\n input: PlanDelegationInput\n): Promise<PlanDelegationResult> {\n const {\n registry,\n issuerUserDid,\n requested,\n resourceScope,\n rebac,\n abac,\n creds,\n providerByIa = {},\n context,\n } = input\n\n // 1) capability展開 → 実アクションへ\n const requestedActions = resolveActionsFromSelection(registry, requested)\n const aIndex = indexActions(registry)\n\n const granted: string[] = []\n const rejected: string[] = []\n const traceByAction: Record<string, DecisionTrace> = {}\n\n // resourceScopeに Resource 単位が無い場合は、Workspace/IA スコープとして評価し、\n // VC自体は scope をそのまま入れる運用を想定。\n // ここでは「代表リソース」を特定できるケースを優先(Resource Scopeが与えられた場合)\n const resourceScopes = resourceScope.filter(s => s.kind === 'Resource') as {\n kind: 'Resource'\n id: string\n type: ResourceType\n }[]\n\n for (const action of requestedActions) {\n const meta = aIndex.get(action)\n const t: DecisionTrace = {}\n traceByAction[action] = t\n\n if (!meta) {\n rejected.push(action)\n continue\n }\n // 2) ReBACチェック(issuerがそもそも対象を委任できるか)\n // Resourceスコープが与えられていればそれで、無ければスキップ(Workspace/IAは発行時はOKとする運用可)\n if (resourceScopes.length) {\n let rebacOk = false\n for (const rs of resourceScopes) {\n const rels = getRequiredRelations(aIndex, action)\n const ok = await rebac.check(\n issuerUserDid,\n rels.length ? rels : ['owner', 'admin', 'editor', 'viewer'],\n {\n id: rs.id,\n type: rs.type,\n iaId: '', // 発行時点では空でもOK。持っているなら入れる。\n }\n )\n if (ok) {\n rebacOk = true\n break\n }\n }\n t.rebac = { ok: rebacOk, relations: getRequiredRelations(aIndex, action) }\n if (!rebacOk) {\n rejected.push(action)\n continue\n }\n }\n\n // 3) ABAC(発行時の基本ルール:高リスクは委任不可等)\n const abacDec = await abac.evaluate({\n principal: { id: issuerUserDid, roles: ['user'] },\n resource: {\n kind: resourceScopes[0]?.type ?? meta.resource_type,\n id: resourceScopes[0]?.id ?? 'SCOPE_ONLY',\n attr: {},\n },\n action,\n context,\n })\n t.abac = { ok: abacDec.allow, ruleId: abacDec.ruleId, reason: abacDec.reason }\n if (!abacDec.allow) {\n rejected.push(action)\n continue\n }\n\n // 4) Credential存在チェック(最低限:将来の実行で使える見込みか)\n // scope→provider解決は iaId→provider を使う。Resource scope が無ければスキップ可。\n let scopeOk = true\n const required = getRequiredScopes(aIndex, action)\n if (resourceScopes.length && required.length) {\n // どれかのResourceで必要スコープを満たすCredentialが取れればOK\n scopeOk = false\n for (const rs of resourceScopes) {\n const provider = inferProviderByResourceType(rs.type)\n const cred = await creds.pickMinimal(provider, '', required, issuerUserDid)\n if (cred) {\n scopeOk = true\n break\n }\n }\n }\n t.scope = { ok: scopeOk, required }\n if (!scopeOk) {\n rejected.push(action)\n continue\n }\n\n granted.push(action)\n }\n\n return { granted_actions: granted, rejected_actions: rejected, traceByAction }\n}\n\nfunction inferProviderByResourceType(rt: ResourceType): Provider {\n // Canonical format: provider:resource (e.g., 'slack:channel', 'github:repo')\n const colonIdx = rt.indexOf(':')\n if (colonIdx > 0) {\n const provider = rt.substring(0, colonIdx)\n return _resolveProvider(provider, true) as Provider\n }\n // Legacy CamelCase fallback\n switch (rt) {\n case 'SlackChannel':\n return 'slack'\n case 'GitHubRepo':\n return 'github'\n default:\n return 'slack' // fallback\n }\n}\n\n/* ========== 5) 実行時判定(VP提示での許可/拒否) ========== */\n\nexport interface CheckPermissionInput {\n registry: ActionRegistry\n actorDid: string // 実行主体(Agent DID推奨)\n onBehalfOfDid?: string // 人の代理で実行する場合に\n action: string // 標準化アクション\n resource: ResourceRef // 対象リソース\n vpToken: string // 委任VCのVP(SD-JWT/mdoc/OID4VP)\n context?: Record<string, unknown> // ABAC用(時間/場所/リスク等)\n rebac: ReBACChecker\n abac: ABACPolicyEngine\n creds: CredentialStore\n vpVerifier: VpVerifier\n}\n\nexport interface CheckPermissionResult {\n allow: boolean\n reason?: string\n trace: DecisionTrace\n credential?: CredentialRef | null\n}\n\n/**\n * 実行直前のフル判定。\n * 1) ReBAC: actor がresourceに対する 基本関係/act_as を満たすか\n * 2) Delegation(VC): actionがallowedか / resourceがscope内か / 期限内か\n * 3) ABAC: コンテキストやassurance levelに適合するか\n * 4) Scope/Credential: 必要スコープを満たすクレデンシャルが取得できるか\n */\nexport async function checkPermissionWithVP(\n input: CheckPermissionInput\n): Promise<CheckPermissionResult> {\n const { registry, actorDid, action, resource, vpToken, context, rebac, abac, creds, vpVerifier } =\n input\n\n const aIndex = indexActions(registry)\n const meta = aIndex.get(action)\n if (!meta) {\n return { allow: false, reason: 'unknown_action', trace: {} }\n }\n\n const trace: DecisionTrace = {}\n\n // 1) ReBAC\n const rels = getRequiredRelations(aIndex, action)\n const rebacOk = await rebac.check(actorDid, rels.length ? rels : ['viewer'], resource)\n trace.rebac = { ok: rebacOk, relations: rels }\n if (!rebacOk) {\n return { allow: false, reason: 'rebac_denied', trace }\n }\n\n // 2) Delegation(VC/VP)\n const vc = await vpVerifier.verifyAndExtractClaims(vpToken)\n let matchedAction = vc.allowed_actions?.includes(action) ?? false\n // resource scope 判定:VCがWorkspace/IAスコープのみなら、ここではresource.idが含まれるか/包含関係を評価\n let inScope = isResourceInScopes(resource, vc.resource_scope || [])\n // 期限\n const notExpired = !vc.expires_at || new Date(vc.expires_at).getTime() > Date.now()\n\n trace.delegation = {\n ok: matchedAction && inScope && notExpired,\n matched_action: matchedAction,\n in_scope: inScope,\n notExpired,\n }\n if (!trace.delegation.ok) {\n return { allow: false, reason: 'delegation_denied', trace }\n }\n\n // 3) ABAC\n const abacDec = await abac.evaluate({\n principal: {\n id: actorDid,\n roles: ['agent'],\n claims: {\n assurance_level: vc.assurance_level,\n actor: vc.actor,\n },\n },\n resource: {\n kind: resource.type,\n id: resource.id,\n attr: resource.attr || {},\n },\n action,\n context,\n })\n trace.abac = { ok: abacDec.allow, ruleId: abacDec.ruleId, reason: abacDec.reason }\n if (!abacDec.allow) {\n return { allow: false, reason: 'abac_denied', trace }\n }\n\n // 4) 必要スコープを満たすCredential選択\n const provider = inferProviderByResourceType(resource.type)\n const requiredScopes = getRequiredScopes(aIndex, action)\n const cred = await creds.pickMinimal(provider, resource.iaId, requiredScopes, actorDid)\n trace.scope = {\n ok: !!cred,\n required: requiredScopes,\n chosenCredentialId: cred?.id,\n }\n if (!cred) {\n return { allow: false, reason: 'insufficient_scopes', trace, credential: null }\n }\n\n return { allow: true, trace, credential: cred }\n}\n\n/* ========== 6) ヘルパ(スコープ包含) ========== */\n\nfunction isResourceInScopes(resource: ResourceRef, scopes: ResourceScope[]): boolean {\n for (const s of scopes) {\n if (s.kind === 'Resource') {\n if (s.type === resource.type && s.id === resource.id) return true\n } else if (s.kind === 'IntegrationAccount') {\n if (s.id === resource.iaId) return true\n } else if (s.kind === 'Workspace') {\n // Workspace→IA/Resourceの包含をここで判定したければ、マッピングを注入して判定する\n // MVPではWorkspace指定は包括OKとみなす場合は true を返す等、運用方針に合わせて調整\n return true\n }\n }\n return false\n}\n\n/* ========== 7) 例:スタブ実装(MVPテスト用) ========== */\n\n// 開発中の簡易スタブ(本番は各システムに差し替え)\nexport class AllowAllAbac implements ABACPolicyEngine {\n async evaluate(): Promise<AbacDecision> {\n return { allow: true, ruleId: 'allow_all' }\n }\n}\nexport class SimpleRebac implements ReBACChecker {\n constructor(\n private allowRelations: Relation[] = ['viewer', 'editor', 'admin', 'owner', 'act_as']\n ) {}\n async check(_sub: string, relations: Relation[]): Promise<boolean> {\n return relations.some(r => this.allowRelations.includes(r))\n }\n}\nexport class DummyCreds implements CredentialStore {\n async pickMinimal(\n provider: Provider,\n _iaId: string,\n requiredScopes: string[]\n ): Promise<CredentialRef | null> {\n // デモ:githubの'merge'などで'repo'が要れば1個返す、など最小限\n if (!requiredScopes.length) return { id: `${provider}-none`, provider, scopes: [] }\n return { id: `${provider}-demo`, provider, scopes: requiredScopes }\n }\n}\nexport class DummyVpVerifier implements VpVerifier {\n constructor(private vc: VerifiedVcClaims) {}\n async verifyAndExtractClaims(): Promise<VerifiedVcClaims> {\n return this.vc // テスト用:引数無視\n }\n}\n\n/* ========== 8) 使い方(サンプル) ========== */\n/*\n // 1) VC発行計画\n const plan = await planDelegationForVC({\n registry,\n issuerUserDid: \"did:user:alice\",\n delegateAgentDid: \"did:agent:bot1\",\n requested: [\"slack.messaging.basic\", \"github:repo.merge_pr\"],\n resourceScope: [\n { kind: \"IntegrationAccount\", id: \"slack-ia-1\" },\n { kind: \"Resource\", type: \"GitHubRepo\", id: \"vess/awesome\" },\n ],\n rebac: new SimpleRebac([\"owner\", \"admin\", \"editor\"]), // 例えば発行は editor 以上のみ許可\n abac: new AllowAllAbac(),\n creds: new DummyCreds(),\n });\n console.log(plan);\n \n // 2) 実行時判定(VP提示)\n const vpVerifier = new DummyVpVerifier({\n allowed_actions: [\"slack:channel.post_message\", \"github:repo.create_issue\"],\n resource_scope: [\n { kind: \"IntegrationAccount\", id: \"slack-ia-1\" },\n { kind: \"Resource\", type: \"GitHubRepo\", id: \"vess/awesome\" },\n ],\n expires_at: \"2099-12-31T00:00:00Z\",\n assurance_level: 2,\n });\n const res = await checkPermissionWithVP({\n registry,\n actorDid: \"did:agent:bot1\",\n action: \"slack:channel.post_message\",\n resource: { id: \"C123\", type: \"SlackChannel\", iaId: \"slack-ia-1\" },\n vpToken: \"ignored-in-dummy\",\n rebac: new SimpleRebac([\"viewer\", \"editor\", \"act_as\"]),\n abac: new AllowAllAbac(),\n creds: new DummyCreds(),\n vpVerifier,\n });\n console.log(res);\n */\n\n// 適用ポイント(MVPコードへの組み込み)\n// VC発行画面/エンドポイント\n// ユーザーが選んだ capability / action と scope を planDelegationForVC に渡す\n// granted_actions を VC の allowed_actions に、resource_scope と expires_at をそのままVCに含めて発行\n// traceByAction を UI の「なぜ発行不可か」ツールチップにそのまま表示可能\n// 実行ミドルウェア(各 Provider Adapter の前段)\n// リクエストを受けたら checkPermissionWithVP を実行\n// allow=true なら返ってきた credential を使って外部APIを実行\n// trace は監査ログに保存(ReBAC/Delegation/ABAC/Scopeの根拠が揃う)\n// 実装を差し替えるだけ\n// ReBACChecker → SpiceDBの CheckPermission をラップ\n// ABACPolicyEngine → Cerbos/OPAクライアントをラップ\n// CredentialStore → 自前のトークン保管庫\n// VpVerifier → 既存VP検証(SD-JWT/ISO 23220/mdoc/OID4VP)に接続\n","/**\n * Canonical Action Registry — single source of truth.\n *\n * Action names use the `provider.resource.operation` dot format matching\n * the tool adapter implementations in packages/api/src/tool/adapters/.\n *\n * All packages (api, mcp, remote-mcp) MUST reference this registry\n * for action names, scopes, and risk levels.\n */\nexport const ACTION_REGISTRY = {\n registry_version: '2025-09-28',\n actions: [\n // ─── Slack Actions ───\n {\n action: 'slack.message.post',\n resource_type: 'slack:channel',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['chat:write'],\n capability: 'slack.messaging.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID, channel name, or channel name with # prefix' },\n text: { type: 'string', minLength: 1, maxLength: 40000 },\n thread_ts: { type: 'string' },\n username: { type: 'string' },\n icon_emoji: { type: 'string' },\n blocks: { type: 'array' },\n },\n required: ['channel', 'text'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.post' },\n effects: ['Create:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.channel.read',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['channels:read', 'groups:read'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:ChannelList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.user.read',\n resource_type: 'slack:user',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['users:read'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n userId: { type: 'string', description: 'The Slack user ID' },\n },\n required: ['userId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:User'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'userId' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.message.read',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['channels:history', 'groups:history'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID, channel name, or channel name with # prefix' },\n latest: { type: 'string' },\n oldest: { type: 'string' },\n limit: { type: 'integer', minimum: 1, maximum: 30 },\n inclusive: { type: 'boolean' },\n },\n required: ['channel'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.message.read_paginated',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['channels:history', 'groups:history'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID, channel name, or channel name with # prefix' },\n cursor: { type: 'string', description: 'Pagination cursor from previous response' },\n limit: { type: 'integer', minimum: 1, maximum: 30 },\n },\n required: ['channel'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.batch.read',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n // Documentation only — NOT used for runtime access control.\n // Actual permission granting uses parseSlackScopes (oauth.service.ts) with OR-logic:\n // any read scope + any history scope grants slack.batch.read.\n // Tokens with partial scopes (e.g. channels:read + channels:history) will still receive this permission.\n required_scopes: ['channels:read', 'groups:read', 'im:read', 'mpim:read', 'channels:history', 'groups:history', 'im:history', 'mpim:history'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID for history retrieval' },\n limit: { type: 'integer', minimum: 1 },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:ChannelList', 'Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel', required: false },\n },\n version: '1.0.0',\n },\n\n {\n action: 'slack.message.update',\n resource_type: 'slack:channel',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['chat:write'],\n capability: 'slack.messaging.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID containing the message' },\n ts: { type: 'string', description: 'Timestamp of the message to update' },\n text: { type: 'string', minLength: 1, maxLength: 40000 },\n },\n required: ['channel', 'ts', 'text'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.post' },\n effects: ['Update:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.message.delete',\n resource_type: 'slack:channel',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['chat:write'],\n capability: 'slack.messaging.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID containing the message' },\n ts: { type: 'string', description: 'Timestamp of the message to delete' },\n },\n required: ['channel', 'ts'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.post' },\n effects: ['Delete:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n\n // ─── GitHub Actions ───\n {\n action: 'github.issue.create',\n resource_type: 'github:repo',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['repo', 'write:issues'],\n capability: 'github.issues.triage',\n input_schema: {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n body: { type: 'string' },\n labels: { type: 'array', items: { type: 'string' } },\n assignees: { type: 'array', items: { type: 'string' } },\n },\n required: ['title'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.write' },\n effects: ['Create:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n {\n action: 'github.issue.list',\n resource_type: 'github:repo',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['repo', 'read:issues'],\n capability: 'github.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n state: { type: 'string', enum: ['open', 'closed', 'all'] },\n labels: { type: 'string' },\n sort: { type: 'string', enum: ['created', 'updated', 'comments'] },\n direction: { type: 'string', enum: ['asc', 'desc'] },\n per_page: { type: 'integer', minimum: 1, maximum: 100 },\n page: { type: 'integer', minimum: 1 },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.read' },\n effects: ['Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n {\n action: 'github.issue.read',\n resource_type: 'github:repo',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['repo', 'read:issues'],\n capability: 'github.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issue_number: { type: 'integer', minimum: 1 },\n },\n required: ['issue_number'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.read' },\n effects: ['Read:Issue'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n {\n action: 'github.issue.update',\n resource_type: 'github:repo',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['repo', 'write:issues'],\n capability: 'github.issues.triage',\n input_schema: {\n type: 'object',\n properties: {\n issue_number: { type: 'integer', minimum: 1 },\n title: { type: 'string' },\n body: { type: 'string' },\n state: { type: 'string', enum: ['open', 'closed'] },\n labels: { type: 'array', items: { type: 'string' } },\n assignees: { type: 'array', items: { type: 'string' } },\n },\n required: ['issue_number'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.write' },\n effects: ['Update:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n\n // ─── Gmail Actions ───\n {\n action: 'gmail.message.search',\n resource_type: 'gmail:thread',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n query: { type: 'string', minLength: 1 },\n maxResults: { type: 'integer', minimum: 1, maximum: 500 },\n },\n required: ['query'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:MessageList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'query', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.message.read',\n resource_type: 'gmail:thread',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n messageId: { type: 'string', minLength: 1 },\n },\n required: ['messageId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageId' },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.message.send',\n resource_type: 'gmail:thread',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.compose'],\n capability: 'gmail.compose',\n input_schema: {\n type: 'object',\n properties: {\n to: { type: 'string', minLength: 1 },\n subject: { type: 'string', minLength: 1 },\n body: { type: 'string', minLength: 1 },\n cc: { type: 'string' },\n bcc: { type: 'string' },\n threadId: { type: 'string' },\n inReplyTo: { type: 'string' },\n references: { type: 'string' },\n },\n required: ['to', 'subject', 'body'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Create:Email'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'to', multi: true, separator: ',' },\n secondary: [\n { name: 'cc', source: { source: 'param' as const, param: 'cc' }, type: 'recipient' },\n { name: 'bcc', source: { source: 'param' as const, param: 'bcc' }, type: 'recipient' },\n ],\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.draft.create',\n resource_type: 'gmail:thread',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.compose'],\n capability: 'gmail.compose',\n input_schema: {\n type: 'object',\n properties: {\n to: { type: 'string', minLength: 1 },\n subject: { type: 'string', minLength: 1 },\n body: { type: 'string', minLength: 1 },\n cc: { type: 'string' },\n bcc: { type: 'string' },\n threadId: { type: 'string' },\n inReplyTo: { type: 'string' },\n references: { type: 'string' },\n },\n required: ['to', 'subject', 'body'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Create:Draft'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'to', multi: true, separator: ',' },\n secondary: [\n { name: 'cc', source: { source: 'param' as const, param: 'cc' }, type: 'recipient' },\n { name: 'bcc', source: { source: 'param' as const, param: 'bcc' }, type: 'recipient' },\n ],\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.label.read',\n resource_type: 'gmail:label',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:LabelList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'labelId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.batch.read',\n resource_type: 'gmail:thread',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n messageIds: {\n type: 'array',\n items: { type: 'string', minLength: 1 },\n minItems: 1,\n maxItems: 20,\n },\n },\n required: ['messageIds'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:MessageBatch'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageIds', required: false },\n },\n version: '1.0.0',\n },\n\n {\n action: 'gmail.message.trash',\n resource_type: 'gmail:message',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.modify'],\n capability: 'gmail.manage',\n input_schema: {\n type: 'object',\n properties: {\n messageId: { type: 'string', minLength: 1 },\n },\n required: ['messageId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Update:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageId' },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.message.delete',\n resource_type: 'gmail:message',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.modify'],\n capability: 'gmail.manage',\n input_schema: {\n type: 'object',\n properties: {\n messageId: { type: 'string', minLength: 1 },\n },\n required: ['messageId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Delete:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageId' },\n },\n version: '1.0.0',\n },\n\n // ─── Calendar Actions ───\n {\n action: 'calendar.event.list',\n resource_type: 'calendar:event',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/calendar.readonly'],\n capability: 'calendar.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string', description: 'Calendar ID (email address). Defaults to primary calendar.' },\n timeMin: { type: 'string', description: 'Lower bound (inclusive) for event start time, as ISO 8601 datetime, e.g. \"2025-01-15T00:00:00Z\"' },\n timeMax: { type: 'string', description: 'Upper bound (exclusive) for event start time, as ISO 8601 datetime, e.g. \"2025-01-16T00:00:00Z\"' },\n maxResults: { type: 'integer', minimum: 1, maximum: 2500, description: 'Maximum number of events to return' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.read' },\n effects: ['Read:EventList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', required: false, default: 'primary' },\n },\n version: '1.0.0',\n },\n {\n action: 'calendar.event.read',\n resource_type: 'calendar:event',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/calendar.readonly'],\n capability: 'calendar.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string' },\n eventId: { type: 'string', minLength: 1 },\n },\n required: ['eventId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.read' },\n effects: ['Read:Event'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'eventId' },\n },\n version: '1.0.0',\n },\n {\n action: 'calendar.event.create',\n resource_type: 'calendar:event',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/calendar'],\n capability: 'calendar.write',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string', description: 'Calendar ID (email address). Defaults to primary calendar.' },\n summary: { type: 'string', minLength: 1, description: 'Event title' },\n description: { type: 'string', description: 'Event description' },\n start: {\n type: 'object',\n description: 'Start time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T10:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-15\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n end: {\n type: 'object',\n description: 'End time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T11:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-16\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n attendees: { type: 'array', description: 'List of attendee objects with email field', items: { type: 'object', properties: { email: { type: 'string' } } } },\n location: { type: 'string', description: 'Event location' },\n },\n required: ['summary', 'start', 'end'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.write' },\n effects: ['Create:Event'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', default: 'primary' },\n secondary: [\n { name: 'attendees', source: { source: 'param' as const, param: 'attendees' }, type: 'participant' },\n ],\n },\n version: '1.0.0',\n },\n {\n action: 'calendar.event.update',\n resource_type: 'calendar:event',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/calendar'],\n capability: 'calendar.write',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string', description: 'Calendar ID (email address). Defaults to primary calendar.' },\n eventId: { type: 'string', minLength: 1, description: 'Event ID to update' },\n summary: { type: 'string', description: 'Event title' },\n description: { type: 'string', description: 'Event description' },\n start: {\n type: 'object',\n description: 'Start time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T10:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-15\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n end: {\n type: 'object',\n description: 'End time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T11:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-16\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n attendees: { type: 'array', description: 'List of attendee objects with email field', items: { type: 'object', properties: { email: { type: 'string' } } } },\n location: { type: 'string', description: 'Event location' },\n },\n required: ['eventId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.write' },\n effects: ['Update:Event'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', default: 'primary' },\n secondary: [\n { name: 'attendees', source: { source: 'param' as const, param: 'attendees' }, type: 'participant' },\n ],\n },\n version: '1.0.0',\n },\n\n {\n action: 'calendar.event.delete',\n resource_type: 'calendar:event',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/calendar'],\n capability: 'calendar.write',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string' },\n eventId: { type: 'string', minLength: 1 },\n },\n required: ['eventId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.write' },\n effects: ['Delete:Event'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', default: 'primary' },\n },\n version: '1.0.0',\n },\n\n // ─── Jira Actions ───\n {\n action: 'jira.project.read',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n recent: { type: 'number' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:ProjectList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.board.read',\n resource_type: 'jira:board',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n projectKeyOrId: { type: 'string' },\n type: { type: 'string' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:BoardList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.sprint.read',\n resource_type: 'jira:sprint',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n boardId: { type: 'number', minimum: 1 },\n state: { type: 'string' },\n },\n required: ['boardId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:SprintList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'boardId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.list',\n resource_type: 'jira:sprint',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n sprintId: { type: 'number', minimum: 1 },\n maxResults: { type: 'number', minimum: 1, maximum: 100 },\n },\n required: ['sprintId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'sprintId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.search',\n resource_type: 'jira:issue',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n jql: { type: 'string', minLength: 1 },\n maxResults: { type: 'integer', minimum: 1, maximum: 100 },\n startAt: { type: 'integer', minimum: 0 },\n },\n required: ['jql'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'jql', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.worklog.read',\n resource_type: 'jira:issue',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Worklog'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.read',\n resource_type: 'jira:issue',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Issue'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.create',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n projectKey: { type: 'string', minLength: 1 },\n summary: { type: 'string', minLength: 1 },\n description: { type: 'string' },\n issueTypeName: { type: 'string', minLength: 1, description: 'Issue type name (default: Task)' },\n priority: { type: 'string' },\n assigneeAccountId: { type: 'string' },\n labels: { type: 'array', items: { type: 'string' } },\n },\n required: ['projectKey', 'summary'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Create:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKey' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.update',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n summary: { type: 'string' },\n description: { type: 'string' },\n priority: { type: 'string' },\n assigneeAccountId: { type: 'string' },\n labels: { type: 'array', items: { type: 'string' } },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Update:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.delete',\n resource_type: 'jira:project',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Delete:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.comment.create',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n body: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey', 'body'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Create:Comment'],\n // high: comments are publicly visible to all project members, consistent with jira.issue.update\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.comment.read',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'act_as'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Comment'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.transition',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n transitionId: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey', 'transitionId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Update:IssueStatus'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.transition.list',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'act_as'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Transition'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.batch.read',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n projectKeyOrId: { type: 'string' },\n boardId: { type: 'number' },\n sprintId: { type: 'number' },\n jql: { type: 'string' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:ProjectList', 'Read:BoardList', 'Read:SprintList', 'Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issuelink.create',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n typeName: { type: 'string', minLength: 1, description: 'Link type name (e.g. Blocks, Relates)' },\n inwardIssueKey: { type: 'string', minLength: 1 },\n outwardIssueKey: { type: 'string', minLength: 1 },\n commentBody: { type: 'string' },\n },\n required: ['typeName', 'inwardIssueKey', 'outwardIssueKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Create:IssueLink'],\n risk: 'high',\n target_bindings: {\n // 両 issue が touch されるが target_bindings は 1 つしか指定できないので\n // outwardIssueKey を主 binding として project_key を導出する。\n // 完全な制御をしたい場合は別途 inwardIssueKey 側も grant チェックする運用を要する。\n resource_id: { source: 'param' as const, param: 'outwardIssueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issuelink.delete',\n resource_type: 'jira:issuelink',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n linkId: { type: 'string', minLength: 1, description: 'Internal id of the issue link (from jira.issue.read fields.issuelinks[].id)' },\n },\n required: ['linkId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Delete:IssueLink'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'linkId' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issuelinktype.list',\n // workspace 全体のメタデータ取得なので、jira.project.read と同様 jira:project\n // resource として扱い、特定 project を要求しないことで全 viewer に許可する。\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:IssueLinkTypes'],\n risk: 'low',\n // workspace 全体のメタデータなので resource_id は常に未解決のまま\n // type-only match で評価する (required: false がその挙動)。input_schema には\n // 該当 param が無いため param 値は実行時に必ず undefined になる。\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n\n // ─── OS Actions (Local) ───\n {\n action: 'os.secret.read',\n resource_type: 'os:secret',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: [],\n input_schema: {\n type: 'object',\n properties: {\n file_path: { type: 'string', description: 'Path to the secret file (e.g., ~/projects/app/.env)' },\n },\n required: ['file_path'],\n additionalProperties: false,\n },\n effects: ['Read:SecretFile'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'file_path' },\n },\n version: '1.0.0',\n },\n {\n action: 'os.secret.write',\n resource_type: 'os:secret',\n required_relations: ['editor', 'admin', 'owner'],\n required_scopes: [],\n input_schema: {\n type: 'object',\n properties: {\n file_path: { type: 'string', description: 'Path to the secret file' },\n content: { type: 'string', description: 'Content to write' },\n },\n required: ['file_path', 'content'],\n additionalProperties: false,\n },\n effects: ['Write:SecretFile'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'file_path' },\n },\n version: '1.0.0',\n },\n {\n action: 'os.process.run',\n resource_type: 'os:process',\n required_relations: ['editor', 'admin', 'owner'],\n required_scopes: [],\n input_schema: {\n type: 'object',\n properties: {\n command: {\n type: 'array',\n items: { type: 'string' },\n description: 'Command and arguments to execute (e.g., [\"pnpm\", \"dev\"])',\n },\n working_directory: {\n type: 'string',\n description: 'Working directory for the process',\n },\n env_profile: {\n type: 'string',\n description: 'VESS env profile name to inject (e.g., \"app_dev\")',\n },\n timeout_seconds: {\n type: 'number',\n description: 'Max execution time in seconds (default: 300)',\n },\n },\n required: ['command'],\n additionalProperties: false,\n },\n effects: ['Execute:Process'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'command' },\n },\n version: '1.0.0',\n },\n ],\n capabilities: [\n {\n capability: 'slack.messaging.basic',\n description: 'Post, update, and delete messages in channels',\n includes: ['slack.message.post', 'slack.message.update', 'slack.message.delete'],\n version: '1.0.0',\n },\n {\n capability: 'slack.read.basic',\n description: 'Read channels, messages, and user info',\n includes: ['slack.channel.read', 'slack.user.read', 'slack.message.read', 'slack.message.read_paginated', 'slack.batch.read'],\n version: '1.0.0',\n },\n {\n capability: 'github.read.basic',\n description: 'Read issues from repositories',\n includes: ['github.issue.list', 'github.issue.read'],\n version: '1.0.0',\n },\n {\n capability: 'github.issues.triage',\n description: 'Create and update issues',\n includes: ['github.issue.create', 'github.issue.update'],\n version: '1.0.0',\n },\n {\n capability: 'gmail.read.basic',\n description: 'Read and search Gmail messages and labels',\n includes: ['gmail.message.search', 'gmail.message.read', 'gmail.label.read', 'gmail.batch.read'],\n version: '1.0.0',\n },\n {\n capability: 'gmail.compose',\n description: 'Send emails and create drafts via Gmail',\n includes: ['gmail.message.send', 'gmail.draft.create'],\n version: '1.0.0',\n },\n {\n capability: 'gmail.manage',\n description: 'Trash and permanently delete Gmail messages',\n includes: ['gmail.message.trash', 'gmail.message.delete'],\n version: '1.0.0',\n },\n {\n capability: 'calendar.read.basic',\n description: 'Read and list Google Calendar events',\n includes: ['calendar.event.list', 'calendar.event.read'],\n version: '1.0.0',\n },\n {\n capability: 'calendar.write',\n description: 'Create, update, and delete Google Calendar events',\n includes: ['calendar.event.create', 'calendar.event.update', 'calendar.event.delete'],\n version: '1.0.0',\n },\n {\n capability: 'jira.read.basic',\n description: 'Read Jira issues, projects, boards, sprints, and issue link types',\n includes: ['jira.project.read', 'jira.board.read', 'jira.sprint.read', 'jira.issue.list', 'jira.issue.search', 'jira.worklog.read', 'jira.issue.read', 'jira.batch.read', 'jira.comment.read', 'jira.transition.list', 'jira.issuelinktype.list'],\n version: '1.0.0',\n },\n {\n capability: 'jira.write.basic',\n description: 'Create, update, delete Jira issues, and manage issue links',\n includes: ['jira.issue.create', 'jira.issue.update', 'jira.issue.delete', 'jira.comment.create', 'jira.issue.transition', 'jira.issuelink.create', 'jira.issuelink.delete'],\n version: '1.0.0',\n },\n ],\n}\n","/**\n * Unified ResourceType definitions — single source of truth.\n *\n * Format: `provider:resource` (e.g., 'slack:channel', 'github:repo')\n * For nested resources: `provider:service:resource` (e.g., 'google:drive:file')\n */\n\n/** All known resource types in canonical `provider:resource` format */\nexport const RESOURCE_TYPES = {\n // Slack\n SLACK_CHANNEL: 'slack:channel',\n SLACK_USER: 'slack:user',\n SLACK_WORKSPACE: 'slack:workspace',\n\n // GitHub\n GITHUB_REPO: 'github:repo',\n GITHUB_ORG: 'github:org',\n GITHUB_ISSUE: 'github:issue',\n\n // Google Drive\n GOOGLE_DRIVE_FILE: 'google:drive:file',\n GOOGLE_DRIVE_FOLDER: 'google:drive:folder',\n\n // Gmail\n GMAIL_THREAD: 'gmail:thread',\n GMAIL_LABEL: 'gmail:label',\n\n // Jira\n JIRA_PROJECT: 'jira:project',\n JIRA_BOARD: 'jira:board',\n JIRA_ISSUE: 'jira:issue',\n JIRA_SPRINT: 'jira:sprint',\n\n // OS (local)\n OS_SECRET: 'os:secret',\n OS_PROCESS: 'os:process',\n\n // Wildcard\n ANY: '*',\n} as const\n\nexport type UnifiedResourceType = typeof RESOURCE_TYPES[keyof typeof RESOURCE_TYPES]\n\n/**\n * Legacy CamelCase → canonical resource type mapping.\n * Used for converting Action Registry's resource_type field.\n */\nexport const LEGACY_RESOURCE_TYPE_MAP: Readonly<Record<string, string>> = {\n // Action Registry CamelCase format\n SlackChannel: RESOURCE_TYPES.SLACK_CHANNEL,\n GitHubRepo: RESOURCE_TYPES.GITHUB_REPO,\n DriveFile: RESOURCE_TYPES.GOOGLE_DRIVE_FILE,\n JiraIssue: RESOURCE_TYPES.JIRA_ISSUE,\n JiraProject: RESOURCE_TYPES.JIRA_PROJECT,\n JiraBoard: RESOURCE_TYPES.JIRA_BOARD,\n JiraSprint: RESOURCE_TYPES.JIRA_SPRINT,\n\n // Legacy GrantResourceType format (already canonical — identity mapping)\n 'slack:channel': RESOURCE_TYPES.SLACK_CHANNEL,\n 'slack:user': RESOURCE_TYPES.SLACK_USER,\n 'slack:workspace': RESOURCE_TYPES.SLACK_WORKSPACE,\n 'github:repo': RESOURCE_TYPES.GITHUB_REPO,\n 'github:org': RESOURCE_TYPES.GITHUB_ORG,\n 'github:issue': RESOURCE_TYPES.GITHUB_ISSUE,\n 'jira:project': RESOURCE_TYPES.JIRA_PROJECT,\n 'jira:board': RESOURCE_TYPES.JIRA_BOARD,\n 'jira:issue': RESOURCE_TYPES.JIRA_ISSUE,\n 'jira:sprint': RESOURCE_TYPES.JIRA_SPRINT,\n 'os:secret': RESOURCE_TYPES.OS_SECRET,\n 'os:process': RESOURCE_TYPES.OS_PROCESS,\n\n // Legacy formats with old provider prefixes\n 'gh:repo': RESOURCE_TYPES.GITHUB_REPO,\n 'drive:file': RESOURCE_TYPES.GOOGLE_DRIVE_FILE,\n 'drive:folder': RESOURCE_TYPES.GOOGLE_DRIVE_FOLDER,\n 'google:gmail:thread': RESOURCE_TYPES.GMAIL_THREAD,\n 'google:gmail:label': RESOURCE_TYPES.GMAIL_LABEL,\n}\n\n/**\n * Resolve a resource type string to its canonical form.\n *\n * Handles CamelCase (SlackChannel), legacy prefixes (gh:repo, drive:file),\n * and already-canonical formats (slack:channel).\n */\nexport function resolveResourceType(resourceType: string): string {\n return LEGACY_RESOURCE_TYPE_MAP[resourceType] ?? resourceType\n}\n","/**\n * Centralized action utilities — single source of truth.\n *\n * Canonical action format is `provider.resource.operation` (dot format).\n * Legacy `provider:resource.operation` (colon format) is supported for\n * backward compatibility with existing grants.\n */\n\nimport { resolveProvider } from './providers'\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Canonicalize an action name.\n *\n * Returns the canonical dot format: `provider.resource.operation`.\n * If action already contains the provider prefix, returns as-is.\n *\n * @param provider - Provider name (e.g., 'slack', 'github')\n * @param action - Action name (e.g., 'message.post')\n * @returns Canonical action string (e.g., 'slack.message.post')\n */\nexport function canonicalizeAction(provider: string, action: string): string {\n const canonicalProvider = resolveProvider(provider)\n // If action already starts with provider prefix, return as-is\n if (action.startsWith(`${canonicalProvider}.`)) {\n return action\n }\n return `${canonicalProvider}.${action}`\n}\n\n/**\n * Get aliases for a canonical action.\n *\n * Returns the legacy colon format for backward compatibility.\n */\nexport function getActionAliases(canonicalAction: string): string[] {\n // Generate colon-format alias: \"slack.message.post\" → \"slack:message.post\"\n const dotIdx = canonicalAction.indexOf('.')\n if (dotIdx > 0) {\n const provider = canonicalAction.substring(0, dotIdx)\n const rest = canonicalAction.substring(dotIdx + 1)\n return [`${provider}:${rest}`]\n }\n return []\n}\n\n/**\n * Get all equivalent forms of an action with provider prefix.\n *\n * Returns both dot format (canonical) and colon format (legacy).\n */\nexport function getAllActionForms(provider: string, action: string): string[] {\n const canonicalProvider = resolveProvider(provider)\n const forms: string[] = []\n\n // Dot format (canonical): provider.resource.operation\n if (action.startsWith(`${canonicalProvider}.`)) {\n forms.push(action)\n // Also add colon format\n const rest = action.substring(canonicalProvider.length + 1)\n forms.push(`${canonicalProvider}:${rest}`)\n } else {\n forms.push(`${canonicalProvider}.${action}`)\n forms.push(`${canonicalProvider}:${action}`)\n }\n\n return forms\n}\n\n/**\n * Check if two action strings refer to the same action.\n *\n * Handles both dot and colon separators.\n */\nexport function isActionEquivalent(action1: string, action2: string): boolean {\n if (action1 === action2) return true\n\n const parse = (a: string) => {\n // Try colon first, then dot\n const colonIdx = a.indexOf(':')\n if (colonIdx > 0) {\n return { provider: a.substring(0, colonIdx), action: a.substring(colonIdx + 1) }\n }\n const dotIdx = a.indexOf('.')\n if (dotIdx > 0) {\n return { provider: a.substring(0, dotIdx), action: a.substring(dotIdx + 1) }\n }\n return { provider: '', action: a }\n }\n\n const p1 = parse(action1)\n const p2 = parse(action2)\n\n const np1 = resolveProvider(p1.provider)\n const np2 = resolveProvider(p2.provider)\n\n return np1 === np2 && p1.action === p2.action\n}\n","/**\n * MCP action name normalization — single source of truth.\n *\n * Valid action names are derived from ACTION_REGISTRY, ensuring consistency\n * between grant definitions, MCP tool schemas, and tool adapter implementations.\n *\n * This module provides normalization logic to handle common misformats from LLM clients:\n * - Double prefix: \"calendar.calendar.event.list\" → \"calendar.event.list\"\n * - Colon format: \"slack:message.post\" → \"slack.message.post\"\n * - Missing prefix: \"message.post\" → \"slack.message.post\"\n *\n * `packages/remote-mcp` imports from here to avoid duplication.\n */\n\nimport { ACTION_REGISTRY } from './action-registry-json'\n\n/**\n * Derive valid action names by provider from ACTION_REGISTRY.\n * This ensures VALID_MCP_ACTIONS is always in sync with the registry.\n */\nfunction buildValidActions(): Record<string, string[]> {\n const result: Record<string, string[]> = {}\n for (const entry of ACTION_REGISTRY.actions) {\n const dotIdx = entry.action.indexOf('.')\n if (dotIdx < 0) continue\n const provider = entry.action.substring(0, dotIdx)\n if (!result[provider]) result[provider] = []\n result[provider].push(entry.action)\n }\n return result\n}\n\n/**\n * Valid MCP-facing action names by tool, derived from ACTION_REGISTRY.\n * These are the canonical names that LLM clients should send and that\n * the API grant system uses for permission matching.\n */\nexport const VALID_MCP_ACTIONS: Record<string, string[]> = buildValidActions()\n\n/**\n * All valid MCP tool names.\n */\nexport const VALID_MCP_TOOLS = Object.keys(VALID_MCP_ACTIONS) as string[]\n\n/**\n * Get all valid MCP action names across all tools.\n */\nexport function getAllValidMcpActionNames(): string[] {\n return Object.values(VALID_MCP_ACTIONS).flat()\n}\n\n/**\n * Get valid MCP action names for a specific tool.\n * @returns Array of action names, or empty array if tool is unknown.\n */\nexport function getValidMcpActionNames(toolName: string): string[] {\n return VALID_MCP_ACTIONS[toolName] ?? []\n}\n\n/**\n * Normalize an MCP action name to canonical `provider.resource.operation` format.\n *\n * Handles common misformats from LLM clients:\n * 1. Already valid → return as-is\n * 2. Double prefix: \"calendar.calendar.event.list\" → strip leading \"toolName.\" → \"calendar.event.list\"\n * 3. Colon format: \"slack:message.post\" → replace \":\" with \".\" → \"slack.message.post\"\n * 4. Missing prefix: \"message.post\" → prepend \"toolName.\" → \"slack.message.post\"\n *\n * @param toolName - Tool name (e.g., \"slack\", \"calendar\")\n * @param actionName - Possibly misformatted action name from LLM client\n * @returns Normalized action name, or the original if no valid match found\n */\nexport function normalizeMcpActionName(toolName: string, actionName: string): string {\n if (!actionName) return ''\n if (!toolName) return actionName\n\n const validActions = VALID_MCP_ACTIONS[toolName]\n if (!validActions) return actionName\n\n // 1. Direct match — already correct\n if (validActions.includes(actionName)) {\n return actionName\n }\n\n // 2. Double prefix: \"calendar.calendar.event.list\" → strip \"calendar.\" → \"calendar.event.list\"\n if (actionName.startsWith(`${toolName}.`)) {\n const stripped = actionName.substring(toolName.length + 1)\n if (validActions.includes(stripped)) {\n return stripped\n }\n }\n\n // 3. Colon format: \"slack:message.post\" → \"slack.message.post\"\n if (actionName.includes(':')) {\n const dotFormat = actionName.replace(':', '.')\n if (validActions.includes(dotFormat)) {\n return dotFormat\n }\n }\n\n // 4. Missing prefix: \"message.post\" → \"slack.message.post\"\n if (!actionName.startsWith(`${toolName}.`)) {\n const withPrefix = `${toolName}.${actionName}`\n if (validActions.includes(withPrefix)) {\n return withPrefix\n }\n }\n\n // 5. No match — return original\n return actionName\n}\n","/**\n * Cross-package constants for the reauth pipeline.\n *\n * These string literals are contract-level identifiers shared between:\n * - api (`tool-auth.service.ts`, `token-refresh.service.ts`)\n * - remote-mcp (`mcp-format-result.ts`)\n * - agentd (`gateway-client.ts`, `credential-errors.ts`, `execution-engine.ts`)\n *\n * Hard-coding them at each site made typo bugs silent. Centralizing here\n * means any renames surface as a compile error on every import site.\n */\n\n/**\n * Value for `ToolInvokeResponse.metadata.action` when the api signals a\n * revoked/expired OAuth token. Consumers branch on this to render a reauth\n * prompt (Slack DM card, CLI authUrl, etc.) instead of treating the response\n * as a normal error.\n */\nexport const REAUTH_REQUIRED_ACTION = 'reauth_required' as const\n\n/**\n * Value for `ToolInvokeResult.metadata.action` when an action needs RAR\n * approval (Cedar `RequireApproval`). Consumers (remote-mcp formatter)\n * branch on this to promote `{ approvalUrl, requestId }` into the MCP\n * `structuredContent` / `_meta.aidentity` channel so the URL reaches the\n * client on the FIRST call_tool, not only via a separate request_permission.\n */\nexport const APPROVAL_REQUIRED_ACTION = 'approval_required' as const\n\n/**\n * Error codes emitted by agentd's `gateway-client.invokeTool` to classify\n * failure modes for the ExecutionEngine to branch on. Kept as a const object\n * rather than an enum so it serializes cleanly across the wire and in logs.\n */\nexport const GATEWAY_ERROR_CODE = {\n /** Upstream OAuth token is revoked — the user must re-auth at the SaaS provider. */\n REAUTH_REQUIRED: 'REAUTH_REQUIRED',\n /** Local VC/VP is invalid (expired, malformed, signature mismatch). Try VC reissuance. */\n CREDENTIAL_INVALID: 'CREDENTIAL_INVALID',\n /** VC allowed a different resource than the request targeted. Try a new approval. */\n RESOURCE_MISMATCH: 'RESOURCE_MISMATCH',\n /**\n * Cedar `forbid` rule fired (HTTP 403 `policy_forbidden`) — a HARD deny that\n * approval CANNOT lift (e.g. a timeWindow forbid outside business hours).\n * The ExecutionEngine surfaces this as a TERMINAL denial with NO approval\n * prompt, unlike CREDENTIAL_INVALID / RESOURCE_MISMATCH which re-request.\n */\n POLICY_FORBIDDEN: 'POLICY_FORBIDDEN',\n} as const\n\nexport type GatewayErrorCode =\n (typeof GATEWAY_ERROR_CODE)[keyof typeof GATEWAY_ERROR_CODE]\n","export interface ActionParamDisplay {\n label: string\n value: string\n}\n\n/**\n * displayFields 1 項目の表示元。\n *\n * - `key` — params[key] を読む単純なケース (string / number など)\n * - `extract` — alias / nested / null など複合 shape を吸収する場合 (jira.* など)\n *\n * extract を指定したケースは key を併用してもよい (fallback として使われる)。\n * 戻り値が undefined / null (Unassign 表現の null は除く) のときは表示しない。\n */\ninterface ActionDisplayField {\n label: string\n key?: string\n extract?: (params: Record<string, any>) => unknown\n}\n\ninterface ActionDisplayConfig {\n summaryTemplate: (params: Record<string, any>) => string\n displayFields: ActionDisplayField[]\n}\n\n/**\n * jira 用: agent が送る 4 つの assignee shape から表示値を抽出する。\n * null は「未アサイン (Unassign)」として明示表示するため特別な戻り値で示す。\n */\nfunction extractJiraAssigneeDisplay(params: Record<string, any>): string | null | undefined {\n const pickFromShape = (value: unknown): string | null | undefined => {\n if (value === null) return null\n if (typeof value === 'string') return value.length > 0 ? value : undefined\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const id = (value as Record<string, unknown>).accountId\n if (id === null) return null\n if (typeof id === 'string' && id.length > 0) return id\n }\n return undefined\n }\n // priority: canonical > top-level alias > nested fields\n if ('assigneeAccountId' in params) {\n const v = params.assigneeAccountId\n if (v === null) return null\n if (typeof v === 'string' && v.length > 0) return v\n }\n if ('assignee' in params) {\n const picked = pickFromShape(params.assignee)\n if (picked !== undefined) return picked\n }\n const fields = params.fields as Record<string, unknown> | undefined\n if (fields && typeof fields === 'object' && 'assignee' in fields) {\n const picked = pickFromShape(fields.assignee)\n if (picked !== undefined) return picked\n }\n return undefined\n}\n\n/**\n * jira 用: nested `fields.X` 形式と top-level canonical の両方をカバーする\n * 汎用 extractor。\n */\nfunction jiraField<T = unknown>(\n params: Record<string, any>,\n topLevelKeys: string[],\n nestedKey: string,\n nestedExtractor?: (v: any) => T,\n): T | undefined {\n for (const k of topLevelKeys) {\n if (params[k] !== undefined && params[k] !== null) return params[k] as T\n }\n const fields = params.fields as Record<string, unknown> | undefined\n if (fields && typeof fields === 'object') {\n const v = fields[nestedKey]\n if (v !== undefined && v !== null) {\n return nestedExtractor ? nestedExtractor(v) : (v as T)\n }\n }\n return undefined\n}\n\nconst ACTION_DISPLAY_CONFIGS: Record<string, ActionDisplayConfig> = {\n 'slack.message.post': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.channel) parts.push(p.channel + ':')\n if (p.text) parts.push(String(p.text))\n return parts.join(' ')\n },\n displayFields: [\n { key: 'channel', label: 'Channel' },\n { key: 'text', label: 'Message' },\n ],\n },\n 'gmail.message.send': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.to) parts.push(`To: ${p.to}`)\n if (p.subject) parts.push(`Subject: ${p.subject}`)\n return parts.join(', ')\n },\n displayFields: [\n { key: 'to', label: 'To' },\n { key: 'subject', label: 'Subject' },\n { key: 'body', label: 'Body' },\n ],\n },\n 'gmail.draft.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.to) parts.push(`To: ${p.to}`)\n if (p.subject) parts.push(`Subject: ${p.subject}`)\n return parts.join(', ')\n },\n displayFields: [\n { key: 'to', label: 'To' },\n { key: 'subject', label: 'Subject' },\n { key: 'body', label: 'Body' },\n ],\n },\n 'calendar.event.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.summary) parts.push(p.summary)\n if (p.start) parts.push(`(${formatValue(p.start)})`)\n return parts.join(' ')\n },\n displayFields: [\n { key: 'summary', label: 'Event' },\n { key: 'start', label: 'Start' },\n { key: 'end', label: 'End' },\n { key: 'attendees', label: 'Attendees' },\n ],\n },\n 'calendar.event.update': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.summary) parts.push(p.summary)\n if (p.start) parts.push(`(${formatValue(p.start)})`)\n return parts.join(' ')\n },\n displayFields: [\n { key: 'summary', label: 'Event' },\n { key: 'start', label: 'Start' },\n { key: 'end', label: 'End' },\n { key: 'attendees', label: 'Attendees' },\n ],\n },\n 'jira.issue.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n const projectKey = jiraField<string>(p, ['projectKey', 'project'], 'project', (v: any) =>\n typeof v === 'string' ? v : v?.key,\n )\n const summary = jiraField<string>(p, ['summary'], 'summary')\n if (projectKey) parts.push(`${projectKey}:`)\n if (summary) parts.push(summary)\n return parts.join(' ')\n },\n // AIDENTITY-54: nested `fields.X` 形式と top-level canonical の両方を\n // 拾えるよう extract を使う。assignee は null (unassign) も表示。\n // legacy alias (project / issuetype 等) も top-level 候補に含めて後方互換を保つ。\n displayFields: [\n {\n label: 'Project',\n extract: (p) =>\n jiraField<string>(p, ['projectKey', 'project'], 'project', (v: any) =>\n typeof v === 'string' ? v : v?.key,\n ),\n },\n {\n label: 'Type',\n extract: (p) =>\n jiraField<string>(p, ['issueTypeName', 'issueType', 'issuetype'], 'issuetype', (v: any) =>\n typeof v === 'string' ? v : v?.name,\n ),\n },\n { label: 'Summary', extract: (p) => jiraField<string>(p, ['summary'], 'summary') },\n { label: 'Description', extract: (p) => jiraField(p, ['description'], 'description') },\n { label: 'Priority', extract: (p) =>\n jiraField<string>(p, ['priority'], 'priority', (v: any) =>\n typeof v === 'string' ? v : v?.name,\n ),\n },\n { label: 'Assignee', extract: extractJiraAssigneeDisplay },\n { label: 'Labels', extract: (p) => jiraField(p, ['labels'], 'labels') },\n ],\n },\n 'jira.issue.update': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n const key = (p.issueIdOrKey ?? p.issueKey) as string | undefined\n const summary = jiraField<string>(p, ['summary'], 'summary')\n if (key) parts.push(`${key}:`)\n if (summary) parts.push(summary)\n return parts.join(' ')\n },\n displayFields: [\n // canonical は issueIdOrKey、agent が issueKey で送ってくる旧仕様も拾う。\n { label: 'Issue', extract: (p) => (p.issueIdOrKey ?? p.issueKey) },\n { label: 'Summary', extract: (p) => jiraField<string>(p, ['summary'], 'summary') },\n { label: 'Description', extract: (p) => jiraField(p, ['description'], 'description') },\n { label: 'Priority', extract: (p) =>\n jiraField<string>(p, ['priority'], 'priority', (v: any) =>\n typeof v === 'string' ? v : v?.name,\n ),\n },\n // AIDENTITY-54: top-level alias (string / object) と null (unassign) も解決。\n { label: 'Assignee', extract: extractJiraAssigneeDisplay },\n { label: 'Labels', extract: (p) => jiraField(p, ['labels'], 'labels') },\n ],\n },\n // AIDENTITY-65: comment 本体は string と ADF document の両方を受けるため、\n // formatValue 側の ADF ハンドリング (extractFirstAdfText) に任せて key 指定で OK。\n 'jira.comment.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.issueIdOrKey) parts.push(`${p.issueIdOrKey}:`)\n if (p.body) parts.push(typeof p.body === 'string' ? p.body : '[ADF]')\n return parts.join(' ')\n },\n displayFields: [\n { key: 'issueIdOrKey', label: 'Issue' },\n { key: 'body', label: 'Comment' },\n ],\n },\n // AIDENTITY-65: API enricher が 'Link' label を upsert で書き換える。\n 'jira.issuelink.delete': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.linkId) parts.push(`Delete link ${p.linkId}`)\n return parts.join(' ')\n },\n displayFields: [\n { key: 'linkId', label: 'Link' },\n ],\n },\n}\n\nfunction truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text\n return text.slice(0, maxLength - 3) + '...'\n}\n\nfunction formatValue(value: unknown): string {\n if (value === undefined) return ''\n // AIDENTITY-54: null は「unset / 未設定 / 削除」意図として、空文字ではなく\n // 明示的なラベルで表示する (assignee=null は unassign、その他 field も同様)。\n // display config 側で意味付けを変えたい場合は extract で string 化することも可能。\n if (value === null) return '(unset)'\n if (Array.isArray(value)) {\n return value.map(item => {\n if (item && typeof item === 'object') {\n // e.g. attendees: [{email: \"a@b.com\"}, {email: \"c@d.com\"}] → \"a@b.com, c@d.com\"\n const email = (item as Record<string, unknown>).email\n if (email) return String(email)\n return JSON.stringify(item)\n }\n return String(item)\n }).join(', ')\n }\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n // Google Calendar datetime object: {dateTime: \"...\", timeZone: \"...\"} → \"2025-01-15T10:00:00 (Asia/Tokyo)\"\n if (obj.dateTime) {\n return obj.timeZone ? `${obj.dateTime} (${obj.timeZone})` : String(obj.dateTime)\n }\n // Google Calendar date object: {date: \"2025-01-15\"} → \"2025-01-15\"\n if (obj.date) return String(obj.date)\n // ADF document (Atlassian Jira description / comment): 最初の paragraph の\n // テキストを軽く抽出して読みやすく表示する。完全な ADF 描画は approve UI 側に\n // 任せる発想もあるが、現状の plain textContent では JSON.stringify で読みにくい。\n if (obj.type === 'doc' && Array.isArray(obj.content)) {\n const firstText = extractFirstAdfText(obj.content as unknown[])\n if (firstText) {\n const moreCount = obj.content.length - 1\n const more = moreCount > 0 ? ` … (+${moreCount} block${moreCount > 1 ? 's' : ''})` : ''\n return `${firstText}${more}`\n }\n return '(ADF document)'\n }\n return JSON.stringify(value)\n }\n return String(value)\n}\n\n/** ADF document の最初の paragraph / heading から先頭テキストを抜き出す。 */\nfunction extractFirstAdfText(nodes: unknown[]): string {\n for (const node of nodes) {\n if (!node || typeof node !== 'object') continue\n const n = node as Record<string, unknown>\n if (n.type === 'paragraph' || n.type === 'heading') {\n const inner = (n.content as unknown[]) ?? []\n for (const child of inner) {\n if (child && typeof child === 'object') {\n const c = child as Record<string, unknown>\n if (c.type === 'text' && typeof c.text === 'string') return c.text\n }\n }\n }\n }\n return ''\n}\n\nexport const ACTION_PARAMS_MAX_SIZE = 10_000\n\nexport function generateActionSummary(\n action: string,\n params: Record<string, any> | undefined | null,\n maxLength = 50,\n): string {\n if (!params || Object.keys(params).length === 0) return ''\n\n const config = ACTION_DISPLAY_CONFIGS[action]\n if (config) {\n const raw = config.summaryTemplate(params)\n return raw ? truncate(raw, maxLength) : ''\n }\n\n for (const [key, val] of Object.entries(params)) {\n if (val !== null && val !== undefined && typeof val !== 'object') {\n return truncate(`${key}: ${String(val)}`, maxLength)\n }\n }\n return ''\n}\n\nexport function generateActionParamsDisplay(\n action: string,\n params: Record<string, any> | undefined | null,\n): ActionParamDisplay[] {\n if (!params || Object.keys(params).length === 0) return []\n\n const config = ACTION_DISPLAY_CONFIGS[action]\n if (config) {\n return config.displayFields\n .map(f => {\n // extract が優先。なければ key 経由 (旧仕様)。\n const raw = f.extract ? f.extract(params) : f.key ? params[f.key] : undefined\n return { label: f.label, raw }\n })\n // 値が undefined のフィールドは表示しない。null は許可 (formatValue で\n // \"(unset)\" として表示される — 「明示的に消した」意味を残す)。\n .filter(item => item.raw !== undefined)\n .map(item => ({ label: item.label, value: formatValue(item.raw) }))\n }\n\n return Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== null)\n .slice(0, 3)\n .map(([key, val]) => ({\n label: key,\n value: formatValue(val),\n }))\n}\n","import {\n TargetBindings,\n ResolvedTargets,\n PolicyTarget,\n BindingSource,\n ParamBindingSource,\n} from '../types/target-binding'\n\n/**\n * Regex to extract project key prefix from a Jira issue key (e.g., \"PROJ-123\" → \"PROJ\").\n * Requires 2+ uppercase characters — single-letter keys like \"A-1\" are rejected\n * (Jira project keys must be at least 2 characters).\n */\nconst PROJECT_KEY_PATTERN = /^([A-Z][A-Z0-9_]+)-\\d+$/\n\n/**\n * Extract the project key from a Jira issue key.\n * Returns the project prefix (e.g., \"AIDENTITY\" from \"AIDENTITY-35\") or null if not a valid issue key.\n *\n * @remarks Project keys must be at least 2 uppercase characters, matching Jira's requirement.\n * Single-letter keys (e.g., \"A-1\") return null.\n */\nexport function extractProjectKey(value: string): string | null {\n const match = value.match(PROJECT_KEY_PATTERN)\n return match ? match[1] : null\n}\n\n/**\n * TargetResolver — extracts resource IDs and secondary targets from tool parameters.\n *\n * Pure function with no external dependencies (NestJS, DB, etc.).\n * Used by the API layer to populate PolicyInput.request.resource.id and targets[].\n */\nexport class TargetResolver {\n /**\n * Resolve target bindings against tool invocation parameters.\n *\n * @param bindings - Target binding declarations from ACTION_REGISTRY\n * @param params - Tool invocation parameters\n * @param context - Optional pre-resolved context values (e.g., resource_id from URL)\n */\n resolve(\n bindings: TargetBindings,\n params: Record<string, unknown>,\n context?: Record<string, string>,\n ): ResolvedTargets {\n const isRequired = bindings.resource_id.required !== false\n\n // Resolve primary resource_id\n const { value, values } = this.resolveBinding(bindings.resource_id, params, context)\n\n // Resolve secondary targets (alpha: collect values but not evaluated by policy)\n const targets = this.resolveSecondary(bindings.secondary, params, context)\n\n return {\n resource_id: value,\n resource_id_required: isRequired,\n resource_id_values: values,\n targets,\n }\n }\n\n private resolveBinding(\n binding: BindingSource,\n params: Record<string, unknown>,\n context?: Record<string, string>,\n ): { value: string | null; values?: string[] } {\n if (binding.source === 'context') {\n const val = context?.[binding.key]\n if (typeof val !== 'string') return { value: null }\n return { value: val }\n }\n\n // source === 'param'\n const paramBinding = binding as ParamBindingSource\n let rawValue = params[paramBinding.param]\n\n // Fallback to alternative param name if primary is missing\n if (rawValue == null && paramBinding.fallback_param) {\n rawValue = params[paramBinding.fallback_param]\n }\n\n // Apply default if missing\n if (rawValue == null && paramBinding.default != null) {\n rawValue = paramBinding.default\n }\n\n // Type validation: must be string\n if (rawValue == null) return { value: null }\n if (typeof rawValue !== 'string') return { value: null }\n\n // Apply derive transformation\n let strValue: string = rawValue\n if (paramBinding.derive === 'project_key') {\n strValue = extractProjectKey(strValue) ?? strValue\n }\n\n // Multi-value handling\n if (paramBinding.multi) {\n const separator = paramBinding.separator ?? ','\n const values = strValue.split(separator).map((v: string) => v.trim()).filter((v: string) => v.length > 0)\n return {\n value: values[0] ?? null,\n values,\n }\n }\n\n return { value: strValue }\n }\n\n private resolveSecondary(\n secondary: TargetBindings['secondary'],\n params: Record<string, unknown>,\n context?: Record<string, string>,\n ): PolicyTarget[] {\n if (!secondary || secondary.length === 0) return []\n\n const targets: PolicyTarget[] = []\n for (const binding of secondary) {\n const { value, values } = this.resolveBinding(binding.source, params, context)\n if (value == null) continue\n\n targets.push({\n name: binding.name,\n values: values ?? [value],\n })\n }\n return targets\n }\n}\n","import { ACTION_REGISTRY } from '../registry/action-registry-json'\nimport { indexActions } from '../registry/action-registry'\n\nconst actionIndex = indexActions({\n registry_version: ACTION_REGISTRY.registry_version,\n actions: ACTION_REGISTRY.actions as any,\n})\n\n/**\n * Determine if an action is a write action based on ACTION_REGISTRY effects and risk.\n * Uses effects (Create/Update/Delete/Write/Execute) as primary signal,\n * falls back to risk level (medium/high = write) for unknown actions.\n */\nexport function isWriteAction(action: string): boolean {\n const meta = actionIndex.get(action)\n if (!meta) {\n // Unknown action: treat as write (safe default)\n return true\n }\n\n // Check effects for write semantics\n const writeEffectPrefixes = ['Create:', 'Update:', 'Delete:', 'Write:', 'Execute:']\n if (meta.effects?.some((e: string) => writeEffectPrefixes.some(p => e.startsWith(p)))) {\n return true\n }\n\n // Fallback: medium/high/critical risk = write\n return meta.risk === 'medium' || meta.risk === 'high' || meta.risk === 'critical'\n}\n\n/**\n * Pre-computed list of all write action names from ACTION_REGISTRY.\n * Used for SQL queries where per-row function calls are not practical.\n * Must be re-generated if ACTION_REGISTRY changes (compile-time constant).\n */\nexport const WRITE_ACTION_NAMES: string[] = ACTION_REGISTRY.actions\n .filter((a: any) => isWriteAction(a.action))\n .map((a: any) => a.action)\n","import { UserTier, TierLimits, TIER_LIMITS } from '../types/tier'\n\n/**\n * Check if a tier limit value represents unlimited.\n * In TIER_LIMITS, -1 is used to represent unlimited values.\n */\nexport function isUnlimited(value: number): boolean {\n return value < 0\n}\n\n/**\n * Safely resolve a tier string to a valid UserTier, defaulting to 'free'.\n */\nexport function resolveUserTier(tier: string | undefined | null): UserTier {\n if (tier && tier in TIER_LIMITS) {\n return tier as UserTier\n }\n return 'free'\n}\n\n/**\n * Get tier limits for a user's tier, with safe fallback to free tier.\n */\nexport function getTierLimits(tier: string | undefined | null): TierLimits {\n return TIER_LIMITS[resolveUserTier(tier)]\n}\n","/**\n * フリーメール / コンシューマ向けメールドメインのリスト。\n * grant の internalDomains で「ドメイン全体ワイルドカード (*@<freemail>)」を\n * 許可することを禁止するために使う (個別アドレス x@gmail.com は許可)。\n * 理由: *@gmail.com を「社内ドメイン」として自動許可すると、全 Gmail ユーザー\n * 宛が無条件許可になり危険。\n *\n * 網羅性は完璧でなくてよい (主要なもの)。後から追加可能な Set 構造。\n */\nexport const FREEMAIL_DOMAINS: ReadonlySet<string> = new Set([\n 'gmail.com',\n 'googlemail.com',\n 'outlook.com',\n 'hotmail.com',\n 'live.com',\n 'yahoo.com',\n 'yahoo.co.jp',\n 'ymail.com',\n 'icloud.com',\n 'me.com',\n 'mac.com',\n 'aol.com',\n 'protonmail.com',\n 'proton.me',\n 'pm.me',\n 'gmx.com',\n 'gmx.net',\n 'mail.com',\n 'zoho.com',\n 'yandex.com',\n // 日本の主要キャリア/フリーメール\n 'docomo.ne.jp',\n 'ezweb.ne.jp',\n 'au.com',\n 'softbank.ne.jp',\n 'i.softbank.jp',\n 'nifty.com',\n 'so-net.ne.jp',\n 'biglobe.ne.jp',\n])\n\n/** ドメインがフリーメールか判定 (小文字化して比較)。 */\nexport function isFreemailDomain(domain: string): boolean {\n return FREEMAIL_DOMAINS.has(domain.trim().toLowerCase())\n}\n","import { createHash } from 'crypto'\n\n/**\n * P1-A14a-1 / Threat Model S4 — canonical-string + signature-header\n * helpers for HMAC body signing of internal HTTP requests.\n *\n * Pure module: no NestJS, no I/O, no side effects. SDK is the\n * single source of truth (P1-A14a-2d) — api / remote-mcp /\n * slack-bot all import from `@vess-id/ai-identity`.\n *\n * Header format (Q1 = A, Stripe-style versioned):\n * X-Internal-Signature: v1=<keyId>:<unixSeconds>:<base64(hmac)>\n *\n * Canonical string (Q2 = A, no header inclusion):\n * ${METHOD.toUpperCase()}\\n${path}\\n${unixSeconds}\\n${sha256Hex(rawBody)}\n *\n * Replay window (Q3 = A): 300 seconds — enforced by the api guard,\n * not here. This module is responsible for *constructing* the\n * canonical string and *parsing* the header; freshness is policy.\n */\n\nexport const SIGNATURE_HEADER = 'x-internal-signature'\nexport const SIGNATURE_VERSION_PREFIX = 'v1='\n\n/**\n * SHA-256 hex digest of an arbitrary buffer or string. Hex (not\n * base64) so the canonical string is URL-safe and grep-friendly in\n * logs if a future debug session ever needs to reconstruct it\n * server-side.\n */\nexport function sha256Hex(input: Buffer | string): string {\n return createHash('sha256').update(input).digest('hex')\n}\n\n/**\n * Build the canonical string that gets HMAC'd. The components are\n * separated by `\\n` because no legitimate input contains `\\n` (the\n * method is uppercase ASCII, the path is URL-encoded by the caller,\n * the timestamp is digits, the body hash is hex). Using `\\n` as\n * separator avoids ambiguity that delimiters like `:` would\n * introduce when the path contains a colon.\n *\n * Whitespace is NOT trimmed — input must be exactly what will land\n * on the wire. Caller controls case and encoding.\n */\nexport function buildCanonicalString(args: {\n method: string\n path: string\n unixSeconds: number\n rawBody: Buffer | string\n}): string {\n const { method, path, unixSeconds, rawBody } = args\n return [method.toUpperCase(), path, String(unixSeconds), sha256Hex(rawBody)].join('\\n')\n}\n\n/** Shape of a parsed `X-Internal-Signature` header. */\nexport interface ParsedSignature {\n /** Identifier of the signing key (e.g. `'mcp-v2'`). */\n keyId: string\n /** Unix epoch seconds at signing time. */\n unixSeconds: number\n /** Base64-encoded HMAC-SHA256 digest. */\n signature: string\n}\n\n/**\n * Parse a `X-Internal-Signature` header value. Returns `null` for\n * any malformed shape rather than throwing — the api guard converts\n * `null` to a `401 Unauthorized` so a malformed header never\n * triggers a `500`.\n *\n * Accepted: `v1=<keyId>:<digits>:<base64>`\n *\n * Defensive checks:\n * - Must start with `v1=` (Q1: explicit version prefix)\n * - keyId / signature must be non-empty after split\n * - timestamp must parse to a finite, non-negative integer\n * - keyId must be ASCII identifier-safe ([A-Za-z0-9_-]+) so a\n * malicious header cannot smuggle control chars or whitespace\n * into log lines / metric labels\n * - signature must be valid base64 (only base64 alphabet chars)\n */\nexport function parseSignatureHeader(headerValue: string | undefined): ParsedSignature | null {\n if (typeof headerValue !== 'string' || !headerValue.startsWith(SIGNATURE_VERSION_PREFIX)) {\n return null\n }\n const payload = headerValue.slice(SIGNATURE_VERSION_PREFIX.length)\n const parts = payload.split(':')\n if (parts.length !== 3) return null\n\n const [keyId, tsStr, signature] = parts\n if (!keyId || !tsStr || !signature) return null\n\n // Identifier-safe check on keyId. Mirrors the convention used for\n // OAuth provider IDs — keep this tight; a future PR adding `.` or\n // `:` to the alphabet should be a deliberate decision.\n if (!/^[A-Za-z0-9_-]+$/.test(keyId)) return null\n\n // Timestamp: digits only (forbid '+', '-', '.', exponent, etc.).\n if (!/^\\d+$/.test(tsStr)) return null\n const unixSeconds = Number(tsStr)\n if (!Number.isFinite(unixSeconds) || unixSeconds < 0) return null\n\n // Base64 alphabet check — `Buffer.from(s, 'base64')` is permissive\n // (it silently drops invalid chars) which would let a malformed\n // signature compare-equal to a legitimate one after re-encoding.\n // Reject up front.\n if (!/^[A-Za-z0-9+/]+=*$/.test(signature)) return null\n\n return { keyId, unixSeconds, signature }\n}\n\n/**\n * Format a ParsedSignature back into a header string. Round-trips\n * with `parseSignatureHeader` for any validly-shaped input.\n *\n * Used by the signing side (HTTP client). Keeping it next to the\n * parser pins the format in one place.\n */\nexport function formatSignatureHeader(parsed: ParsedSignature): string {\n return `${SIGNATURE_VERSION_PREFIX}${parsed.keyId}:${parsed.unixSeconds}:${parsed.signature}`\n}\n","import { createHmac } from 'crypto'\nimport {\n buildCanonicalString,\n formatSignatureHeader,\n type ParsedSignature,\n} from './canonical'\n\n/**\n * P1-A14a-2d — pure HMAC signer for outbound /api/internal/**\n * requests. Lives in SDK so remote-mcp and slack-bot (both of which\n * already depend on `@vess-id/ai-identity`) can attach\n * `X-Internal-Signature` to every request without dragging the\n * api package into their dependency graph.\n *\n * Pure (no I/O, no Nest). Mirrors the `utils/crypto.ts` profile:\n * the only Node-builtin used is `crypto.createHmac`.\n *\n * Pairing with the verifier\n * -------------------------\n * The verifier (api side, `HmacKeyset.verify` →\n * `buildCanonicalString` → constant-time compare) reads the same\n * `buildCanonicalString` from this module by construction. As long\n * as both sides pass the same `(method, path, unixSeconds, rawBody)`\n * the HMACs match by definition.\n *\n * Body bytes\n * ----------\n * The caller MUST pass the exact bytes that go on the wire as\n * `rawBody`. Re-running `JSON.stringify(...)` on each side would\n * risk a byte mismatch (object key order is implementation-defined\n * in spec, even though V8 preserves insertion order in practice).\n * The api-client `makeRequest` helper computes `JSON.stringify`\n * once, hands the same string to both `signRequest` and `fetch`.\n */\n\n/**\n * Minimum signer key length in raw bytes. 32 bytes = 256 bits\n * matches HMAC-SHA256's natural block size and the verifier's\n * `MIN_KEY_BYTES`. A truncated env var (accidental newline,\n * copy-paste error) is the realistic failure mode this guards\n * against.\n */\nexport const MIN_SIGNER_KEY_BYTES = 32\n\nexport interface InternalHmacSignerKey {\n /** Stable identifier for the key, e.g. `'mcp-v1'`. Embedded in\n * the X-Internal-Signature header so the verifier can pick the\n * right key. Must match `/^[A-Za-z0-9_-]+$/`. */\n keyId: string\n /** Raw HMAC secret. >= MIN_SIGNER_KEY_BYTES bytes. */\n secret: Buffer\n}\n\nexport interface SignRequestArgs {\n /** HTTP method. Will be upper-cased by `buildCanonicalString`,\n * but callers should pass the uppercase form they use on the\n * wire so signer and `fetch()` stay in lockstep. */\n method: string\n /** URL path with query string already stripped (verifier does\n * `request.originalUrl?.split('?')[0]`; signer must mirror).\n * Path encoding (e.g. `%2F` vs `/`) is caller's responsibility\n * — the canonical string treats them as different bytes. */\n path: string\n /** Wire bytes. The same string/buffer passed to `fetch({body})`\n * must be passed here — `JSON.stringify` runs ONCE per request\n * in the caller. */\n rawBody: Buffer | string\n /** Optional fixed timestamp for testing. Defaults to\n * `Math.floor(Date.now() / 1000)`. */\n unixSeconds?: number\n}\n\n/**\n * Sign an outbound request and return a fully-formatted\n * `X-Internal-Signature` header value. The caller sets the header\n * on the outbound request directly:\n *\n * ```ts\n * headers[SIGNATURE_HEADER] = signRequest(key, { method, path, rawBody })\n * ```\n *\n * Throws if key material is invalid (bad keyId or short secret) —\n * surfacing misconfiguration loudly at request time rather than\n * silently producing a header the verifier will reject.\n */\nexport function signRequest(key: InternalHmacSignerKey, args: SignRequestArgs): string {\n assertKeyMaterial(key)\n const unixSeconds = args.unixSeconds ?? Math.floor(Date.now() / 1000)\n const canonical = buildCanonicalString({\n method: args.method,\n path: args.path,\n unixSeconds,\n rawBody: args.rawBody,\n })\n const signature = createHmac('sha256', key.secret).update(canonical).digest('base64')\n const parsed: ParsedSignature = {\n keyId: key.keyId,\n unixSeconds,\n signature,\n }\n return formatSignatureHeader(parsed)\n}\n\nfunction assertKeyMaterial(k: InternalHmacSignerKey): void {\n if (!k.keyId || !/^[A-Za-z0-9_-]+$/.test(k.keyId)) {\n throw new Error(\n `internal-signature signer: invalid keyId ${JSON.stringify(k.keyId)} (must match /^[A-Za-z0-9_-]+$/)`,\n )\n }\n if (!Buffer.isBuffer(k.secret) || k.secret.length < MIN_SIGNER_KEY_BYTES) {\n throw new Error(\n `internal-signature signer: secret too short for keyId=${k.keyId} ` +\n `(${Buffer.isBuffer(k.secret) ? k.secret.length : 'not a Buffer'} bytes; ` +\n `minimum ${MIN_SIGNER_KEY_BYTES} required)`,\n )\n }\n}\n","/**\n * CedarEngine — minimal wrapper around `@cedar-policy/cedar-wasm/nodejs`.\n *\n * Phase 1 Step 1 scope (server-side / Node-runtime only):\n * - preparseSchema : ingest Cedar schema text → opaque SchemaHandle\n * - preparsePolicySet: ingest Cedar PolicySet text → opaque PolicySetHandle\n * - evaluate : run statefulIsAuthorized against preparsed handles\n *\n * Browser callers receive `CedarEngineUnavailableError` because the\n * `/nodejs` subpath depends on Node `fs` to instantiate the wasm.\n *\n * Performance notes (companion design spec Appendix C, PoC 2026-05-23):\n * - statefulIsAuthorized + preparsed cache: p50 0.067ms / p99 0.076ms\n * (~9x faster than re-parsing every call). The wasm caches preparsed\n * handles internally keyed by string name/id, so the opaque handles\n * we expose are thin wrappers around an auto-generated id.\n *\n * Concurrency / TOCTOU (Cedar design spec rev 5/6, fix C3):\n * - `createCedarEngine()` caches the in-flight Promise (not the resolved\n * engine). Two parallel callers therefore share the same load — no\n * duplicated dynamic import of the 4.1 MB wasm.\n * - On load failure the cached promise is cleared so the next caller can\n * retry. This avoids permanently poisoning the module after a transient\n * failure (e.g. wasm streaming compile blip).\n *\n * Design ref: docs/specs/2026-05-23-cedar-rar-permission-redesign.md\n * Plan ref: docs/specs/2026-05-23-cedar-rar-implementation-plan-phase1.md\n */\n\n// --- Public types -----------------------------------------------------------\n\n/**\n * Decision domain exposed by the wrapper. Cedar's wasm uses lowercase\n * `'allow' | 'deny'`; we normalize to the spec's casing so callers can\n * pattern-match on a single canonical form across the codebase.\n */\nexport type CedarDecision = 'Allow' | 'Deny'\n\n/**\n * Structured error returned for evaluation-time problems (policy execution\n * errors). Parse / schema errors are surfaced at preparse time as thrown\n * `CedarParseError`s instead.\n */\nexport interface CedarError {\n /** Policy id that errored, if attributable. */\n policyId?: string\n /** Human-readable message from Cedar. */\n message: string\n /** Optional structured diagnostic code from Cedar. */\n code?: string\n}\n\n/**\n * Phase 2-1-H — structured policy validation error surfaced by\n * `CedarParseError.validationErrors` (and re-exported as a public type\n * so API / UI callers don't have to re-implement source-location math).\n *\n * One `PolicyValidationError` entry corresponds to one cedar-wasm\n * diagnostic (top-level `errors[]` entries + their `related[]`\n * descendants are flattened into a single list, since callers always\n * want to render every diagnostic — the related chain is metadata about\n * the top-level failure, not a separate parse).\n *\n * Fields:\n * - `code` — machine-readable classification, snake_case. Phase 1\n * surface: `'parse_error'` (default). Future cedar-wasm releases\n * ship structured codes; the classifier here uses message-pattern\n * heuristics until then (see `classifyCedarErrorMessage`).\n * - `message` — cedar-wasm's human-readable English. UI is\n * responsible for i18n / templating; we don't translate here.\n * - `line` / `column` — 1-based caret. Computed from the byte\n * `start` offset in cedar-wasm's `sourceLocations[]` against the\n * ORIGINAL policy text, so the caret matches what the user sees\n * in the textarea / editor.\n * - `context` — the offending byte slice (max 200 chars, truncated\n * with an ellipsis). Lets UIs render an inline highlight without\n * a second round trip.\n * - `offset` — 0-based byte offset (for editors that prefer offsets\n * to line/column; line/column is provided as a convenience).\n */\nexport interface PolicyValidationError {\n /**\n * Machine-readable code, snake_case. Currently a small set:\n * - `'parse_error'` — syntax / grammar failure (default)\n * - `'unexpected_end_of_input'` — incomplete policy\n * - `'unexpected_token'` — token didn't match expected production\n * - `'unknown_extension'` — referenced an unknown extension fn\n * - `'unknown'` — fallback when no heuristic matches\n * Callers that switch on this string MUST default to a generic\n * branch — the set will grow as cedar-wasm exposes structured codes.\n */\n code: string\n /** Cedar's human-readable English diagnostic. */\n message: string\n /** 1-based line in the original policy text where the error starts. */\n line?: number\n /** 1-based column in the line (counts UTF-16 code units, matching JS String). */\n column?: number\n /**\n * The raw policy slice that triggered the error, truncated to 200\n * chars with a trailing ellipsis when longer. Useful for UIs to\n * highlight the offending span without re-computing offsets.\n */\n context?: string\n /** 0-based byte offset into the policy text (when known). */\n offset?: number\n}\n\n/**\n * Opaque handle to a Cedar schema that has been parsed and cached\n * inside the wasm. Returned by `preparseSchema`; pass to `evaluate`.\n *\n * The wasm caches by string name, so the handle carries the auto-generated\n * id. Callers must treat the type as opaque.\n */\nexport interface SchemaHandle {\n readonly __cedar: 'schema'\n readonly name: string\n}\n\n/** Opaque handle to a Cedar PolicySet. Returned by `preparsePolicySet`. */\nexport interface PolicySetHandle {\n readonly __cedar: 'policySet'\n readonly id: string\n}\n\n/**\n * A Cedar entity in the JSON shape expected by the wasm.\n *\n * We keep this as `Record<string, unknown>` rather than importing the\n * detailed `EntityJson` type from `@cedar-policy/cedar-wasm` because the\n * SDK is consumed by browser bundlers; pulling in the d.ts would force\n * the wasm typings into browser builds (the runtime is still lazy-loaded).\n * Callers cast as needed; runtime validation is delegated to the wasm.\n */\nexport type CedarEntity = Record<string, unknown>\n\nexport interface CedarEvaluateRequest {\n /** Cedar entity-uid expression, e.g. `Agent::\"agent-1\"`. */\n principal: string\n /** Cedar entity-uid expression, e.g. `Action::\"gmail.message.send\"`. */\n action: string\n /** Cedar entity-uid expression, e.g. `GmailThread::\"thread-1\"`. */\n resource: string\n /** Free-form context dict (must match the schema's context shape). */\n context: Record<string, unknown>\n}\n\nexport interface EvaluateInput {\n policySetHandle: PolicySetHandle\n schemaHandle?: SchemaHandle\n entities: ReadonlyArray<CedarEntity>\n request: CedarEvaluateRequest\n}\n\nexport interface EvaluateResult {\n decision: CedarDecision\n /** Policy ids that determined the decision (Cedar's `diagnostics.reason`). */\n reasons: string[]\n /** Evaluation-time errors, if any. Empty array on success. */\n errors: CedarError[]\n}\n\nexport interface CedarEngine {\n preparseSchema(schemaText: string): SchemaHandle\n preparsePolicySet(cedarText: string): PolicySetHandle\n evaluate(input: EvaluateInput): EvaluateResult\n}\n\n// --- Errors -----------------------------------------------------------------\n\n/**\n * Thrown when the Cedar wasm module cannot be loaded — typically because\n * the wrapper is running in a browser (the `/nodejs` subpath requires Node\n * `fs`), but also raised for any unexpected load-time failure.\n */\nexport class CedarEngineUnavailableError extends Error {\n override readonly name = 'CedarEngineUnavailableError'\n\n constructor(cause: unknown) {\n // The `cause` option is ES2022 standard; the base Error constructor\n // assigns it to `this.cause` so we don't need a separate field.\n super(\n 'Cedar wasm engine could not be loaded. ' +\n 'This typically happens in non-Node environments (browser) or when ' +\n 'the @cedar-policy/cedar-wasm/nodejs module fails to instantiate.',\n { cause },\n )\n }\n}\n\n/**\n * Thrown by `preparseSchema` / `preparsePolicySet` when Cedar reports a\n * structured `{ type: 'failure', errors: [...] }` answer. Callers (e.g.\n * the Policy Registry lint) can inspect `errors` for diagnostics.\n *\n * Phase 2-1-H — `validationErrors` is a parallel, richer view of the\n * same failures with line / column / context derived against the\n * original policy text. The legacy `errors` field is preserved as-is\n * so call sites that only need the message text don't need to change.\n */\nexport class CedarParseError extends Error {\n override readonly name = 'CedarParseError'\n readonly errors: CedarError[]\n /**\n * Structured diagnostics with `{ code, message, line, column, context,\n * offset }`. Always non-empty when the throw is from cedar-wasm; may\n * be empty when constructed from a non-cedar-wasm path (e.g. when an\n * upstream caller wraps an unexpected throw).\n */\n readonly validationErrors: PolicyValidationError[]\n\n constructor(\n message: string,\n errors: CedarError[],\n validationErrors: PolicyValidationError[] = [],\n ) {\n super(message)\n this.errors = errors\n this.validationErrors = validationErrors\n }\n}\n\n// --- Internal: cedar-wasm minimal surface ----------------------------------\n\n/**\n * Minimal subset of the cedar-wasm module surface we depend on. We type only\n * the shape we use so the SDK's d.ts doesn't accidentally pull in the full\n * upstream typings (which would broaden the public type-surface).\n */\ninterface CedarWasmModule {\n preparseSchema(name: string, schema: string): CedarCheckParseAnswer\n preparsePolicySet(\n psetId: string,\n policies: { staticPolicies: string },\n ): CedarCheckParseAnswer\n statefulIsAuthorized(call: CedarStatefulCall): CedarAuthorizationAnswer\n}\n\ninterface CedarStatefulCall {\n principal: { type: string; id: string }\n action: { type: string; id: string }\n resource: { type: string; id: string }\n context: Record<string, unknown>\n preparsedSchemaName?: string\n preparsedPolicySetId: string\n validateRequest?: boolean\n entities: ReadonlyArray<CedarEntity>\n}\n\ntype CedarCheckParseAnswer =\n | { type: 'success' }\n | { type: 'failure'; errors: CedarDetailedError[] }\n\ntype CedarAuthorizationAnswer =\n | {\n type: 'success'\n response: {\n decision: 'allow' | 'deny'\n diagnostics: { reason: string[]; errors: CedarAuthorizationError[] }\n }\n warnings: CedarDetailedError[]\n }\n | { type: 'failure'; errors: CedarDetailedError[]; warnings: CedarDetailedError[] }\n\ninterface CedarDetailedError {\n message: string\n code?: string | null\n /**\n * Source spans reported by cedar-wasm's miette-backed diagnostic\n * pipeline. `start` / `end` are 0-based byte offsets into the policy\n * text. `label` is a short hint about what was expected. We type only\n * the subset we use; cedar-wasm may include additional fields.\n */\n sourceLocations?: ReadonlyArray<{\n start?: number\n end?: number\n label?: string | null\n }> | null\n /** Cascaded diagnostics — same shape as the top-level error. */\n related?: ReadonlyArray<CedarDetailedError> | null\n}\n\ninterface CedarAuthorizationError {\n policyId: string\n error: CedarDetailedError\n}\n\n// --- Loader cache (C3 TOCTOU-safe) -----------------------------------------\n\ntype CedarLoader = () => Promise<CedarWasmModule>\n\nconst defaultLoader: CedarLoader = async () =>\n // Dynamic import keeps browser bundlers from inlining the Node-only subpath.\n // The cast widens the upstream module to our minimal surface above; we don't\n // re-export the upstream types.\n (await import('@cedar-policy/cedar-wasm/nodejs')) as unknown as CedarWasmModule\n\nlet activeLoader: CedarLoader = defaultLoader\nlet enginePromise: Promise<CedarEngine> | null = null\n\n/**\n * Create (or reuse) the singleton Cedar engine.\n *\n * - First call performs the dynamic import of cedar-wasm.\n * - Subsequent calls return the cached Promise — TOCTOU-safe.\n * - If the in-flight load rejects, the cache is cleared so retries work.\n */\nexport async function createCedarEngine(): Promise<CedarEngine> {\n if (enginePromise) return enginePromise\n\n const inFlight = doCreateCedarEngine(activeLoader).catch((err) => {\n // Clear cache on failure so a subsequent caller can retry.\n if (enginePromise === inFlight) {\n enginePromise = null\n }\n throw err\n })\n enginePromise = inFlight\n return enginePromise\n}\n\nasync function doCreateCedarEngine(loader: CedarLoader): Promise<CedarEngine> {\n let mod: CedarWasmModule\n try {\n mod = await loader()\n } catch (err) {\n throw new CedarEngineUnavailableError(err)\n }\n\n // Auto-generate per-handle ids. Cedar's wasm keys its preparsed cache by\n // string name/id, so we mint a unique one per call. A monotonic counter\n // is sufficient (the engine is process-scoped; ids never need to survive\n // across processes).\n let handleCounter = 0\n const nextId = (kind: string): string =>\n `${kind}-${++handleCounter}-${Date.now().toString(36)}`\n\n const adapter: CedarEngine = {\n preparseSchema(schemaText) {\n const name = nextId('schema')\n const ans = mod.preparseSchema(name, schemaText)\n if (ans.type === 'failure') {\n throw new CedarParseError(\n `Failed to parse Cedar schema: ${ans.errors[0]?.message ?? 'unknown error'}`,\n ans.errors.map(toCedarError),\n buildValidationErrors(ans.errors, schemaText),\n )\n }\n return { __cedar: 'schema', name }\n },\n\n preparsePolicySet(cedarText) {\n const id = nextId('pset')\n const ans = mod.preparsePolicySet(id, { staticPolicies: cedarText })\n if (ans.type === 'failure') {\n throw new CedarParseError(\n `Failed to parse Cedar PolicySet: ${ans.errors[0]?.message ?? 'unknown error'}`,\n ans.errors.map(toCedarError),\n buildValidationErrors(ans.errors, cedarText),\n )\n }\n return { __cedar: 'policySet', id }\n },\n\n evaluate(input) {\n const call: CedarStatefulCall = {\n principal: parseEntityUid(input.request.principal),\n action: parseEntityUid(input.request.action),\n resource: parseEntityUid(input.request.resource),\n context: input.request.context ?? {},\n preparsedPolicySetId: input.policySetHandle.id,\n entities: input.entities,\n }\n if (input.schemaHandle) {\n call.preparsedSchemaName = input.schemaHandle.name\n // Only request validation when a schema is available; without one\n // Cedar treats `validateRequest: true` as an error.\n call.validateRequest = true\n }\n\n const ans = mod.statefulIsAuthorized(call)\n if (ans.type === 'failure') {\n return {\n decision: 'Deny',\n reasons: [],\n errors: ans.errors.map(toCedarError),\n }\n }\n\n return {\n decision: ans.response.decision === 'allow' ? 'Allow' : 'Deny',\n reasons: ans.response.diagnostics.reason ?? [],\n errors: (ans.response.diagnostics.errors ?? []).map((e) => ({\n policyId: e.policyId,\n message: e.error.message,\n code: e.error.code ?? undefined,\n })),\n }\n },\n }\n\n return adapter\n}\n\nfunction toCedarError(e: CedarDetailedError): CedarError {\n return {\n message: e.message,\n code: e.code ?? undefined,\n }\n}\n\n/**\n * Phase 2-1-H — flatten cedar-wasm's `{ message, sourceLocations[],\n * related[] }` tree into a list of `PolicyValidationError` entries\n * with line/column derived against the original policy text.\n *\n * `related[]` entries are walked recursively and emitted as siblings\n * of the top-level error (cedar-wasm uses `related` for \"and also...\"\n * style cascade diagnostics — UIs typically render all of them, not\n * just the head).\n *\n * If cedar-wasm returns no `sourceLocations`, we still emit an entry\n * (without line/column) so the caller always sees at least one error\n * per failure path.\n *\n * @internal — Phase 2-1-H heuristic implementation. Exported for cross-package\n * reuse (API + agentd / remote-mcp future surfaces) and unit tests, but NOT a\n * stable public API. Will be replaced once cedar-wasm exposes structured\n * diagnostic codes upstream (tracked as Phase 2-2-I). Semver of `@vess-id/ai-identity`\n * may remove or rename this function without a major bump.\n */\nexport function buildValidationErrors(\n errors: ReadonlyArray<CedarDetailedError>,\n sourceText: string,\n): PolicyValidationError[] {\n const out: PolicyValidationError[] = []\n // Defensive depth cap — cedar-wasm 4.11.0 produces shallow trees (1-2 levels)\n // in practice, but a malformed/cyclic `related` chain shouldn't blow the stack.\n // Higher levels are dropped silently; UI would not render them anyway.\n const MAX_DEPTH = 10\n const visit = (e: CedarDetailedError, depth: number): void => {\n if (depth >= MAX_DEPTH) return\n const code = classifyCedarErrorMessage(e.message, e.code ?? undefined)\n const loc = (e.sourceLocations ?? []).find(\n (l) => typeof l?.start === 'number',\n )\n const offset = typeof loc?.start === 'number' ? loc.start : undefined\n const end = typeof loc?.end === 'number' ? loc.end : undefined\n const lc = offset !== undefined ? offsetToLineColumn(sourceText, offset) : null\n const context =\n offset !== undefined && end !== undefined && end > offset\n ? truncateContext(sourceText.slice(offset, end))\n : undefined\n out.push({\n code,\n message: e.message,\n ...(lc ? { line: lc.line, column: lc.column } : {}),\n ...(context !== undefined ? { context } : {}),\n ...(offset !== undefined ? { offset } : {}),\n })\n if (e.related && Array.isArray(e.related)) {\n for (const child of e.related) visit(child, depth + 1)\n }\n }\n for (const e of errors) visit(e, 0)\n return out\n}\n\n/**\n * Heuristic classifier mapping cedar-wasm's English message text to a\n * stable snake_case code. cedar-wasm@4.11.0 does not yet expose a\n * structured `code` field (the `code` slot in `CedarDetailedError` is\n * always `null` for parse failures), so we match on substring patterns\n * that have proven stable across recent releases.\n *\n * If `cedarCode` is supplied (future cedar-wasm release) it wins.\n *\n * Returned codes (must stay in sync with the JSDoc on\n * `PolicyValidationError.code`):\n * - `parse_error` — generic parse failure (fallback)\n * - `unexpected_end_of_input` — incomplete policy\n * - `unexpected_token` — token didn't match expected production\n * - `unknown_extension` — referenced unknown extension fn\n * - `unknown` — message didn't match any pattern\n *\n * @internal — Phase 2-1-H heuristic implementation, same caveat as\n * `buildValidationErrors`. Will be replaced once cedar-wasm exposes structured\n * diagnostic codes upstream (Phase 2-2-I).\n */\nexport function classifyCedarErrorMessage(\n message: string,\n cedarCode?: string,\n): string {\n if (cedarCode && cedarCode.length > 0) return cedarCode\n const m = message.toLowerCase()\n if (m.includes('unexpected end of input')) return 'unexpected_end_of_input'\n if (m.includes('unexpected token')) return 'unexpected_token'\n if (m.includes('unknown extension')) return 'unknown_extension'\n if (m.includes('failed to parse')) return 'parse_error'\n return 'unknown'\n}\n\n/**\n * Convert a 0-based byte offset to a 1-based `{ line, column }`.\n *\n * Cedar's `sourceLocations` reports byte offsets, but JS strings are\n * UTF-16; for ASCII Cedar source (the common case) the two coincide.\n * For multi-byte chars in policy text (rare — non-ASCII can appear in\n * quoted string literals, Cedar entity / type names, and policy\n * comments) the column may be slightly off by the UTF-8/UTF-16\n * mismatch. We accept this trade-off because the alternative\n * (decoding the policy text as UTF-8 bytes to find the char boundary)\n * would push the implementation considerably; the resulting caret is\n * \"approximately right\" for UI display, which is what's needed.\n */\nfunction offsetToLineColumn(\n text: string,\n offset: number,\n): { line: number; column: number } {\n // Clamp so an out-of-range offset (cedar-wasm sometimes points one\n // past the end for `unexpected end of input`) doesn't blow up.\n const safe = Math.max(0, Math.min(offset, text.length))\n let line = 1\n let lineStart = 0\n for (let i = 0; i < safe; i++) {\n if (text.charCodeAt(i) === 10 /* \\n */) {\n line += 1\n lineStart = i + 1\n }\n }\n return { line, column: safe - lineStart + 1 }\n}\n\n/**\n * Truncate the offending slice so a 64 KB upstream policy doesn't\n * end up in a 64 KB error response. 200 chars is enough to convey\n * the offending span; a trailing `…` signals truncation.\n */\nfunction truncateContext(slice: string): string {\n const max = 200\n if (slice.length <= max) return slice\n return slice.slice(0, max - 1) + '…'\n}\n\n/**\n * Parse a Cedar entity-uid expression like `Agent::\"agent-1\"` into the\n * `{ type, id }` shape statefulIsAuthorized expects.\n *\n * We accept the textual form because it's the natural representation in\n * policy strings and is easier for callers to construct. Throws if the\n * input doesn't match — this is intentionally strict; downstream code\n * should always pass canonical entity uids.\n */\n// Cedar uses `::` (double colon) as the namespace separator. A single colon\n// in the type prefix is invalid (e.g. `Foo:Bar::\"id\"` should be rejected).\n// We allow optional repeated `::Segment` segments before the final `::\"id\"`.\nconst ENTITY_UID_PATTERN =\n /^([A-Za-z_]\\w*(?:::[A-Za-z_]\\w*)*)::\"((?:[^\"\\\\]|\\\\.)*)\"$/\n\nfunction parseEntityUid(uid: string): { type: string; id: string } {\n // Match `Namespace::\"id\"` with an optional namespace-path prefix.\n // e.g. `Agent::\"a-1\"`, `MyOrg::Agent::\"a-1\"`.\n const m = uid.match(ENTITY_UID_PATTERN)\n if (!m) {\n throw new Error(\n `Invalid Cedar entity uid expression: ${JSON.stringify(uid)}. ` +\n `Expected form: Type::\"id\" (e.g. Agent::\"agent-1\").`,\n )\n }\n return {\n type: m[1] as string,\n // Unescape standard Cedar string escapes (\\\" → \").\n id: (m[2] as string).replace(/\\\\(.)/g, '$1'),\n }\n}\n\n// --- Test-only hooks --------------------------------------------------------\n//\n// These are exported so the unit tests can drive load behaviour\n// deterministically (TOCTOU regression + retry-after-failure). Production\n// code MUST NOT call them.\n\n/** Drop the cached engine Promise. Production callers should never need this. */\nexport function __resetCedarEngineCache(): void {\n enginePromise = null\n}\n\n/**\n * Override the cedar-wasm loader used by `createCedarEngine`. Pass `null` to\n * restore the default dynamic-import loader.\n */\nexport function __setCedarLoaderForTests(loader: CedarLoader | null): void {\n activeLoader = loader ?? defaultLoader\n}\n\n/**\n * Test-only wrapper around the module-internal `parseEntityUid`. Lets the\n * spec assert the entity-uid regex directly (e.g. that single-colon namespace\n * forms are rejected) without contorting `evaluate` invocations.\n *\n * Production code MUST NOT call this — the leading underscores follow the\n * `__resetCedarEngineCache` / `__setCedarLoaderForTests` convention used\n * elsewhere in this module for test-only escape hatches.\n */\nexport function __parseEntityUidForTests(uid: string): {\n type: string\n id: string\n} {\n return parseEntityUid(uid)\n}\n","/**\n * Action risk-level resolver — registry-driven (OpenQ-5 root fix).\n *\n * Spec refs:\n * - docs/specs/2026-05-27-action-risk-registry-driven.md §3\n * - docs/specs/2026-05-24-cedar-unification-design.md §7.2 (original Phase 1\n * suffix heuristic, now retained only as a fallback)\n *\n * Resolution order:\n * 1. If the action exists in ACTION_REGISTRY and declares a `risk`, return\n * that value — ACTION_REGISTRY is the single source of truth (matching\n * CLAUDE.md). This is what Cedar `context.action.risk_level` binds to,\n * so a developer's hand-curated `risk: 'high'` is now authoritative.\n * 2. Otherwise (unknown / not-yet-registered action) fall back to the\n * deterministic suffix heuristic below:\n * - write/send/delete-class suffixes → 'high'\n * - read/list/get-class suffixes → 'low'\n * - everything else → 'medium' (fail-safe)\n *\n * The suffix heuristic classifies by the **last dotted segment** of the\n * action name (e.g., `gmail.message.send` → `send` → 'high').\n *\n * Lookup is case-insensitive: input is lowercased before the registry Map\n * lookup (registry keys are all lowercase), so `gmail.message.TRASH` still\n * hits the registry `high` instead of mis-falling-back to the suffix value.\n */\n\nimport { ACTION_REGISTRY } from './action-registry-json'\n\nexport type ActionRisk = 'low' | 'medium' | 'high'\n\nconst HIGH_RISK_SUFFIXES = new Set([\n 'send',\n 'post',\n 'create',\n 'update',\n 'delete',\n 'remove',\n 'write',\n 'modify',\n 'upload',\n 'invite',\n 'archive',\n 'unarchive',\n 'kick',\n 'rename',\n 'patch',\n 'put',\n])\n\nconst LOW_RISK_SUFFIXES = new Set([\n 'read',\n 'list',\n 'get',\n 'search',\n 'find',\n 'lookup',\n 'show',\n 'view',\n 'fetch',\n 'history',\n 'info',\n])\n\n/**\n * Module-load-time cache: lowercased action name → registry `risk`.\n *\n * Built once so resolveActionRisk does an O(1) Map lookup instead of a\n * linear scan of ACTION_REGISTRY.actions on every call. Keys are lowercased\n * to support case-insensitive lookup.\n */\nconst REGISTRY_RISK_BY_ACTION: ReadonlyMap<string, ActionRisk> = (() => {\n const map = new Map<string, ActionRisk>()\n for (const entry of ACTION_REGISTRY.actions) {\n if (typeof entry.action === 'string' && typeof entry.risk === 'string') {\n map.set(entry.action.toLowerCase(), entry.risk as ActionRisk)\n }\n }\n return map\n})()\n\n/**\n * Suffix-heuristic fallback for actions not present in ACTION_REGISTRY.\n * Classifies by the last dotted segment of an already-lowercased name.\n */\nfunction resolveActionRiskBySuffix(lowerAction: string): ActionRisk {\n const segments = lowerAction.split('.')\n const last = segments[segments.length - 1] ?? ''\n if (!last) return 'medium'\n if (HIGH_RISK_SUFFIXES.has(last)) return 'high'\n if (LOW_RISK_SUFFIXES.has(last)) return 'low'\n return 'medium'\n}\n\n/**\n * Resolve the risk level for a dotted action name.\n *\n * Registry-driven: a registered action returns its declared `risk`\n * (authoritative); unknown actions fall back to the suffix heuristic.\n *\n * Examples:\n * resolveActionRisk('os.secret.read') → 'high' (registry)\n * resolveActionRisk('gmail.message.trash') → 'high' (registry)\n * resolveActionRisk('jira.issue.transition') → 'high' (registry)\n * resolveActionRisk('unknown.connector.send') → 'high' (suffix fallback)\n * resolveActionRisk('unknown.connector.read') → 'low' (suffix fallback)\n * resolveActionRisk('unknown.connector.sync') → 'medium'(suffix fallback)\n *\n * Defensive defaults:\n * - empty / falsy input → 'medium' (fail-safe; never throws)\n * - unknown suffix → 'medium'\n */\nexport function resolveActionRisk(action: string | undefined | null): ActionRisk {\n if (!action || typeof action !== 'string') return 'medium'\n const lower = action.toLowerCase()\n const registryRisk = REGISTRY_RISK_BY_ACTION.get(lower)\n if (registryRisk) return registryRisk\n return resolveActionRiskBySuffix(lower)\n}\n","/**\n * buildCedarEntities — Cedar entity-list builder (Cedar unification Step 1).\n *\n * Spec ref:\n * - docs/specs/2026-05-24-cedar-unification-design.md §7.1\n * Phase 1 採用方針: entity attribute と context の **二重 bind**。本 helper は\n * entity 側のみを組み立て、`context.action.risk_level` は呼び出し側\n * (`CedarDecisionService.buildCedarEvaluateRequest`) が context にも別途\n * 注入する。これは Cedar 4.11.0 が schema-less な entity attribute 直参照を\n * policy text 内では制限するため、policy 内では `context.action.risk_level`\n * 経由を Phase 1 で採用するという rev 3 C1 で確定した設計判断による。\n *\n * Action entity の `attrs.risk_level` は本 helper の責務、\n * `context.action.risk_level` は CedarDecisionService の責務。\n * Phase 2+ で Cedar schema 導入時に context 側を撤去し entity 直参照に統一する。\n */\n\nimport type { CedarEntity } from './cedar-engine'\nimport { resolveActionRisk } from '../registry/action-risk'\n\n/**\n * Principal or resource descriptor accepted by {@link buildCedarEntities}.\n * `type` is the Cedar entity-type name (e.g., `Agent`, `User`, `GmailThread`).\n * `attrs` defaults to `{}` if omitted. `parents` is always `[]` in Phase 1\n * (entity hierarchy is reserved for Phase 2 schema work).\n */\nexport interface CedarEntityDescriptor {\n type: string\n id: string\n attrs?: Record<string, unknown>\n}\n\n/**\n * Input contract for {@link buildCedarEntities}. `action` is the dotted\n * action name (e.g., `'gmail.message.send'`); the helper looks up the\n * Phase 1 risk level via {@link resolveActionRisk} and binds it as\n * `Action::\"<id>\".attrs.risk_level`.\n *\n * Context (including `context.action.risk_level`, `context.approval.granted`,\n * `context.environment.*`) is **not** built here — the caller (typically\n * `CedarDecisionService`) builds context separately because the same entities\n * are reused across Phase A / Phase B (approval=false / approval=true)\n * evaluations.\n */\nexport interface CedarEntitiesInput {\n principal: CedarEntityDescriptor\n action: string\n resource: CedarEntityDescriptor\n}\n\n/**\n * Build the Cedar entity list (principal + action + resource) for a single\n * authorization evaluation.\n *\n * Returns exactly 3 entities, in stable order [principal, action, resource].\n * The Action entity gets `attrs.risk_level` populated from\n * {@link resolveActionRisk}. principal / resource pass through `attrs`\n * unchanged (defaulting to `{}` when omitted).\n *\n * Entity hierarchy (`parents`) is intentionally empty in Phase 1 — Phase 2\n * will introduce schema-driven parents (e.g., GmailThread → GmailLabel).\n */\nexport function buildCedarEntities(input: CedarEntitiesInput): CedarEntity[] {\n const { principal, action, resource } = input\n\n const principalEntity: CedarEntity = {\n uid: { type: principal.type, id: principal.id },\n attrs: principal.attrs ?? {},\n parents: [],\n }\n\n const actionEntity: CedarEntity = {\n uid: { type: 'Action', id: action },\n attrs: { risk_level: resolveActionRisk(action) },\n parents: [],\n }\n\n const resourceEntity: CedarEntity = {\n uid: { type: resource.type, id: resource.id },\n attrs: resource.attrs ?? {},\n parents: [],\n }\n\n return [principalEntity, actionEntity, resourceEntity]\n}\n","/**\n * Decision 7-value enum — A2A / AP2 aligned (Cedar unification Step 1).\n *\n * Spec ref:\n * - docs/specs/2026-05-24-cedar-unification-design.md §3\n * - decision #9 (Locked Decisions §2): A2A 互換 7 値、後方互換破壊 OK\n *\n * HTTP mapping (spec §3, line 169):\n * - `permit` → 200\n * - `auth_required` → 202 (replaces legacy `RequireApproval`)\n * - `input_required` → reserved for Phase 2+\n * - `denied` → 403 (explicit forbid policy match)\n * - `denied_default` → 403 (no permit policy matched)\n * - `denied_by_user` → 403 (HITL UI rejection)\n * - `indeterminate` → 500 (Cedar evaluation error, fail-closed)\n *\n * Phase 1 Step 1 scope: SDK enum + runtime guard only.\n * Step 2 (API layer) will rewire `CedarDecisionService` to emit these values\n * and replace the legacy 3-value `CedarDecisionValue` (`Permit | Forbid |\n * RequireApproval`) over the wire. Both types coexist during the transition.\n */\n\n/**\n * The 7 decision states a permission evaluator may emit. Lowercase + snake_case\n * to match A2A protocol naming conventions.\n */\nexport type Decision =\n | 'permit'\n | 'auth_required'\n | 'input_required'\n | 'denied'\n | 'denied_default'\n | 'denied_by_user'\n | 'indeterminate'\n\n/**\n * Frozen ordered tuple of every {@link Decision} value. Useful for `it.each`\n * test enumeration, exhaustiveness assertions, and audit-log validation.\n *\n * The order is **stable** and is the canonical iteration order (permit first,\n * then approval gate, then input gate, then the 3 denied variants, then the\n * fail-closed indeterminate). Do not rely on alphabetic order.\n */\nexport const DECISION_VALUES = [\n 'permit',\n 'auth_required',\n 'input_required',\n 'denied',\n 'denied_default',\n 'denied_by_user',\n 'indeterminate',\n] as const satisfies ReadonlyArray<Decision>\n\n/**\n * Runtime type guard for {@link Decision}. Returns `true` only if `value` is\n * one of the 7 canonical literals. Use this when validating wire payloads\n * (audit log rows, HTTP bodies, IPC) before narrowing to `Decision`.\n *\n * Legacy 3-value capitalized literals (`Permit`, `Forbid`, `RequireApproval`)\n * are **not** accepted; callers that still need to handle the old wire format\n * must do their own translation (Step 2 will provide the migration helper).\n */\nexport function isDecision(value: unknown): value is Decision {\n return (\n typeof value === 'string' &&\n (DECISION_VALUES as ReadonlyArray<string>).includes(value)\n )\n}\n"],"mappings":"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","names":["path","uuidv4","import_node_crypto","fs","path","os","import_uuid","uuidv4","fs","path","os","import_crypto_nodejs","AgentStatus","AgentType","CredentialType","CredentialStatus","VCType","VCStatus","GrantStatus","GrantScope","GrantResourceType","ReceiptStatus","StandardActionCategory","OAuthProvider","InvitationStatus","fs","path","os","Ajv","addFormats","path","fs","import_crypto","path","import_crypto"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config/index.ts","../src/did/key-manager.ts","../src/storage/filesystem-key-storage.ts","../src/storage/memory-key-storage.ts","../src/utils/sdjwt-client.ts","../src/utils/crypto.ts","../src/did/did-utils.ts","../src/agent/agent-did-manager.ts","../src/did/agent.ts","../src/identity/user-identity-manager.ts","../src/vc/vc-manager.ts","../src/vp/vp-manager.ts","../src/vp/kb-jwt-builder.ts","../src/tool/tool-manager.ts","../src/grant/grant-manager.ts","../src/client.ts","../src/identity/user-key-pair-manager.ts","../src/identity/device-enroll-manager.ts","../src/types/agent.ts","../src/types/vc.ts","../src/types/errors.ts","../src/types/permission-vc.ts","../src/types/grant.ts","../src/types/receipt.ts","../src/types/intent.ts","../src/types/oauth.ts","../src/types/invitation.ts","../src/types/permission-mode.ts","../src/types/tier.ts","../src/utils/sdjwt-disclosure.ts","../src/vc/api-vc-manager.ts","../src/constraint/constraint-evaluator.ts","../src/state/json-state-store.ts","../src/gateway/gateway-client.ts","../src/auth/auth-provider.ts","../src/registry/action-registry.ts","../src/registry/providers.ts","../src/registry/access-orchestrator.ts","../src/registry/action-registry-json.ts","../src/registry/resource-types.ts","../src/registry/action-aliases.ts","../src/registry/action-normalizer.ts","../src/registry/reauth-constants.ts","../src/registry/action-summary.ts","../src/resolver/target-resolver.ts","../src/utils/action-classifier.ts","../src/utils/tier-utils.ts","../src/utils/freemail-domains.ts","../src/internal-signature/canonical.ts","../src/internal-signature/signer.ts","../src/policy/cedar-engine.ts","../src/registry/action-risk.ts","../src/policy/cedar-entities.ts","../src/policy/decision.ts"],"sourcesContent":["// Main client\nexport { AIdentityClient, getClient } from './client'\n\n// Configuration\nexport { configure, AIdentityConfig } from './config'\n\n// Managers\nexport { AgentManager } from './did/agent'\nexport { KeyManager } from './did/key-manager'\nexport { AgentDIDManager } from './agent/agent-did-manager'\nexport { UserIdentityManager } from './identity/user-identity-manager'\nexport { UserKeyPairManager } from './identity/user-key-pair-manager'\nexport type { KeyPairGenerationResult } from './identity/user-key-pair-manager'\nexport {\n DeviceEnrollManager,\n DeviceEnrollStartParams,\n DeviceEnrollServerSideParams,\n DeviceEnrollStartResult,\n DeviceEnrollPollResult,\n} from './identity/device-enroll-manager'\nexport { VCManager } from './vc/vc-manager'\nexport { APIVCManager } from './vc/api-vc-manager'\nexport { VPManager } from './vp/vp-manager'\nexport {\n buildKbJwtPayload,\n KB_JWT_DEFAULT_LIFETIME_SECONDS,\n normalizeDomain,\n readVcExpSeconds,\n KbJwtPayload,\n BuildKbJwtPayloadArgs,\n BuildKbJwtPayloadDeps,\n} from './vp/kb-jwt-builder'\nexport { ToolManager, ToolDefinition } from './tool/tool-manager'\n\nexport {\n getDefaultDisclosureFields,\n DisclosureFields,\n} from './utils/sdjwt-disclosure'\n\n// Constraint Evaluation\nexport {\n ConstraintEvaluator,\n ConstraintEvaluatorOptions,\n defaultConstraintEvaluator,\n evaluateConstraints,\n} from './constraint/constraint-evaluator'\n\n// Storage providers\nexport * from './storage'\n\n// State persistence\nexport type { IStateStore } from './state/state-store.interface'\nexport { JsonStateStore } from './state/json-state-store'\n\n// Gateway client\nexport { GatewayClient, GatewayError } from './gateway/gateway-client'\nexport type {\n GatewayEvent,\n GetEventsResponse,\n GetEventsOptions,\n AckEventResponse,\n ApiKeyValidationResult,\n} from './gateway/gateway-client'\n\n// Auth provider\nexport { AuthProvider } from './auth/auth-provider'\nexport type { AuthState } from './auth/auth-provider'\n\nexport * from './registry'\n\n// Action summary utilities\nexport { generateActionSummary, generateActionParamsDisplay, ACTION_PARAMS_MAX_SIZE } from './registry/action-summary'\nexport type { ActionParamDisplay } from './registry/action-summary'\n\n// Utils\nexport { generateKeyPair, signJWT, verifyJWT, generateNonce } from './utils/crypto'\nexport { SDJwtClient } from './utils/sdjwt-client'\n\n// DID Utilities\nexport {\n createDidJwk,\n extractPublicKey,\n extractPublicKeyFromDid,\n isValidDidJwk,\n getKeyIdFromDid,\n publicKeysMatch,\n} from './did/did-utils'\n\n// Target Resolution\nexport { TargetResolver, extractProjectKey } from './resolver/target-resolver'\n\n// Types (consolidated from @vess-id/ai-identity-types)\nexport * from './types'\n\n// Cedar + RAR Phase 1 — explicit named re-exports for ergonomic imports.\n// Note: these are also available via `export * from './types'` above; the\n// explicit re-exports here pin the public surface for assert:publish-surface.\nexport type {\n PolicyRef,\n PolicyRefInline,\n PolicyRefReference,\n PermissionVcClaims_V2,\n PermissionVcClaims_V3,\n Phase1VcLayer,\n VcApprovalClaim,\n} from './types/permission-vc'\nexport {\n isPolicyRefInline,\n isPolicyRefReference,\n PHASE_1_VC_LAYER,\n buildPhase1VcClaims,\n} from './types/permission-vc'\nexport type {\n CedarSchema,\n CedarPolicySetHandle,\n CedarSchemaHandle,\n CedarDecisionValue,\n CedarDecisionDiagnostic,\n} from './types/cedar-policy'\n\n// Action Classifier\nexport { isWriteAction, WRITE_ACTION_NAMES } from './utils/action-classifier'\n\n// Tier Utilities\nexport { resolveUserTier, getTierLimits, isUnlimited } from './utils/tier-utils'\n\n// Freemail domain list — grant internalDomains validation guard\n// (block *@<freemail> domain-wide wildcard; individual addresses allowed)\nexport { FREEMAIL_DOMAINS, isFreemailDomain } from './utils/freemail-domains'\n\n// Internal-signature (HMAC) — P1-A14a-2d\n// Single source of truth for canonical-string + signer used by\n// api (verify) / remote-mcp (sign) / slack-bot (sign).\nexport * from './internal-signature'\n\n// Cedar policy engine (Phase 1 Step 1)\nexport {\n createCedarEngine,\n CedarEngineUnavailableError,\n CedarParseError,\n} from './policy'\nexport type {\n CedarEngine,\n CedarDecision,\n CedarEntity,\n CedarEvaluateRequest,\n EvaluateInput,\n EvaluateResult,\n CedarError,\n SchemaHandle,\n PolicySetHandle,\n} from './policy'\n\n// Phase 2-1-H — structured policy validation error surface for the\n// lint API + grant-manage UI. `buildValidationErrors` is exposed so\n// callers (API service) can re-classify off-line if cedar-wasm changes.\nexport {\n buildValidationErrors,\n classifyCedarErrorMessage,\n} from './policy'\nexport type { PolicyValidationError } from './policy'\n\n// Cedar unification Step 1 — 7-value Decision + Cedar entity builder\nexport { buildCedarEntities, DECISION_VALUES, isDecision } from './policy'\nexport type {\n CedarEntitiesInput,\n CedarEntityDescriptor,\n Decision,\n} from './policy'\nexport { resolveActionRisk } from './registry/action-risk'\nexport type { ActionRisk } from './registry/action-risk'\n\n// Version\nexport const version = '0.0.1'\n","export interface AIdentityConfig {\n didApi?: {\n baseUrl: string\n apiKey?: string\n bearerToken?: string\n }\n issuerApi?: {\n baseUrl: string\n apiKey?: string\n bearerToken?: string\n }\n verifierApi?: {\n baseUrl: string\n apiKey?: string\n bearerToken?: string\n }\n proxyApi?: {\n baseUrl: string\n }\n storage?: {\n keyStorePath?: string // Default: ~/.vess-aidentity/keys\n }\n}\n\nlet globalConfig: AIdentityConfig = {}\n\nexport function configure(config: AIdentityConfig): void {\n globalConfig = { ...globalConfig, ...config }\n}\n\nexport function getConfig(): AIdentityConfig {\n return globalConfig\n}\n\nexport function getDidApiUrl(path: string): string {\n const baseUrl = globalConfig.didApi?.baseUrl || process.env.DID_API_BASE_URL\n if (!baseUrl) {\n throw new Error('DID API base URL not configured')\n }\n return `${baseUrl}${path}`\n}\n\nexport function getIssuerApiUrl(path: string): string {\n const baseUrl = globalConfig.issuerApi?.baseUrl || process.env.ISSUER_API_BASE_URL\n if (!baseUrl) {\n throw new Error('Issuer API base URL not configured')\n }\n return `${baseUrl}${path}`\n}\n\nexport function getVerifierApiUrl(path: string): string {\n const baseUrl = globalConfig.verifierApi?.baseUrl || process.env.VERIFIER_API_BASE_URL\n if (!baseUrl) {\n throw new Error('Verifier API base URL not configured')\n }\n return `${baseUrl}${path}`\n}\n\nexport function getApiHeaders(apiType: 'did' | 'issuer' | 'verifier'): any {\n const headers: any = {\n 'Content-Type': 'application/json',\n }\n\n let apiKey: string | undefined\n let bearerToken: string | undefined\n\n switch (apiType) {\n case 'did':\n apiKey = globalConfig.didApi?.apiKey || process.env.DID_API_KEY\n bearerToken = globalConfig.didApi?.bearerToken\n break\n case 'issuer':\n apiKey = globalConfig.issuerApi?.apiKey || process.env.ISSUER_API_KEY\n bearerToken = globalConfig.issuerApi?.bearerToken\n break\n case 'verifier':\n apiKey = globalConfig.verifierApi?.apiKey || process.env.VERIFIER_API_KEY\n bearerToken = globalConfig.verifierApi?.bearerToken\n break\n }\n\n if (apiKey) {\n headers['x-api-key'] = apiKey\n }\n if (bearerToken) {\n headers['Authorization'] = `Bearer ${bearerToken}`\n }\n\n return headers\n}\n","import * as crypto from 'crypto'\nimport { KeyStorageProvider, FilesystemKeyStorage } from '../storage'\nimport { getConfig } from '../config'\n\nexport class KeyManager {\n private encryptionKey?: Buffer\n private storageProvider: KeyStorageProvider\n\n constructor(password?: string, storageProvider?: KeyStorageProvider) {\n if (password) {\n // Derive encryption key from password\n this.encryptionKey = crypto.scryptSync(password, 'aidentity-salt', 32)\n }\n\n // Use provided storage provider or default to filesystem\n this.storageProvider = storageProvider || this.createDefaultStorageProvider()\n }\n\n private createDefaultStorageProvider(): KeyStorageProvider {\n const config = getConfig()\n return new FilesystemKeyStorage({\n type: 'filesystem',\n options: {\n path: config.storage?.keyStorePath,\n },\n })\n }\n\n async storeKey(did: string, privateKey: any): Promise<void> {\n const keyData = JSON.stringify(privateKey)\n const encrypted = this.encrypt(keyData)\n // const keyId = this.getKeyId(did)\n\n await this.storageProvider.store(did, encrypted)\n }\n\n async getKey(did: string): Promise<any | null> {\n // const keyId = this.getKeyId(did)\n const encrypted = await this.storageProvider.retrieve(did)\n\n if (!encrypted) {\n return null\n }\n\n const decrypted = this.decrypt(encrypted)\n return JSON.parse(decrypted)\n }\n\n async deleteKey(did: string): Promise<void> {\n // const keyId = this.getKeyId(did)\n await this.storageProvider.delete(did)\n }\n\n async listDids(): Promise<string[]> {\n const keyIds = await this.storageProvider.list()\n return keyIds.map(keyId => this.didFromKeyId(keyId))\n }\n\n /**\n * Check if storage is available\n */\n async isAvailable(): Promise<boolean> {\n return this.storageProvider.isAvailable()\n }\n\n // private getKeyId(did: string): string {\n // // Use SHA256 hash to create short, storage-safe identifier\n // return crypto.createHash('sha256').update(did).digest('hex').substring(0, 16)\n // }\n\n private didFromKeyId(keyId: string): string {\n // For now, we cannot reverse the hash, so we need to store the mapping\n // This is a limitation of the current design.\n // TODO: Consider storing DID->keyId mapping in storage provider\n return keyId // Temporary fallback\n }\n\n private encrypt(data: string): string {\n if (!this.encryptionKey) {\n // No encryption if no password provided\n return Buffer.from(data).toString('base64')\n }\n\n const iv = crypto.randomBytes(16)\n const cipher = crypto.createCipheriv('aes-256-gcm', this.encryptionKey, iv)\n\n let encrypted = cipher.update(data, 'utf8', 'base64')\n encrypted += cipher.final('base64')\n\n const authTag = cipher.getAuthTag()\n\n // Combine iv, authTag, and encrypted data\n const combined = Buffer.concat([iv, authTag, Buffer.from(encrypted, 'base64')])\n\n return combined.toString('base64')\n }\n\n private decrypt(encrypted: string): string {\n if (!this.encryptionKey) {\n // No decryption if no password provided\n return Buffer.from(encrypted, 'base64').toString('utf-8')\n }\n\n const combined = Buffer.from(encrypted, 'base64')\n\n // Extract iv, authTag, and encrypted data\n const iv = combined.subarray(0, 16)\n const authTag = combined.subarray(16, 32)\n const encryptedData = combined.subarray(32)\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', this.encryptionKey, iv)\n decipher.setAuthTag(authTag)\n\n let decrypted = decipher.update(encryptedData, undefined, 'utf8')\n decrypted += decipher.final('utf8')\n\n return decrypted\n }\n}\n","import * as fs from 'fs/promises'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { KeyStorageProvider, KeyStorageConfig } from './key-storage.interface'\n\n/**\n * Filesystem-based key storage provider\n */\nexport class FilesystemKeyStorage implements KeyStorageProvider {\n private keyStorePath: string\n\n constructor(config?: KeyStorageConfig) {\n this.keyStorePath = config?.options?.path || path.join(os.homedir(), '.vess-aidentity', 'keys')\n }\n\n async store(id: string, encryptedKey: string): Promise<void> {\n await this.ensureKeyStoreExists()\n const keyPath = this.getKeyPath(id)\n await fs.writeFile(keyPath, encryptedKey, 'utf-8')\n }\n\n async retrieve(id: string): Promise<string | null> {\n const keyPath = this.getKeyPath(id)\n\n try {\n return await fs.readFile(keyPath, 'utf-8')\n } catch (error) {\n if ((error as any).code === 'ENOENT') {\n return null\n }\n throw error\n }\n }\n\n async delete(id: string): Promise<void> {\n const keyPath = this.getKeyPath(id)\n\n try {\n await fs.unlink(keyPath)\n } catch (error) {\n if ((error as any).code !== 'ENOENT') {\n throw error\n }\n }\n }\n\n async list(): Promise<string[]> {\n await this.ensureKeyStoreExists()\n\n const files = await fs.readdir(this.keyStorePath)\n return files\n .filter(f => f.endsWith('.key'))\n .map(f => f.replace('.key', ''))\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n await this.ensureKeyStoreExists()\n return true\n } catch {\n return false\n }\n }\n\n private async ensureKeyStoreExists(): Promise<void> {\n try {\n await fs.access(this.keyStorePath)\n } catch {\n await fs.mkdir(this.keyStorePath, { recursive: true })\n }\n }\n\n private getKeyPath(id: string): string {\n return path.join(this.keyStorePath, `${id}.key`)\n }\n}","import { KeyStorageProvider } from './key-storage.interface'\n\n/**\n * In-memory key storage provider (for testing)\n */\nexport class MemoryKeyStorage implements KeyStorageProvider {\n private keys: Map<string, string> = new Map()\n\n async store(id: string, encryptedKey: string): Promise<void> {\n this.keys.set(id, encryptedKey)\n }\n\n async retrieve(id: string): Promise<string | null> {\n return this.keys.get(id) || null\n }\n\n async delete(id: string): Promise<void> {\n this.keys.delete(id)\n }\n\n async list(): Promise<string[]> {\n return Array.from(this.keys.keys())\n }\n\n async isAvailable(): Promise<boolean> {\n return true\n }\n\n /**\n * Clear all stored keys (for testing)\n */\n clear(): void {\n this.keys.clear()\n }\n}","import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc'\nimport { ES256, digest, generateSalt } from '@sd-jwt/crypto-nodejs'\nimport { generateKeyPair, getSigner, getVerifier } from './crypto'\nimport { KeyManager } from '../did/key-manager'\nimport { extractPublicKeyFromDid } from '../did/did-utils'\nimport type { DisclosureFrame } from '@sd-jwt/types'\nimport type { JWK } from 'jose'\nimport { subtle } from 'node:crypto'\n\nexport class SDJwtClient {\n private static instances: Map<string, SDJwtVcInstance> = new Map()\n private static keyManager: KeyManager\n private static signerCache: Map<string, any> = new Map()\n private static verifierCache: Map<string, any> = new Map()\n\n private constructor() {}\n\n /**\n * Initialize with KeyManager for DID-based key management\n */\n public static setKeyManager(keyManager: KeyManager) {\n this.keyManager = keyManager\n }\n\n /**\n * Get SDJwtVcInstance for issuer role (VC issuance)\n */\n public static async getIssuerInstance(issuerDid: string): Promise<SDJwtVcInstance> {\n const cacheKey = `${issuerDid}:issuer`\n if (!this.instances.has(cacheKey)) {\n const instance = await this.createInstance(issuerDid, 'issuer')\n this.instances.set(cacheKey, instance)\n }\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Get SDJwtVcInstance for holder role (VP presentation)\n */\n public static async getHolderInstance(holderDid: string): Promise<SDJwtVcInstance> {\n const cacheKey = `${holderDid}:holder`\n if (!this.instances.has(cacheKey)) {\n const instance = await this.createInstance(holderDid, 'holder')\n this.instances.set(cacheKey, instance)\n }\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Get SDJwtVcInstance with specified role (backward compatibility)\n */\n public static async getSDJwtInstance(\n did: string,\n options?: { role?: 'issuer' | 'holder' }\n ): Promise<SDJwtVcInstance> {\n const role = options?.role || 'issuer' // Default to issuer for backward compatibility\n return role === 'holder' ? this.getHolderInstance(did) : this.getIssuerInstance(did)\n }\n\n /**\n * Create a new SDJwtVcInstance with DID-based keys and role\n */\n private static async createInstance(\n did: string,\n role: 'issuer' | 'holder'\n ): Promise<SDJwtVcInstance> {\n if (!this.keyManager) {\n this.keyManager = new KeyManager()\n }\n\n // Get private key for DID\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error(`Private key not found for ${role}: ${did}`)\n }\n\n try {\n // Check cache first\n const signerCacheKey = `signer:${did}`\n const verifierCacheKey = `verifier:${did}`\n\n let signer = this.signerCache.get(signerCacheKey)\n let verifier = this.verifierCache.get(verifierCacheKey)\n\n if (!signer) {\n signer = await getSigner(privateKey)\n this.signerCache.set(signerCacheKey, signer)\n }\n\n if (!verifier) {\n // Extract public key from private key for verifier\n const { d, key_ops, ...publicKey } = privateKey // Remove private component and key_ops\n const publicKeyForVerifier = {\n ...publicKey,\n key_ops: ['verify'], // Set correct key operations for verifier\n }\n verifier = await getVerifier(publicKeyForVerifier)\n this.verifierCache.set(verifierCacheKey, verifier)\n }\n\n // Configure based on role\n const config: any = {\n signer,\n verifier,\n signAlg: ES256.alg,\n hasher: digest,\n hashAlg: 'sha-256',\n saltGenerator: generateSalt,\n }\n\n // Add key binding configuration only for holder role\n if (role === 'holder') {\n config.kbSigner = signer\n config.kbSignAlg = ES256.alg\n }\n\n return new SDJwtVcInstance(config)\n } catch (error) {\n console.error('❌ Error creating SDJwtVcInstance:', error)\n throw error\n }\n }\n\n /**\n * Claims that MUST NOT be selectively disclosable.\n *\n * - cnf: Proof of Possession binding (RFC 7800). If disclosable, Holder can\n * hide cnf to bypass PoP verification and transfer VC to another party.\n * - Standard JWT registered claims (iss, sub, exp, iat, nbf, jti) must\n * always be visible for signature verification and expiry checks.\n * - vct: SD-JWT VC credential type discriminator.\n */\n private static readonly NEVER_DISCLOSE = new Set([\n 'cnf', 'iss', 'sub', 'exp', 'iat', 'nbf', 'jti', 'vct',\n ])\n\n /**\n * Create disclosure frame for selective disclosure\n */\n public static createDisclosureFrame<T extends Record<string, any>>(\n claims: T,\n selectivelyDisclosable: string[] = []\n ): DisclosureFrame<T> {\n const frame: any = {}\n\n // Filter selectively disclosable fields to only include fields that actually exist in claims\n // and are not in the NEVER_DISCLOSE set\n const existingDisclosableFields = selectivelyDisclosable.filter(field =>\n claims.hasOwnProperty(field) && !this.NEVER_DISCLOSE.has(field)\n )\n\n // Make specified fields selectively disclosable\n if (existingDisclosableFields.length > 0) {\n frame._sd = existingDisclosableFields\n frame._sd_decoy = Math.max(0, Math.floor(existingDisclosableFields.length * 0.1))\n }\n\n // Process nested objects — skip fields that must never be disclosed\n for (const [key, value] of Object.entries(claims)) {\n if (this.NEVER_DISCLOSE.has(key)) continue\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recursively process nested objects\n const nestedKeys = Object.keys(value)\n const nestedFrame = this.createDisclosureFrame(\n value,\n nestedKeys // Make all nested fields disclosable\n )\n frame[key] = nestedFrame\n }\n }\n\n return frame as DisclosureFrame<T>\n }\n\n /**\n * Issue an SD-JWT with selective disclosure\n */\n public static async issueSDJWT(\n payload: Record<string, any>,\n _privateKey: any, // Not used since we get key from KeyManager based on issuer DID\n selectiveDisclosureFields: string[] = []\n ): Promise<string> {\n const issuerDid = payload.iss || 'unknown'\n const sdjwtInstance = await this.getIssuerInstance(issuerDid)\n\n // Ensure payload has required vct field for SD-JWT VC\n const vcPayload = {\n vct: 'IdentityCredential', // Default VC type\n ...payload,\n }\n\n // Create disclosure frame for selective disclosure\n const disclosureFrame = this.createDisclosureFrame(vcPayload, selectiveDisclosureFields)\n\n return await sdjwtInstance.issue(vcPayload as any, disclosureFrame)\n }\n\n /**\n * Verify an SD-JWT\n */\n public static async verifySDJWT(\n credential: string\n ): Promise<{ valid: boolean; payload?: any; error?: string }> {\n try {\n // Parse to get issuer from the SD-JWT\n const parts = credential.split('~')\n if (parts.length === 0) {\n return { valid: false, error: 'Invalid SD-JWT format' }\n }\n\n const jwt = parts[0]\n const jwtParts = jwt.split('.')\n if (jwtParts.length !== 3) {\n return { valid: false, error: 'Invalid JWT format in SD-JWT' }\n }\n\n const payload = JSON.parse(Buffer.from(jwtParts[1], 'base64url').toString())\n const issuerDid = payload.iss\n\n if (!issuerDid) {\n return { valid: false, error: 'Issuer DID not found in SD-JWT' }\n }\n\n const sdjwtInstance = await this.getIssuerInstance(issuerDid)\n\n // Verify the SD-JWT\n const verificationResult = await sdjwtInstance.verify(credential)\n const claims = await sdjwtInstance.getClaims(credential)\n\n return {\n valid: true,\n payload: {\n ...verificationResult.payload,\n claims,\n },\n }\n } catch (error: any) {\n return {\n valid: false,\n error: error.message,\n }\n }\n }\n\n /**\n * Legacy methods for backward compatibility\n */\n public static async createSignerVerifier() {\n const { privateKey, publicKey } = await this.generateKeyPair()\n return {\n signer: await getSigner(privateKey),\n verifier: await getVerifier(publicKey),\n }\n }\n\n public static async generateKeyPair() {\n return await generateKeyPair()\n }\n\n /**\n * Clear caches for optimization\n */\n public static clearCaches(): void {\n this.instances.clear()\n this.signerCache.clear()\n this.verifierCache.clear()\n }\n\n /**\n * Clear cache for specific issuer\n */\n public static clearIssuerCache(issuerDid: string): void {\n this.instances.delete(issuerDid)\n this.signerCache.delete(`signer:${issuerDid}`)\n this.verifierCache.delete(`verifier:${issuerDid}`)\n }\n\n /**\n * Get cache statistics\n */\n public static getCacheStats(): {\n instanceCount: number\n signerCount: number\n verifierCount: number\n } {\n return {\n instanceCount: this.instances.size,\n signerCount: this.signerCache.size,\n verifierCount: this.verifierCache.size,\n }\n }\n\n /**\n * Create a verifier function from an external public key\n * This is used for verifying SD-JWTs when you don't have the private key\n * (e.g., API side verifying credentials issued by MCP)\n */\n private static async getVerifierFromPublicKey(publicKey: JWK): Promise<(data: string, signature: string) => Promise<boolean>> {\n const key = await subtle.importKey(\n 'jwk',\n publicKey,\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true,\n ['verify']\n )\n\n return async (data: string, signatureBase64url: string) => {\n const encoder = new TextEncoder()\n const signature = Uint8Array.from(\n atob(signatureBase64url.replace(/-/g, '+').replace(/_/g, '/')),\n c => c.charCodeAt(0)\n )\n\n const isValid = await subtle.verify(\n {\n name: 'ECDSA',\n hash: { name: 'SHA-256' },\n },\n key,\n signature,\n encoder.encode(data)\n )\n\n return isValid\n }\n }\n\n /**\n * Get SDJwtVcInstance for verification with an external public key\n * Used when verifying credentials without having the issuer's private key\n */\n private static async getVerificationInstance(publicKey: JWK): Promise<SDJwtVcInstance> {\n const cacheKey = `verify:${JSON.stringify(publicKey)}`\n\n if (!this.instances.has(cacheKey)) {\n const dummySigner = async () => 'dummy'\n const verifier = await this.getVerifierFromPublicKey(publicKey)\n\n const instance = new SDJwtVcInstance({\n signer: dummySigner,\n verifier,\n signAlg: ES256.alg,\n hasher: digest,\n hashAlg: 'sha-256',\n saltGenerator: generateSalt,\n })\n\n this.instances.set(cacheKey, instance)\n }\n\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Get SDJwtVcInstance for decoding without verification\n */\n private static async getDecodingInstance(): Promise<SDJwtVcInstance> {\n const cacheKey = 'decode:dummy'\n\n if (!this.instances.has(cacheKey)) {\n const dummySigner = async () => 'dummy'\n const dummyVerifier = async () => false\n\n const instance = new SDJwtVcInstance({\n signer: dummySigner,\n verifier: dummyVerifier,\n signAlg: ES256.alg,\n hasher: digest,\n hashAlg: 'sha-256',\n saltGenerator: generateSalt,\n })\n\n this.instances.set(cacheKey, instance)\n }\n\n return this.instances.get(cacheKey)!\n }\n\n /**\n * Verify an SD-JWT with an external public key\n * Use this when you have the issuer's public key but not their private key\n *\n * @param credential - The SD-JWT credential string\n * @param publicKey - The issuer's public key (JWK format)\n * @returns Verification result with valid flag and payload\n *\n * @example\n * ```typescript\n * const publicKey = extractPublicKeyFromDid(issuerDid)\n * const result = await SDJwtClient.verifyWithExternalKey(credential, publicKey)\n * if (result.valid) {\n * console.log('Verified claims:', result.payload.claims)\n * }\n * ```\n */\n public static async verifyWithExternalKey(\n credential: string,\n publicKey: JWK\n ): Promise<{ valid: boolean; payload?: any; claims?: any; error?: string }> {\n try {\n const sdJwtInstance = await this.getVerificationInstance(publicKey)\n\n // Verify the SD-JWT\n const verificationResult = await sdJwtInstance.verify(credential, {})\n\n if (!verificationResult) {\n return { valid: false, error: 'Verification failed' }\n }\n\n // Get disclosed claims\n const claims = await sdJwtInstance.getClaims(credential)\n\n return {\n valid: true,\n payload: verificationResult.payload,\n claims,\n }\n } catch (error: any) {\n return {\n valid: false,\n error: error.message,\n }\n }\n }\n\n /**\n * Verify an SD-JWT by extracting the issuer's public key from the DID\n * Automatically resolves did:jwk DIDs\n *\n * @param credential - The SD-JWT credential string\n * @returns Verification result with valid flag and payload\n *\n * @example\n * ```typescript\n * const result = await SDJwtClient.verifyWithIssuerDid(credential)\n * if (result.valid) {\n * console.log('Issuer:', result.payload.iss)\n * }\n * ```\n */\n public static async verifyWithIssuerDid(\n credential: string\n ): Promise<{ valid: boolean; payload?: any; claims?: any; issuerDid?: string; error?: string }> {\n try {\n // First decode to get the issuer DID\n const decoded = await this.decodeWithoutVerification(credential)\n\n if (!decoded.payload) {\n return { valid: false, error: 'Failed to decode credential' }\n }\n\n const issuerDid = decoded.payload.iss || decoded.payload.issuer\n\n if (!issuerDid || typeof issuerDid !== 'string') {\n return { valid: false, error: 'Issuer DID not found in credential' }\n }\n\n // Extract public key from DID\n const publicKey = extractPublicKeyFromDid(issuerDid)\n\n // Verify with the extracted public key\n const result = await this.verifyWithExternalKey(credential, publicKey)\n\n return {\n ...result,\n issuerDid,\n }\n } catch (error: any) {\n return {\n valid: false,\n error: error.message,\n }\n }\n }\n\n /**\n * Decode an SD-JWT without verification\n * Use this when you need to inspect the credential before verification\n * or when you don't have the issuer's public key\n *\n * WARNING: The returned payload has not been verified!\n * Only use this for inspection purposes, not for authorization decisions.\n *\n * @param credential - The SD-JWT credential string\n * @returns Decoded JWT payload, header, and disclosures\n *\n * @example\n * ```typescript\n * const decoded = await SDJwtClient.decodeWithoutVerification(credential)\n * console.log('Issuer (unverified):', decoded.payload?.iss)\n * console.log('Disclosures:', decoded.disclosures?.length)\n * ```\n */\n public static async decodeWithoutVerification(\n credential: string\n ): Promise<{\n payload?: any\n header?: any\n disclosures?: any[]\n claims?: any\n error?: string\n }> {\n try {\n const sdJwtInstance = await this.getDecodingInstance()\n const decoded = await sdJwtInstance.decode(credential)\n\n if (!decoded || !decoded.jwt) {\n return { error: 'Failed to decode SD-JWT' }\n }\n\n // Get claims with disclosures applied\n const claims = await decoded.getClaims(digest)\n\n return {\n payload: decoded.jwt.payload,\n header: decoded.jwt.header,\n disclosures: decoded.disclosures,\n claims,\n }\n } catch (error: any) {\n return { error: error.message }\n }\n }\n\n /**\n * Extract issuer DID from an SD-JWT without verification\n * Useful for determining the issuer before verification\n *\n * @param credential - The SD-JWT credential string\n * @returns The issuer DID or null if not found\n */\n public static extractIssuerDid(credential: string): string | null {\n try {\n const parts = credential.split('~')\n if (parts.length === 0) return null\n\n const jwt = parts[0]\n const jwtParts = jwt.split('.')\n if (jwtParts.length !== 3) return null\n\n const payload = JSON.parse(Buffer.from(jwtParts[1], 'base64url').toString())\n return payload.iss || payload.issuer || null\n } catch {\n return null\n }\n }\n}\n","import * as jose from 'jose'\nimport { v4 as uuidv4 } from 'uuid'\nimport { subtle } from 'node:crypto'\n\nexport interface KeyPair {\n publicKey: any\n privateKey: any\n}\n\nexport async function generateKeyPair(): Promise<KeyPair> {\n const keyPair = await subtle.generateKey(\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true, // extractable\n ['sign', 'verify']\n )\n\n // Export keys in JWK format\n const publicJwk = await subtle.exportKey('jwk', keyPair.publicKey)\n const privateJwk = await subtle.exportKey('jwk', keyPair.privateKey)\n\n // Add key ID\n const kid = uuidv4()\n ;(publicJwk as any).kid = kid\n ;(privateJwk as any).kid = kid\n\n // Add algorithm\n ;(publicJwk as any).alg = 'ES256'\n ;(privateJwk as any).alg = 'ES256'\n\n return {\n publicKey: publicJwk,\n privateKey: privateJwk,\n }\n}\n\nexport async function signJWT(\n payload: any,\n privateKey: any,\n options?: {\n issuer?: string\n audience?: string\n expiresIn?: string\n notBefore?: string\n subject?: string\n jti?: string\n }\n): Promise<string> {\n const alg = privateKey.alg || 'ES256'\n const key = await jose.importJWK(privateKey, alg)\n\n const jwt = new jose.SignJWT(payload)\n .setProtectedHeader({ alg, kid: privateKey.kid })\n .setIssuedAt()\n .setJti(options?.jti ?? uuidv4())\n\n if (options?.issuer) jwt.setIssuer(options.issuer)\n if (options?.audience) jwt.setAudience(options.audience)\n if (options?.expiresIn) jwt.setExpirationTime(options.expiresIn)\n if (options?.notBefore) jwt.setNotBefore(options.notBefore)\n if (options?.subject) jwt.setSubject(options.subject)\n\n return await jwt.sign(key)\n}\n\nexport async function verifyJWT(\n jwt: string,\n publicKey: any,\n options?: {\n issuer?: string\n audience?: string\n }\n): Promise<jose.JWTPayload> {\n const alg = publicKey.alg || 'ES256'\n const key = await jose.importJWK(publicKey, alg)\n\n const verifyOptions: jose.JWTVerifyOptions = {}\n if (options?.issuer) verifyOptions.issuer = options.issuer\n if (options?.audience) verifyOptions.audience = options.audience\n\n const { payload } = await jose.jwtVerify(jwt, key, verifyOptions)\n return payload\n}\n\nexport function generateNonce(): string {\n return uuidv4()\n}\n\nexport async function getSigner(privateKey: any) {\n try {\n const key = await subtle.importKey(\n 'jwk',\n privateKey,\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true,\n ['sign']\n )\n\n return async (data: string) => {\n const encoder = new TextEncoder()\n const signature = await subtle.sign(\n {\n name: 'ECDSA',\n hash: { name: 'SHA-256' },\n },\n key,\n encoder.encode(data)\n )\n\n const result = btoa(String.fromCharCode(...new Uint8Array(signature)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '') // Convert to base64url format\n\n return result\n }\n } catch (error) {\n console.error('Error in getSigner:', error instanceof Error ? error.message : 'Unknown error')\n console.error('Key algorithm:', privateKey?.alg || 'unknown')\n console.error('Key type:', privateKey?.kty || 'unknown')\n throw error\n }\n}\n\nexport async function getVerifier(publicKey: any) {\n const key = await subtle.importKey(\n 'jwk',\n publicKey,\n {\n name: 'ECDSA',\n namedCurve: 'P-256',\n },\n true,\n ['verify']\n )\n\n return async (data: string, signatureBase64url: string) => {\n const encoder = new TextEncoder()\n const signature = Uint8Array.from(\n atob(signatureBase64url.replace(/-/g, '+').replace(/_/g, '/')),\n c => c.charCodeAt(0)\n )\n\n const isValid = await subtle.verify(\n {\n name: 'ECDSA',\n hash: { name: 'SHA-256' },\n },\n key,\n signature,\n encoder.encode(data)\n )\n\n return isValid\n }\n}\n","/**\n * DID Utilities\n *\n * Common utility functions for DID operations.\n * These functions are shared across AgentDIDManager, EphemeralDIDManager,\n * UserIdentityManager, and UserRootDIDManager.\n */\n\nimport type { JWK } from 'jose'\n\n/**\n * Public key JWK properties for did:jwk creation\n */\nexport interface PublicKeyJWK {\n kty: string\n crv?: string\n x?: string\n y?: string\n use?: string\n alg?: string\n}\n\n/**\n * Create did:jwk from a public key JWK\n *\n * @param publicKey - The public key JWK (can include private key fields, they will be filtered)\n * @returns The did:jwk string\n *\n * @example\n * ```typescript\n * const keyPair = await SDJwtClient.generateKeyPair()\n * const did = createDidJwk(keyPair.publicKey)\n * // => did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6Ii4uLiIsInkiOiIuLi4ifQ\n * ```\n */\nexport function createDidJwk(publicKey: JWK | PublicKeyJWK): string {\n const publicJwk: PublicKeyJWK = {\n kty: publicKey.kty!,\n crv: publicKey.crv,\n x: publicKey.x,\n y: publicKey.y,\n use: publicKey.use,\n alg: publicKey.alg,\n }\n\n // Remove undefined values for cleaner encoding\n const cleanedJwk = Object.fromEntries(\n Object.entries(publicJwk).filter(([_, v]) => v !== undefined)\n )\n\n const encoded = Buffer.from(JSON.stringify(cleanedJwk)).toString('base64url')\n return `did:jwk:${encoded}`\n}\n\n/**\n * Extract public key JWK from a private key JWK\n *\n * @param privateKey - The private key JWK containing the 'd' parameter\n * @returns The public key JWK (without private key material)\n *\n * @example\n * ```typescript\n * const keyPair = await SDJwtClient.generateKeyPair()\n * const publicKey = extractPublicKey(keyPair.privateKey)\n * ```\n */\nexport function extractPublicKey(privateKey: JWK): JWK {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { d, key_ops, ...publicKey } = privateKey\n return publicKey as JWK\n}\n\n/**\n * Extract public key JWK from a did:jwk string\n *\n * @param did - The did:jwk string\n * @returns The public key JWK decoded from the DID\n * @throws Error if the DID is not in did:jwk format\n *\n * @example\n * ```typescript\n * const publicKey = extractPublicKeyFromDid('did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6Ii4uLiIsInkiOiIuLi4ifQ')\n * ```\n */\nexport function extractPublicKeyFromDid(did: string): JWK {\n if (!did.startsWith('did:jwk:')) {\n throw new Error('Only did:jwk format is supported')\n }\n\n const encoded = did.replace('did:jwk:', '')\n return JSON.parse(Buffer.from(encoded, 'base64url').toString()) as JWK\n}\n\n/**\n * Validate that a string is a valid did:jwk\n *\n * @param did - The string to validate\n * @returns true if valid did:jwk, false otherwise\n */\nexport function isValidDidJwk(did: string): boolean {\n if (!did.startsWith('did:jwk:')) {\n return false\n }\n\n try {\n const encoded = did.replace('did:jwk:', '')\n const decoded = JSON.parse(Buffer.from(encoded, 'base64url').toString())\n return typeof decoded === 'object' && decoded.kty !== undefined\n } catch {\n return false\n }\n}\n\n/**\n * Get the key ID (kid) from a did:jwk\n * Following the did:jwk specification, the key ID is the DID with #0 appended\n *\n * @param did - The did:jwk string\n * @returns The key ID\n */\nexport function getKeyIdFromDid(did: string): string {\n return `${did}#0`\n}\n\n/**\n * Compare two EC public key JWKs for equality.\n * Only compares canonical fields (kty, crv, x, y) to avoid\n * mismatches from optional fields like alg, use, kid, key_ops.\n * Returns false if any canonical field is missing or undefined.\n */\nexport function publicKeysMatch(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): boolean {\n if (!a.kty || !a.crv || !a.x || !a.y) return false\n if (!b.kty || !b.crv || !b.x || !b.y) return false\n return a.kty === b.kty && a.crv === b.crv && a.x === b.x && a.y === b.y\n}\n","import { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { createDidJwk, extractPublicKey } from '../did/did-utils'\n\n/**\n * Agent DID Manager\n * Manages DID generation and lifecycle for AI Agents specifically\n */\nexport class AgentDIDManager {\n private keyManager: KeyManager\n private agentDIDMap: Map<string, string> = new Map() // agentId -> DID mapping\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n }\n\n /**\n * Generate a new DID for an AI Agent\n */\n async generateAgentDID(agentId: string): Promise<string> {\n // Generate unique key pair for this agent\n const keyPair = await SDJwtClient.generateKeyPair()\n\n // Create did:jwk from public key\n const did = createDidJwk(keyPair.publicKey)\n\n // Store private key with agent-specific namespace\n await this.keyManager.storeKey(did, keyPair.privateKey)\n\n // Store agent ID -> DID mapping\n this.agentDIDMap.set(agentId, did)\n await this.saveAgentDIDMapping(agentId, did)\n\n return did\n }\n\n /**\n * Get DID for a specific agent\n */\n async getAgentDID(agentId: string): Promise<string> {\n // Check memory cache first\n if (this.agentDIDMap.has(agentId)) {\n return this.agentDIDMap.get(agentId)!\n }\n\n // Load from storage\n const did = await this.loadAgentDIDMapping(agentId)\n if (did) {\n this.agentDIDMap.set(agentId, did)\n return did\n }\n\n throw new Error(`No DID found for agent: ${agentId}`)\n }\n\n /**\n * Check if agent has a DID\n */\n async hasAgentDID(agentId: string): Promise<boolean> {\n try {\n await this.getAgentDID(agentId)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get agent's key pair\n */\n async getAgentKeyPair(agentId: string): Promise<any> {\n const did = await this.getAgentDID(agentId)\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error(`Private key not found for agent: ${agentId}`)\n }\n\n return {\n privateKey,\n publicKey: extractPublicKey(privateKey),\n }\n }\n\n /**\n * Delete agent DID and associated keys\n */\n async deleteAgentDID(agentId: string): Promise<void> {\n try {\n const did = await this.getAgentDID(agentId)\n\n // Delete private key\n await this.keyManager.deleteKey(did)\n\n // Remove from memory cache\n this.agentDIDMap.delete(agentId)\n\n // Remove from persistent storage\n await this.deleteAgentDIDMapping(agentId)\n } catch (error) {\n throw new Error(`Failed to delete agent DID: ${error}`)\n }\n }\n\n /**\n * List all agent DIDs\n */\n async listAgentDIDs(): Promise<Array<{ agentId: string; did: string }>> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingDir = path.join(os.homedir(), '.vess-aidentity', 'agent-dids')\n\n try {\n const files = await fs.readdir(mappingDir)\n const results: Array<{ agentId: string; did: string }> = []\n\n for (const file of files) {\n if (file.endsWith('.did')) {\n const agentId = file.replace('.did', '')\n try {\n const did = await this.getAgentDID(agentId)\n results.push({ agentId, did })\n } catch {\n // Skip invalid entries\n }\n }\n }\n\n return results\n } catch {\n return []\n }\n }\n\n\n /**\n * Save agent ID -> DID mapping to persistent storage\n */\n private async saveAgentDIDMapping(agentId: string, did: string): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingDir = path.join(os.homedir(), '.vess-aidentity', 'agent-dids')\n await fs.mkdir(mappingDir, { recursive: true })\n\n const mappingFile = path.join(mappingDir, `${agentId}.did`)\n await fs.writeFile(mappingFile, did, 'utf-8')\n }\n\n /**\n * Load agent ID -> DID mapping from persistent storage\n */\n private async loadAgentDIDMapping(agentId: string): Promise<string | null> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingFile = path.join(os.homedir(), '.vess', 'agent-dids', `${agentId}.did`)\n\n try {\n return await fs.readFile(mappingFile, 'utf-8')\n } catch {\n return null\n }\n }\n\n /**\n * Delete agent ID -> DID mapping from persistent storage\n */\n private async deleteAgentDIDMapping(agentId: string): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const mappingFile = path.join(os.homedir(), '.vess', 'agent-dids', `${agentId}.did`)\n\n try {\n await fs.unlink(mappingFile)\n } catch {\n // File might not exist, ignore\n }\n }\n}\n","import { Agent, DIDDocument } from '../types'\nimport { getDidApiUrl, getApiHeaders } from '../config'\nimport { KeyManager } from './key-manager'\nimport { AgentDIDManager } from '../agent/agent-did-manager'\nimport { v4 as uuidv4 } from 'uuid'\n\nexport class AgentManager {\n private keyManager: KeyManager\n private agentDIDManager: AgentDIDManager\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n this.agentDIDManager = new AgentDIDManager(this.keyManager)\n }\n\n /**\n * Create a new AI agent with unique ID and DID\n */\n async create(metadata?: Record<string, any>): Promise<Agent & { id: string }> {\n // Generate unique agent ID\n const agentId = uuidv4()\n\n // Generate dedicated DID for this agent\n const agentDid = await this.agentDIDManager.generateAgentDID(agentId)\n\n // Create DID Document for the agent\n const didDocument = this.resolveDidJwkLocally(agentDid)\n\n // Create agent with ID and DID\n const agent: Agent & { id: string } = {\n id: agentId,\n did: agentDid,\n didDocument,\n createdAt: new Date().toISOString(),\n metadata,\n }\n\n // Optionally register with DID API (if configured)\n try {\n await this.registerDid(agent)\n } catch (error) {\n console.warn('Failed to register DID with API:', error)\n // Continue even if registration fails - DID:jwk works locally\n }\n\n return agent\n }\n\n /**\n * Get agent DID by agent ID\n */\n async getAgentDID(agentId: string): Promise<string> {\n return await this.agentDIDManager.getAgentDID(agentId)\n }\n\n /**\n * Get agent by ID\n */\n async getAgent(agentId: string): Promise<Agent & { id: string }> {\n const agentDid = await this.agentDIDManager.getAgentDID(agentId)\n const didDocument = await this.resolve(agentDid)\n\n return {\n id: agentId,\n did: agentDid,\n didDocument,\n createdAt: new Date().toISOString(), // TODO: Store actual creation time\n }\n }\n\n /**\n * Delete an agent and its DID\n */\n async deleteAgent(agentId: string): Promise<void> {\n await this.agentDIDManager.deleteAgentDID(agentId)\n }\n\n /**\n * Resolve a DID to get DID Document\n */\n async resolve(did: string): Promise<DIDDocument> {\n // For did:jwk, we can resolve locally\n if (did.startsWith('did:jwk:')) {\n return this.resolveDidJwkLocally(did)\n }\n\n // Otherwise, call DID API\n try {\n const response = await fetch(getDidApiUrl(`/api/v1/did/${encodeURIComponent(did)}`), {\n headers: getApiHeaders('did'),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to resolve DID: ${response.statusText}`)\n }\n\n const data = (await response.json()) as any\n return data.didDocument\n } catch (error) {\n throw new Error(`Failed to resolve DID: ${error}`)\n }\n }\n\n /**\n * Export agent with private key (for backup)\n */\n async export(did: string): Promise<{ agent: Agent; privateKey: any }> {\n const didDocument = await this.resolve(did)\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error(`Private key not found for DID: ${did}`)\n }\n\n const agent: Agent = {\n did,\n didDocument,\n createdAt: new Date().toISOString(),\n }\n\n return { agent, privateKey }\n }\n\n /**\n * Import agent from backup\n */\n async import(agent: Agent, privateKey: any): Promise<void> {\n await this.keyManager.storeKey(agent.did, privateKey)\n }\n\n /**\n * List all locally stored agents\n */\n async list(): Promise<Array<Agent & { id: string }>> {\n const agentDIDs = await this.agentDIDManager.listAgentDIDs()\n const agents: Array<Agent & { id: string }> = []\n\n for (const { agentId, did } of agentDIDs) {\n try {\n const didDocument = await this.resolve(did)\n agents.push({\n id: agentId,\n did,\n didDocument,\n createdAt: new Date().toISOString(), // TODO: Store actual creation time\n })\n } catch (error) {\n console.warn(`Failed to resolve Agent DID ${did}:`, error)\n }\n }\n\n return agents\n }\n\n private createDidDocument(did: string, publicKey: any): DIDDocument {\n const verificationMethodId = `${did}#0`\n\n return {\n '@context': ['https://www.w3.org/ns/did/v1', 'https://w3id.org/security/suites/jws-2020/v1'],\n id: did,\n verificationMethod: [\n {\n id: verificationMethodId,\n type: 'JsonWebKey2020',\n controller: did,\n publicKeyJwk: publicKey,\n },\n ],\n authentication: [verificationMethodId],\n assertionMethod: [verificationMethodId],\n capabilityInvocation: [verificationMethodId],\n capabilityDelegation: [verificationMethodId],\n }\n }\n\n private resolveDidJwkLocally(did: string): DIDDocument {\n // Extract JWK from did:jwk\n const encoded = did.replace('did:jwk:', '')\n const publicJwk = JSON.parse(Buffer.from(encoded, 'base64url').toString())\n\n return this.createDidDocument(did, publicJwk)\n }\n\n private async registerDid(_agent: Agent): Promise<void> {\n // This would call the DID API to register the DID\n // Implementation depends on the actual API\n // For now, this is a placeholder\n }\n}\n","import { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { createDidJwk, extractPublicKey, extractPublicKeyFromDid } from '../did/did-utils'\nimport { DIDDocument } from '../types'\n\n/**\n * User Identity Manager\n * Manages DID generation and lifecycle for Users (Issuers) specifically\n * Separate from Agent management to avoid confusion\n */\nexport class UserIdentityManager {\n private keyManager: KeyManager\n private currentUserDID: string | null = null\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n }\n\n /**\n * Get or create current user DID\n * This represents the user who will be the issuer of VCs\n */\n async getCurrentUserDID(): Promise<string> {\n if (this.currentUserDID) {\n return this.currentUserDID\n }\n\n // Try to load existing user DID\n const existingDID = await this.loadUserDID()\n if (existingDID) {\n this.currentUserDID = existingDID\n return existingDID\n }\n\n // Create new user DID if none exists\n return await this.createUserDID()\n }\n\n /**\n * Create a new user DID (for issuing VCs)\n */\n async createUserDID(): Promise<string> {\n // Generate key pair for user identity\n const keyPair = await SDJwtClient.generateKeyPair()\n\n // Create did:jwk\n const did = createDidJwk(keyPair.publicKey)\n\n // Store private key\n await this.keyManager.storeKey(did, keyPair.privateKey)\n\n // Save as current user DID\n await this.saveUserDID(did)\n this.currentUserDID = did\n\n return did\n }\n\n /**\n * Get user's key pair\n */\n async getUserKeyPair(): Promise<any> {\n const did = await this.getCurrentUserDID()\n const privateKey = await this.keyManager.getKey(did)\n\n if (!privateKey) {\n throw new Error('User private key not found')\n }\n\n return {\n privateKey,\n publicKey: extractPublicKey(privateKey),\n }\n }\n\n /**\n * Resolve user DID to DID Document\n */\n async resolveUserDID(did?: string): Promise<DIDDocument> {\n const userDid = did || (await this.getCurrentUserDID())\n\n if (!userDid.startsWith('did:jwk:')) {\n throw new Error('Only did:jwk supported for user identity')\n }\n\n return this.resolveDidJwkLocally(userDid)\n }\n\n /**\n * Export user identity for backup\n */\n async exportUserIdentity(): Promise<{ did: string; privateKey: any; didDocument: DIDDocument }> {\n const did = await this.getCurrentUserDID()\n const privateKey = await this.keyManager.getKey(did)\n const didDocument = await this.resolveUserDID(did)\n\n if (!privateKey) {\n throw new Error('User private key not found')\n }\n\n return { did, privateKey, didDocument }\n }\n\n /**\n * Import user identity from backup\n */\n async importUserIdentity(backup: { did: string; privateKey: any }): Promise<void> {\n // Store the private key\n await this.keyManager.storeKey(backup.did, backup.privateKey)\n\n // Set as current user DID\n await this.saveUserDID(backup.did)\n this.currentUserDID = backup.did\n }\n\n /**\n * Reset user identity (create new DID)\n */\n async resetUserIdentity(): Promise<string> {\n // Clear current DID\n this.currentUserDID = null\n\n // Clear saved DID\n await this.clearUserDID()\n\n // Create new DID\n return await this.createUserDID()\n }\n\n\n /**\n * Resolve did:jwk locally\n */\n private resolveDidJwkLocally(did: string): DIDDocument {\n const publicJwk = extractPublicKeyFromDid(did)\n return this.createDidDocument(did, publicJwk)\n }\n\n /**\n * Create DID Document\n */\n private createDidDocument(did: string, publicKey: any): DIDDocument {\n const verificationMethodId = `${did}#0`\n\n return {\n '@context': ['https://www.w3.org/ns/did/v1', 'https://w3id.org/security/suites/jws-2020/v1'],\n id: did,\n verificationMethod: [\n {\n id: verificationMethodId,\n type: 'JsonWebKey2020',\n controller: did,\n publicKeyJwk: publicKey,\n },\n ],\n authentication: [verificationMethodId],\n assertionMethod: [verificationMethodId],\n capabilityInvocation: [verificationMethodId],\n capabilityDelegation: [verificationMethodId],\n }\n }\n\n /**\n * Save current user DID to persistent storage\n */\n private async saveUserDID(did: string): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const configDir = path.join(os.homedir(), '.vess-aidentity')\n await fs.mkdir(configDir, { recursive: true })\n\n const userDIDFile = path.join(configDir, 'user-did.txt')\n await fs.writeFile(userDIDFile, did, 'utf-8')\n }\n\n /**\n * Load current user DID from persistent storage\n */\n private async loadUserDID(): Promise<string | null> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const userDIDFile = path.join(os.homedir(), '.vess-aidentity', 'user-did.txt')\n\n try {\n return await fs.readFile(userDIDFile, 'utf-8')\n } catch {\n return null\n }\n }\n\n /**\n * Clear saved user DID\n */\n private async clearUserDID(): Promise<void> {\n const fs = await import('fs/promises')\n const path = await import('path')\n const os = await import('os')\n\n const userDIDFile = path.join(os.homedir(), '.vess-aidentity', 'user-did.txt')\n\n try {\n await fs.unlink(userDIDFile)\n } catch {\n // File might not exist, ignore\n }\n }\n}\n","import {\n DelegationVC,\n ToolPermissionVC,\n DataAccessVC,\n VCTemplate,\n} from '../types'\nimport { getIssuerApiUrl, getApiHeaders } from '../config'\nimport { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { AgentManager } from '../did/agent'\nimport { UserIdentityManager } from '../identity/user-identity-manager'\nimport type { DisclosureFrame } from '@sd-jwt/types'\n\nexport class VCManager {\n private keyManager: KeyManager\n private templates: Map<string, VCTemplate> = new Map()\n private agentManager: AgentManager\n private userIdentityManager: UserIdentityManager\n\n constructor(\n keyManager?: KeyManager,\n agentManager?: AgentManager,\n userIdentityManager?: UserIdentityManager\n ) {\n this.keyManager = keyManager || new KeyManager()\n this.agentManager = agentManager || new AgentManager(this.keyManager)\n this.userIdentityManager = userIdentityManager || new UserIdentityManager(this.keyManager)\n this.registerDefaultTemplates()\n }\n\n /**\n * Get fields that should be selectively disclosable based on VC type\n */\n private getSelectivelyDisclosableFields(template: string): string[] {\n switch (template) {\n case 'ToolPermissionVC':\n return ['tool', 'action', 'scope', 'conditions']\n case 'DataAccessVC':\n return ['resource', 'actions', 'scope', 'conditions']\n case 'OrganizationVC':\n return ['organizationId', 'employeeId', 'department', 'role', 'permissions']\n default:\n return []\n }\n }\n\n /**\n * Issue a Verifiable Credential as SD-JWT VC\n * Enhanced to support User/Agent DID separation\n */\n async issue(\n template: string,\n claims: any,\n options: {\n issuerDid?: string // User DID (if not provided, uses current user)\n subjectDid?: string // Subject DID (if not provided, uses issuer DID for backward compatibility)\n agentId?: string // Agent ID (auto-resolves to agent DID as subject)\n expiresIn?: string // e.g., '1h', '30d'\n }\n ): Promise<string> {\n const vcTemplate = this.templates.get(template)\n if (!vcTemplate) {\n throw new Error(`Unknown VC template: ${template}`)\n }\n\n // Determine issuer DID (User Identity)\n const issuerDid = options.issuerDid || (await this.userIdentityManager.getCurrentUserDID())\n\n // Determine subject DID\n let subjectDid: string\n if (options.agentId) {\n // Agent ID provided - resolve to agent DID\n subjectDid = await this.agentManager.getAgentDID(options.agentId)\n } else if (options.subjectDid) {\n // Explicit subject DID provided\n subjectDid = options.subjectDid\n } else {\n // Backward compatibility: use issuer DID as subject\n subjectDid = issuerDid\n }\n\n // Build VC payload according to SD-JWT VC spec\n const now = new Date()\n const iat = Math.floor(now.getTime() / 1000)\n\n // Prepare credential subject with claims\n const credentialSubject = {\n id: subjectDid,\n ...claims,\n }\n\n // Apply template defaults\n if (vcTemplate.defaults) {\n Object.assign(credentialSubject, vcTemplate.defaults)\n }\n\n // Build the VC payload for SD-JWT VC\n const vcPayload: any = {\n // SD-JWT VC specific fields\n vct: vcTemplate.type,\n iss: issuerDid,\n iat,\n cnf: {\n // Confirmation method - binding to subject's key\n jwk: await this.getSubjectPublicKey(subjectDid),\n },\n // Standard VC fields\n credentialSubject,\n }\n\n if (options.expiresIn) {\n const expDate = this.calculateExpirationDate(options.expiresIn)\n vcPayload.exp = Math.floor(expDate.getTime() / 1000)\n }\n\n // Validate with template\n const vc = {\n ...vcPayload,\n '@context': ['https://www.w3.org/ns/credentials/v2'],\n issuer: issuerDid,\n validFrom: now.toISOString(),\n } as DelegationVC\n\n if (vcTemplate.validate && !vcTemplate.validate(vc as any)) {\n throw new Error('VC validation failed')\n }\n\n // Set up SDJwtClient with KeyManager\n SDJwtClient.setKeyManager(this.keyManager)\n\n // Get SD-JWT VC instance for this issuer\n const sdjwtInstance = await SDJwtClient.getIssuerInstance(issuerDid)\n\n // Get selectively disclosable fields for this VC type\n const selectivelyDisclosableFields = this.getSelectivelyDisclosableFields(template)\n\n // Create disclosure frame for the entire payload\n // The credentialSubject should have its own _sd array\n const credentialSubjectFrame = SDJwtClient.createDisclosureFrame(\n credentialSubject,\n selectivelyDisclosableFields\n )\n\n // Create the main disclosure frame that targets credentialSubject\n const disclosureFrame = {\n credentialSubject: credentialSubjectFrame,\n }\n\n // Issue the SD-JWT VC\n //@ts-ignore\n const sdjwtVc = await sdjwtInstance.issue(\n vcPayload,\n disclosureFrame as DisclosureFrame<typeof vcPayload>\n )\n\n return sdjwtVc\n }\n\n /**\n * Get subject's public key for cnf claim\n */\n private async getSubjectPublicKey(subjectDid: string): Promise<any> {\n // Extract JWK from did:jwk DID\n if (!subjectDid.startsWith('did:jwk:')) {\n throw new Error(`Unsupported DID method. Expected did:jwk, got: ${subjectDid}`)\n }\n\n try {\n // Extract the base64url-encoded JWK from the DID\n const jwkEncoded = subjectDid.replace('did:jwk:', '')\n const jwkJson = Buffer.from(jwkEncoded, 'base64url').toString('utf-8')\n const jwk = JSON.parse(jwkJson)\n\n // Return only the public key components (remove private key 'd' if present)\n const { d, key_ops, ...publicJwk } = jwk\n\n // Ensure it has the correct key operations for verification\n const publicKeyForCnf = {\n ...publicJwk,\n // Remove key_ops entirely for cnf claim as it's not needed there\n }\n\n return publicKeyForCnf\n } catch (error) {\n throw new Error(\n `Failed to extract JWK from did:jwk: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n }\n }\n\n /**\n * Issue using existing Issuer API (OID4VCI)\n */\n async issueViaAPI(\n credentialType: string,\n claims: any,\n options: {\n issuerDid: string\n subjectDid: string\n }\n ): Promise<string> {\n // First get credential offer\n const offerResponse = await fetch(getIssuerApiUrl('/api/v1/credential/offer'), {\n method: 'POST',\n headers: getApiHeaders('issuer'),\n body: JSON.stringify({\n credentialType,\n claims,\n subjectDid: options.subjectDid,\n }),\n })\n\n if (!offerResponse.ok) {\n throw new Error(`Failed to get credential offer: ${offerResponse.statusText}`)\n }\n\n const offer = (await offerResponse.json()) as { id: string }\n\n // Then acquire credential\n const acquireResponse = await fetch(getIssuerApiUrl('/api/v1/credential/acquire'), {\n method: 'POST',\n headers: getApiHeaders('issuer'),\n body: JSON.stringify({\n offerId: offer.id,\n holderDid: options.subjectDid,\n }),\n })\n\n if (!acquireResponse.ok) {\n throw new Error(`Failed to acquire credential: ${acquireResponse.statusText}`)\n }\n\n const credential = (await acquireResponse.json()) as { jwt: string }\n return credential.jwt\n }\n\n /**\n * Verify a SD-JWT VC\n */\n async verify(\n sdjwtVc: string,\n options?: {\n expectedIssuer?: string\n expectedSubject?: string\n requiredClaims?: string[] // Claims that must be disclosed\n }\n ): Promise<any> {\n // Parse to get issuer from the SD-JWT\n const parts = sdjwtVc.split('~')\n const jwt = parts[0]\n const jwtParts = jwt.split('.')\n const payload = JSON.parse(Buffer.from(jwtParts[1], 'base64url').toString())\n\n const issuerDid = payload.iss\n if (!issuerDid) {\n throw new Error('Issuer DID not found in SD-JWT VC')\n }\n\n // Validate expected issuer if provided\n if (options?.expectedIssuer && issuerDid !== options.expectedIssuer) {\n throw new Error(`Issuer mismatch: expected ${options.expectedIssuer}, got ${issuerDid}`)\n }\n\n // Set up SDJwtClient\n SDJwtClient.setKeyManager(this.keyManager)\n\n // Get SD-JWT VC instance for this issuer\n const sdjwtInstance = await SDJwtClient.getIssuerInstance(issuerDid)\n\n // Verify the SD-JWT VC\n const { payload: verifiedPayload } = await sdjwtInstance.verify(\n sdjwtVc,\n options?.requiredClaims ? { requiredClaimKeys: options?.requiredClaims } : undefined\n )\n\n const disclosures = await sdjwtInstance.getClaims(sdjwtVc)\n\n // Validate expected subject if provided\n const subjectId = (verifiedPayload?.credentialSubject as any)?.id || verifiedPayload.sub\n if (options?.expectedSubject) {\n if (subjectId !== options.expectedSubject) {\n throw new Error(`Subject mismatch: expected ${options.expectedSubject}, got ${subjectId}`)\n }\n }\n\n // Return the verified payload and disclosures\n return {\n payload: verifiedPayload,\n disclosures,\n issuer: issuerDid,\n subject: subjectId,\n issuedAt: verifiedPayload?.iat && new Date(verifiedPayload.iat * 1000),\n expiresAt: verifiedPayload.exp ? new Date(verifiedPayload.exp * 1000) : null,\n }\n }\n\n /**\n * Revoke a Verifiable Credential\n */\n async revoke(_vcId: string, _issuerDid: string): Promise<void> {\n // TODO: Call StatusList API to revoke\n throw new Error('VC revocation not yet implemented')\n }\n\n /**\n * Register a custom VC template\n */\n registerTemplate(template: VCTemplate): void {\n this.templates.set(template.name, template)\n }\n\n private registerDefaultTemplates(): void {\n // ToolPermissionVC template\n this.templates.set('ToolPermissionVC', {\n type: 'ToolPermissionVC',\n name: 'ToolPermissionVC',\n description: 'Permission to use a specific tool',\n validate: (vc: DelegationVC) => {\n const toolVc = vc as ToolPermissionVC\n return !!(toolVc.credentialSubject.tool && toolVc.credentialSubject.aud)\n },\n })\n\n // DataAccessVC template\n this.templates.set('DataAccessVC', {\n type: 'DataAccessVC',\n name: 'DataAccessVC',\n description: 'Permission to access data resources',\n validate: (vc: DelegationVC) => {\n const dataVc = vc as DataAccessVC\n return !!(\n dataVc.credentialSubject.resource &&\n dataVc.credentialSubject.actions &&\n dataVc.credentialSubject.actions.length > 0\n )\n },\n })\n }\n\n private calculateExpirationDate(expiresIn: string): Date {\n const now = new Date()\n const match = expiresIn.match(/^(\\d+)([hdm])$/)\n\n if (!match) {\n throw new Error(`Invalid expiresIn format: ${expiresIn}`)\n }\n\n const value = parseInt(match[1])\n const unit = match[2]\n\n switch (unit) {\n case 'h':\n now.setHours(now.getHours() + value)\n break\n case 'd':\n now.setDate(now.getDate() + value)\n break\n case 'm':\n now.setMinutes(now.getMinutes() + value)\n break\n default:\n throw new Error(`Unknown time unit: ${unit}`)\n }\n\n return now\n }\n}\n","import { VerifiablePresentation, VPRequest } from '../types'\nimport { generateNonce } from '../utils/crypto'\nimport { KeyManager } from '../did/key-manager'\nimport { getVerifierApiUrl, getApiHeaders } from '../config'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { digest } from '@sd-jwt/crypto-nodejs'\nimport { buildKbJwtPayload } from './kb-jwt-builder'\n\nexport class VPManager {\n private keyManager: KeyManager\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n // Initialize SDJwtClient with KeyManager\n SDJwtClient.setKeyManager(this.keyManager)\n }\n\n /**\n * Create a SD-JWT presentation using the present() method\n * This properly binds the holder's key to the SD-JWT VC\n */\n async create(\n vcs: string[], // Array of SD-JWT VC strings\n options: {\n holderDid: string\n challenge: string // nonce\n domain: string\n purpose?: string\n }\n ): Promise<string> {\n if (vcs.length === 0) {\n throw new Error('At least one SD-JWT VC is required for presentation')\n }\n\n // Get SDJwtClient instance for the holder DID\n const sdJwtInstance = await SDJwtClient.getHolderInstance(options.holderDid)\n\n // Use the first SD-JWT VC for presentation\n const sdJwtVC = vcs[0]\n\n try {\n // First decode the SD-JWT VC to get available claims\n const decodedVC = await sdJwtInstance.decode(sdJwtVC)\n\n // Get all presentable keys (we'll present all available claims)\n const presentableKeys = await decodedVC.presentableKeys(digest)\n\n // Create presentation frame to present ALL available claims\n // This is a simplified approach - in production you'd be selective\n const presentationFrame: Record<string, boolean> = {}\n presentableKeys.forEach((key: string) => {\n presentationFrame[key] = true\n })\n\n const kbJwtPayload = buildKbJwtPayload({\n holderDid: options.holderDid,\n audience: options.domain,\n nonce: options.challenge,\n vcCredential: sdJwtVC,\n })\n\n // Create a presentation using the issued credential and the presentation frame\n // The third parameter is the KB-JWT payload for holder binding\n const presentation = await sdJwtInstance.present(sdJwtVC, presentationFrame, {\n kb: { payload: kbJwtPayload },\n })\n\n return presentation\n } catch (error: any) {\n console.error('ERROR: Error creating SD-JWT presentation:', error)\n throw new Error(`Failed to create SD-JWT presentation: ${error.message}`)\n }\n }\n\n /**\n * Verify a Verifiable Presentation\n */\n async verify(\n vpJwt: string,\n options: {\n expectedChallenge: string\n expectedDomain: string\n expectedHolder?: string\n }\n ): Promise<VerifiablePresentation> {\n // Call Verifier API\n const response = await fetch(getVerifierApiUrl('/api/v1/vp/verify'), {\n method: 'POST',\n headers: getApiHeaders('verifier'),\n body: JSON.stringify({\n vp: vpJwt,\n challenge: options.expectedChallenge,\n domain: options.expectedDomain,\n }),\n })\n\n if (!response.ok) {\n throw new Error(`VP verification failed: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n\n if (!result?.valid) {\n throw new Error(`VP verification failed: ${result?.error}`)\n }\n\n // Additional local verification\n const vp = result?.verifiablePresentation as VerifiablePresentation\n\n if (options.expectedHolder && vp.holder !== options.expectedHolder) {\n throw new Error(`Holder mismatch. Expected: ${options.expectedHolder}, Got: ${vp.holder}`)\n }\n\n if (vp.proof?.challenge !== options.expectedChallenge) {\n throw new Error('Challenge mismatch')\n }\n\n if (vp.proof?.domain !== options.expectedDomain) {\n throw new Error('Domain mismatch')\n }\n\n return vp\n }\n\n /**\n * Create a VP request\n */\n createRequest(\n domain: string,\n query?: {\n type?: string\n credentialQuery?: any\n }\n ): VPRequest {\n return {\n challenge: generateNonce(),\n domain,\n query,\n }\n }\n\n /**\n * Submit VP to a verifier\n */\n async submit(\n vpJwt: string,\n verifierEndpoint: string\n ): Promise<{ verified: boolean; result?: any }> {\n const response = await fetch(verifierEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ vp: vpJwt }),\n })\n\n if (!response.ok) {\n throw new Error(`Failed to submit VP: ${response.statusText}`)\n }\n\n return response.json() as any\n }\n}\n","/**\n * Single source of truth for Key Binding JWT (KB-JWT) issuance shared across\n * the AIdentity stack. Four production code paths build KB-JWTs and they\n * MUST stay byte-for-byte equivalent so a presentation built on one side is\n * accepted by the verifier on the other:\n *\n * - SDK clients via `VPManager.create()` (this package)\n * - API service via `packages/api/src/vp/vp-creation.service.ts`\n * - Remote MCP via `packages/remote-mcp/src/services/vp-creation.service.ts`\n * - agentd (`@vess-id/vess`) via `VPBuilder.buildVP()`\n * (`packages/agentd/src/wallet/vp-builder.ts`)\n *\n * Historically each path had its own copy of this logic. PR #391 (the\n * commit that made `exp` REQUIRED on the verifier side) updated only two of\n * the three issuer paths known at the time; the SDK was missed and every\n * SDK-built VP started failing at verification time. The follow-up\n * consolidation (commit 02b169aa) brought the SDK in line, but agentd —\n * which had its own KB-JWT literal in `wallet/vp-builder.ts` — was not\n * recognized as a fourth issuer. Staging then rejected every VP from\n * `@vess-id/vess` agentd alpha builds with `KB-JWT missing exp` until the\n * agentd hotfix (this commit's cohort) wired its VPBuilder through\n * `buildKbJwtPayload()`. This module exists so that a future verifier\n * change cannot drift from the issuer side: any update lands in one place\n * and all four paths inherit it.\n */\n\n/**\n * Default KB-JWT lifetime in seconds. Mirrors the cap enforced by the API's\n * `KeyBindingVerifierService.MAX_KB_JWT_LIFETIME_SECONDS` (also 300).\n *\n * The KB-JWT `exp` is the smaller of:\n * - `iat + KB_JWT_DEFAULT_LIFETIME_SECONDS`\n * - the parent VC's `exp` (so the bearer's freshness window cannot outlive\n * the underlying credential's validity, which is itself bounded by\n * `grant.expiresAt` at issuance time).\n */\nexport const KB_JWT_DEFAULT_LIFETIME_SECONDS = 300\n\nexport interface KbJwtPayload {\n iss: string\n aud: string\n nonce: string\n iat: number\n exp: number\n}\n\nexport interface BuildKbJwtPayloadArgs {\n /** Holder DID — becomes the KB-JWT `iss` claim. */\n holderDid: string\n /** Verifier audience (URL or hostname). Will be normalized via {@link normalizeDomain}. */\n audience: string\n /** Verifier-supplied nonce / challenge. */\n nonce: string\n /** The parent SD-JWT VC string. Its `exp` (if any) caps the KB-JWT lifetime. */\n vcCredential: string\n}\n\nexport interface BuildKbJwtPayloadDeps {\n /** Returns the current time in milliseconds. Defaults to `Date.now`. */\n now?: () => number\n}\n\n/**\n * Build a Key Binding JWT payload for an SD-JWT VC presentation.\n *\n * Throws when the parent VC is already expired (`vc.exp <= now`). The error\n * message intentionally contains the substring `\"VC has expired\"` so that\n * downstream catchers (notably remote-mcp's `isCredentialInvalidError`) can\n * detect a stale-credential condition and trigger a re-approval flow rather\n * than surface an opaque issuance failure to the user.\n */\nexport function buildKbJwtPayload(\n args: BuildKbJwtPayloadArgs,\n deps: BuildKbJwtPayloadDeps = {},\n): KbJwtPayload {\n const now = deps.now ?? Date.now\n // deps.now() is milliseconds (per Date.now contract); KB-JWT iat is seconds.\n const iatSeconds = Math.floor(now() / 1000)\n const kbExpCap = iatSeconds + KB_JWT_DEFAULT_LIFETIME_SECONDS\n const vcExp = readVcExpSeconds(args.vcCredential)\n const expSeconds = vcExp !== undefined ? Math.min(kbExpCap, vcExp) : kbExpCap\n\n if (expSeconds <= iatSeconds) {\n throw new Error(\n `VC has expired: cannot issue KB-JWT (vc.exp=${vcExp}, now=${iatSeconds})`,\n )\n }\n\n return {\n iss: args.holderDid,\n aud: normalizeDomain(args.audience),\n nonce: args.nonce,\n iat: iatSeconds,\n exp: expSeconds,\n }\n}\n\n/**\n * Best-effort read of the VC's `exp` claim from the SD-JWT outer payload.\n * Returns undefined when the VC is malformed, missing exp, or the field is\n * not a number — callers fall back to {@link KB_JWT_DEFAULT_LIFETIME_SECONDS}\n * in that case so issuance does not break for VCs without an explicit expiry.\n */\nexport function readVcExpSeconds(sdJwtVc: string): number | undefined {\n try {\n const jwtPart = sdJwtVc.split('~')[0]\n const payloadB64 = jwtPart.split('.')[1]\n if (!payloadB64) return undefined\n const payload = JSON.parse(Buffer.from(payloadB64, 'base64url').toString())\n return typeof payload.exp === 'number' ? payload.exp : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Normalize a domain string for consistent use as a JWT `aud` claim.\n *\n * The API verifier compares the KB-JWT `aud` against the expected domain by\n * exact string match, so issuer and verifier must agree on the canonical\n * form. We delegate to the URL parser, which strips paths and lowercases\n * the host, then return the resulting `origin`.\n *\n * Inputs without a scheme are assumed to be hostnames; `localhost` (with or\n * without a port) defaults to `http://`, everything else to `https://`. If\n * URL parsing fails, the input is returned unchanged so a caller can still\n * detect the mismatch downstream rather than silently swallowing a typo.\n */\nexport function normalizeDomain(domain: string): string {\n if (!domain) return domain\n\n let urlStr: string\n if (/^https?:\\/\\//i.test(domain)) {\n urlStr = domain\n } else {\n const scheme = /^localhost(:\\d+)?$/i.test(domain) ? 'http' : 'https'\n urlStr = `${scheme}://${domain}`\n }\n\n try {\n return new URL(urlStr).origin\n } catch {\n return domain\n }\n}\n","import { ConnectorResponse } from '../types'\nimport { VPManager } from '../vp/vp-manager'\nimport { getConfig } from '../config'\n\nexport interface ToolDefinition {\n name: string\n description: string\n actions: {\n name: string\n description: string\n parameters: Record<string, any>\n }[]\n}\n\nexport class ToolManager {\n private vpManager: VPManager\n private tools: Map<string, ToolDefinition> = new Map()\n private proxyApiUrl: string\n\n constructor(vpManager?: VPManager) {\n this.vpManager = vpManager || new VPManager()\n const config = getConfig()\n this.proxyApiUrl = config.proxyApi?.baseUrl || 'http://localhost:3000'\n this.registerDefaultTools()\n }\n\n /**\n * Invoke a tool action with VC authorization\n */\n async invoke<T = any>(\n tool: string,\n action: string,\n params: Record<string, any>,\n options: {\n vcs: string[] // VC JWTs authorizing this action\n holderDid: string\n }\n ): Promise<ConnectorResponse<T>> {\n // Validate tool exists\n const toolDef = this.tools.get(tool)\n if (!toolDef) {\n throw new Error(`Unknown tool: ${tool}`)\n }\n\n // Validate action exists\n const actionDef = toolDef.actions.find(a => a.name === action)\n if (!actionDef) {\n throw new Error(`Unknown action ${action} for tool ${tool}`)\n }\n\n // Create VP for this invocation\n const domain = new URL(this.proxyApiUrl).hostname\n const challenge = this.generateChallenge()\n\n const vpJwt = await this.vpManager.create(options.vcs, {\n holderDid: options.holderDid,\n challenge,\n domain,\n purpose: 'invocation',\n })\n\n // Mock mode for demo - avoid API calls\n if (this.proxyApiUrl === 'mock://demo') {\n // Return mock response for demo purposes\n const mockResponse: ConnectorResponse<T> = {\n success: true,\n data: {\n message: 'Mock Slack response - message posted successfully!',\n channel: params.channel || '#general',\n text: params.text || 'Hello from AIdentity!',\n ts: Date.now().toString(),\n ok: true,\n } as T,\n metadata: {\n tool,\n action,\n holder: options.holderDid,\n timestamp: new Date().toISOString(),\n mock: true,\n },\n }\n\n // Simulate API delay\n await new Promise(resolve => setTimeout(resolve, 500))\n return mockResponse\n }\n\n // Call Proxy API - check if we need to send VCs separately\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${vpJwt}`,\n 'X-Holder-DID': options.holderDid,\n 'X-Auth-Challenge': challenge,\n }\n\n // Only send X-VCs header if vpJwt doesn't contain ~ (not a full SD-JWT presentation)\n if (!vpJwt.includes('~')) {\n headers['X-VCs'] = JSON.stringify(options.vcs)\n }\n\n const response = await fetch(`${this.proxyApiUrl}/api/v1/tool/invoke`, {\n method: 'POST',\n headers,\n body: JSON.stringify({\n tool,\n action,\n params,\n challenge,\n }),\n })\n\n if (!response.ok) {\n // Try to parse JSON error response first to preserve metadata (e.g., reauthRequired)\n const contentType = response.headers.get('content-type')\n if (contentType && contentType.includes('application/json')) {\n try {\n const errorResponse = await response.json() as any\n // If the error response already has the ConnectorResponse structure, return it\n if (errorResponse.success === false) {\n return errorResponse as ConnectorResponse<T>\n }\n // Otherwise, wrap it\n return {\n success: false,\n error: errorResponse.message || errorResponse.error || 'Tool invocation failed',\n metadata: errorResponse.metadata,\n }\n } catch (parseError) {\n // If JSON parsing fails, fall back to text\n const error = await response.text()\n return {\n success: false,\n error: `Tool invocation failed: ${error}`,\n }\n }\n } else {\n // Non-JSON response, use text\n const error = await response.text()\n return {\n success: false,\n error: `Tool invocation failed: ${error}`,\n }\n }\n }\n\n const result = await response.json()\n return result as ConnectorResponse<T>\n }\n\n /**\n * List available tools\n */\n list(): ToolDefinition[] {\n return Array.from(this.tools.values())\n }\n\n /**\n * Get a specific tool definition\n */\n getTool(name: string): ToolDefinition | undefined {\n return this.tools.get(name)\n }\n\n /**\n * Register a custom tool\n */\n registerTool(tool: ToolDefinition): void {\n this.tools.set(tool.name, tool)\n }\n\n /**\n * Check if VCs authorize a tool action\n */\n async checkAuthorization(\n vcs: string[],\n tool: string,\n action: string,\n resourceScope?: Record<string, any>\n ): Promise<boolean> {\n // Parse VCs and check permissions\n // This is a simplified check - real implementation would verify signatures\n for (const vcJwt of vcs) {\n try {\n const parts = vcJwt.split('.')\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString())\n\n if (payload.credentialSubject?.tool === `${tool}.${action}`) {\n // Check resource scope if provided\n if (resourceScope) {\n const vcScope = payload.credentialSubject.resourceScope\n if (!this.matchScope(vcScope, resourceScope)) {\n continue\n }\n }\n return true\n }\n } catch {\n continue\n }\n }\n return false\n }\n\n private matchScope(vcScope: Record<string, any>, requiredScope: Record<string, any>): boolean {\n // Simple scope matching - can be enhanced\n for (const [key, value] of Object.entries(requiredScope)) {\n if (vcScope[key] !== value && vcScope[key] !== '*') {\n return false\n }\n }\n return true\n }\n\n private generateChallenge(): string {\n return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)\n }\n\n private registerDefaultTools(): void {\n // Slack tool\n this.tools.set('slack', {\n name: 'slack',\n description: 'Slack workspace operations',\n actions: [\n {\n name: 'slack.message.post',\n description: 'Post a message to a channel',\n parameters: {\n channel: 'string',\n text: 'string',\n thread_ts: 'string?',\n },\n },\n {\n name: 'slack.channel.read',\n description: 'List channels',\n parameters: {},\n },\n {\n name: 'slack.user.read',\n description: 'Get user information',\n parameters: {\n userId: 'string',\n },\n },\n {\n name: 'slack.message.read',\n description: 'Get channel history',\n parameters: {\n channel: 'string',\n latest: 'string?',\n oldest: 'string?',\n limit: 'number?',\n inclusive: 'boolean?',\n },\n },\n ],\n })\n\n // GitHub tool\n this.tools.set('github', {\n name: 'github',\n description: 'GitHub repository operations',\n actions: [\n {\n name: 'github.issue.create',\n description: 'Create a new issue',\n parameters: {\n owner: 'string',\n repo: 'string',\n title: 'string',\n body: 'string',\n labels: 'string[]?',\n },\n },\n {\n name: 'github.issue.list',\n description: 'List repository issues',\n parameters: {\n owner: 'string',\n repo: 'string',\n state: 'string?',\n },\n },\n {\n name: 'github.repo.read',\n description: 'Get repository information',\n parameters: {\n owner: 'string',\n repo: 'string',\n },\n },\n ],\n })\n\n // Gmail tool\n this.tools.set('gmail', {\n name: 'gmail',\n description: 'Gmail operations',\n actions: [\n {\n name: 'gmail.message.send',\n description: 'Send an email message',\n parameters: {\n to: 'string',\n subject: 'string',\n body: 'string',\n cc: 'string[]?',\n bcc: 'string[]?',\n format: 'string?',\n },\n },\n {\n name: 'gmail.message.list',\n description: 'Get email messages',\n parameters: {\n query: 'string?',\n maxResults: 'number?',\n pageToken: 'string?',\n labelIds: 'string[]?',\n },\n },\n {\n name: 'gmail.message.read',\n description: 'Get a specific email message',\n parameters: {\n messageId: 'string',\n format: 'string?',\n },\n },\n {\n name: 'gmail.label.read',\n description: 'Get available labels',\n parameters: {},\n },\n {\n name: 'gmail.message.search',\n description: 'Search email messages',\n parameters: {\n query: 'string',\n maxResults: 'number?',\n pageToken: 'string?',\n },\n },\n {\n name: 'gmail.message.update',\n description: 'Modify message labels',\n parameters: {\n messageId: 'string',\n addLabelIds: 'string[]?',\n removeLabelIds: 'string[]?',\n },\n },\n {\n name: 'gmail.draft.create',\n description: 'Create a draft email',\n parameters: {\n to: 'string',\n subject: 'string',\n body: 'string',\n cc: 'string[]?',\n bcc: 'string[]?',\n format: 'string?',\n },\n },\n ],\n })\n\n // Jira tool\n this.tools.set('jira', {\n name: 'jira',\n description: 'Jira project and issue management',\n actions: [\n {\n name: 'jira.project.read',\n description: 'List all Jira projects',\n parameters: {\n recent: 'number?',\n },\n },\n {\n name: 'jira.board.read',\n description: 'Get Jira board details',\n parameters: {\n boardId: 'number',\n },\n },\n {\n name: 'jira.board.list',\n description: 'List all Jira boards',\n parameters: {\n projectKeyOrId: 'string?',\n type: 'string?',\n },\n },\n {\n name: 'jira.sprint.read',\n description: 'Get sprints for a Jira board',\n parameters: {\n boardId: 'number',\n state: 'string?',\n },\n },\n {\n name: 'jira.issue.list',\n description: 'Get issues in a specific sprint',\n parameters: {\n sprintId: 'number',\n maxResults: 'number?',\n },\n },\n {\n name: 'jira.issue.search',\n description: 'Search for Jira issues using JQL',\n parameters: {\n jql: 'string',\n maxResults: 'number?',\n startAt: 'number?',\n },\n },\n {\n name: 'jira.issue.read',\n description: 'Get a specific Jira issue',\n parameters: {\n issueIdOrKey: 'string',\n },\n },\n {\n name: 'jira.worklog.read',\n description: 'Get worklogs for a specific issue',\n parameters: {\n issueKey: 'string',\n },\n },\n {\n name: 'jira.issue.create',\n description: 'Create a new Jira issue',\n parameters: {\n projectKey: 'string',\n summary: 'string',\n description: 'string?',\n issueTypeName: 'string',\n priority: 'string?',\n assignee: 'string?',\n },\n },\n ],\n })\n }\n}\n","import { VPManager } from '../vp/vp-manager'\nimport { getDidApiUrl } from '../config'\nimport {\n Grant,\n GrantStatus,\n CreateGrantRequest,\n UpdateGrantRequest,\n CheckGrantPermissionRequest,\n CheckGrantPermissionResult,\n} from '../types'\n\n/**\n * Grant提案レスポンス\n */\nexport interface GrantSuggestion {\n id: string\n oauthTokenId: string\n userId?: string\n projectId: string\n provider: string\n suggestedActions: string[]\n suggestedResources: Array<{\n type: string\n id?: string\n pattern?: string\n name?: string\n }>\n metadata: {\n providerInfo: any\n scopes: string[]\n }\n createdAt: string\n}\n\n/**\n * Grant提案確認リクエスト\n */\nexport interface ConfirmGrantRequest {\n suggestionId: string\n selectedActions: string[]\n selectedResources: Array<{\n type: string\n id?: string\n pattern?: string\n name?: string\n selected: boolean\n }>\n constraints: {\n maxInvocations?: number\n expiresAt?: string\n timeWindow?: {\n start: string\n end: string\n timezone: string\n daysOfWeek: number[]\n }\n }\n name?: string\n description?: string\n}\n\n/**\n * GrantManager\n * Grants APIを操作するSDKクライアント\n */\nexport class GrantManager {\n constructor(_vpManager: VPManager) {\n // vpManager might be used in future for VP creation\n }\n\n /**\n * Grant提案を取得\n * @param options - 提案オプション\n * @param options.oauthTokenId - OAuthトークンID\n * @param options.userId - 対象ユーザーID\n * @param options.projectId - プロジェクトID\n * @param authOptions - 認証オプション(VP or issuerDid)\n */\n async suggest(\n options: {\n oauthTokenId: string\n userId: string\n projectId: string\n },\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<GrantSuggestion> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl('/api/v1/grants/suggest'), {\n method: 'POST',\n headers,\n body: JSON.stringify(options),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to get grant suggestion: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grant提案を確認して作成\n * @param request - 確認リクエスト\n * @param authOptions - 認証オプション\n */\n async confirm(\n request: ConfirmGrantRequest,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl('/api/v1/grants/confirm'), {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to confirm grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grantを直接作成\n * @param request - Grant作成リクエスト\n * @param authOptions - 認証オプション\n */\n async create(\n request: CreateGrantRequest,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl('/api/v1/grants'), {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to create grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * ユーザー用のGrant一覧を取得\n * @param userId - ユーザーID\n * @param status - フィルタするステータス(オプション)\n */\n async listForUser(\n userId: string,\n status?: GrantStatus\n ): Promise<{ grants: Grant[]; total: number }> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const encodedUserId = encodeURIComponent(userId)\n const url = status\n ? getDidApiUrl(`/api/v1/grants/user/${encodedUserId}?status=${status}`)\n : getDidApiUrl(`/api/v1/grants/user/${encodedUserId}`)\n\n const response = await fetch(url, {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to list grants for user: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Issuer用のGrant一覧を取得\n * @param issuerDid - IssuerのDID\n * @param status - フィルタするステータス(オプション)\n */\n async listForIssuer(\n issuerDid: string,\n status?: GrantStatus\n ): Promise<{ grants: Grant[]; total: number }> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const encodedDid = encodeURIComponent(issuerDid)\n const url = status\n ? getDidApiUrl(`/api/v1/grants/issuer/${encodedDid}?status=${status}`)\n : getDidApiUrl(`/api/v1/grants/issuer/${encodedDid}`)\n\n const response = await fetch(url, {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to list grants for issuer: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grantを取得\n * @param grantId - GrantのID\n */\n async get(grantId: string): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const response = await fetch(getDidApiUrl(`/api/v1/grants/${grantId}`), {\n method: 'GET',\n headers,\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to get grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grantを取り消し\n * @param grantId - GrantのID\n * @param reason - 取り消し理由\n * @param authOptions - 認証オプション\n */\n async revoke(\n grantId: string,\n reason: string,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl(`/api/v1/grants/${grantId}`), {\n method: 'DELETE',\n headers,\n body: JSON.stringify({ reason }),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to revoke grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grant権限をチェック\n * @param request - 権限チェックリクエスト\n */\n async checkPermission(\n request: CheckGrantPermissionRequest\n ): Promise<CheckGrantPermissionResult> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n const response = await fetch(getDidApiUrl('/api/v1/grants/check'), {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to check grant permission: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n\n /**\n * Grant更新\n * @param grantId - GrantのID\n * @param request - 更新リクエスト\n * @param authOptions - 認証オプション\n */\n async update(\n grantId: string,\n request: UpdateGrantRequest,\n authOptions: {\n vpJwt?: string\n issuerDid?: string\n }\n ): Promise<Grant> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (authOptions.vpJwt) {\n headers['Authorization'] = `Bearer ${authOptions.vpJwt}`\n } else if (authOptions.issuerDid) {\n headers['x-issuer-did'] = authOptions.issuerDid\n } else {\n throw new Error('Either vpJwt or issuerDid is required for authentication')\n }\n\n const response = await fetch(getDidApiUrl(`/api/v1/grants/${grantId}`), {\n method: 'PUT',\n headers,\n body: JSON.stringify(request),\n })\n\n if (!response.ok) {\n const error = (await response.json()) as any\n throw new Error(error.error || `Failed to update grant: ${response.statusText}`)\n }\n\n const result = (await response.json()) as any\n return result.data\n }\n}\n","import { AIdentityConfig, configure } from './config'\nimport { AgentManager } from './did/agent'\nimport { KeyManager } from './did/key-manager'\nimport { UserIdentityManager } from './identity/user-identity-manager'\nimport { VCManager } from './vc/vc-manager'\nimport { VPManager } from './vp/vp-manager'\nimport { ToolManager } from './tool/tool-manager'\nimport { GrantManager } from './grant/grant-manager'\nimport { Agent, ConnectorResponse } from './types'\n\nexport class AIdentityClient {\n public readonly agent: AgentManager\n public readonly user: UserIdentityManager\n public readonly vc: VCManager\n public readonly vp: VPManager\n public readonly tool: ToolManager\n public readonly grant: GrantManager\n\n private keyManager: KeyManager\n private currentAgent?: Agent\n\n constructor(config?: AIdentityConfig, password?: string) {\n if (config) {\n configure(config)\n }\n\n // Initialize key manager with optional password for encryption\n this.keyManager = new KeyManager(password)\n\n // Initialize managers\n this.agent = new AgentManager(this.keyManager)\n this.user = new UserIdentityManager(this.keyManager)\n this.vc = new VCManager(this.keyManager, this.agent, this.user)\n this.vp = new VPManager(this.keyManager)\n this.tool = new ToolManager(this.vp)\n this.grant = new GrantManager(this.vp)\n }\n\n /**\n * Quick setup: Create or load an agent\n */\n async setup(did?: string): Promise<Agent> {\n if (did) {\n // Load existing agent\n this.currentAgent = await this.agent.export(did).then(({ agent }) => agent)\n } else {\n // Create new agent\n this.currentAgent = await this.agent.create()\n }\n return this.currentAgent\n }\n\n /**\n * Get current agent\n */\n getCurrentAgent(): Agent | undefined {\n return this.currentAgent\n }\n\n /**\n * Get current user DID\n */\n async getCurrentUserDID(): Promise<string> {\n return this.user.getCurrentUserDID()\n }\n\n /**\n * Create or reset user identity\n */\n async resetUserIdentity(): Promise<string> {\n return this.user.resetUserIdentity()\n }\n\n /**\n * Issue a VC for tool permission\n * Enhanced to support User → Agent delegation pattern\n */\n async issueToolPermission(\n tool: string,\n action: string,\n options: {\n subjectDid?: string\n agentId?: string\n issuerDid?: string\n resourceScope?: Record<string, any>\n expiresIn?: string\n }\n ): Promise<string> {\n return this.vc.issue(\n 'ToolPermissionVC',\n {\n tool: `${tool}.${action}`,\n resourceScope: options.resourceScope,\n aud: tool,\n },\n {\n issuerDid: options.issuerDid,\n subjectDid: options.subjectDid,\n agentId: options.agentId,\n expiresIn: options.expiresIn || '1h',\n }\n )\n }\n\n /**\n * Issue a VC for data access\n * Enhanced to support User → Agent delegation pattern\n */\n async issueDataAccess(\n resource: string,\n actions: ('read' | 'write' | 'delete')[],\n options: {\n subjectDid?: string\n agentId?: string\n issuerDid?: string\n expiresIn?: string\n }\n ): Promise<string> {\n return this.vc.issue(\n 'DataAccessVC',\n {\n resource,\n actions,\n },\n {\n issuerDid: options.issuerDid,\n subjectDid: options.subjectDid,\n agentId: options.agentId,\n expiresIn: options.expiresIn || '24h',\n }\n )\n }\n\n /**\n * Invoke a tool with automatic VP creation\n */\n async invokeTool<T = any>(\n tool: string,\n action: string,\n params: Record<string, any>,\n vcs: string[]\n ): Promise<ConnectorResponse<T>> {\n const holderDid = this.currentAgent?.did\n if (!holderDid) {\n throw new Error('No current agent available')\n }\n\n return this.tool.invoke<T>(tool, action, params, {\n vcs,\n holderDid,\n })\n }\n\n}\n\n// Export singleton instance for convenience\nlet defaultClient: AIdentityClient | undefined\n\nexport function getClient(config?: AIdentityConfig, password?: string): AIdentityClient {\n if (!defaultClient) {\n defaultClient = new AIdentityClient(config, password)\n }\n return defaultClient\n}\n\nexport { configure, AIdentityConfig } from './config'\n","import { SDJwtClient } from '../utils/sdjwt-client'\nimport { createDidJwk, extractPublicKeyFromDid } from '../did/did-utils'\nimport type { JWK } from 'jose'\n\nexport interface KeyPairGenerationResult {\n did: string\n publicKey: JWK\n privateKey: JWK\n}\n\n/**\n * Manages key pair generation for remote user issuer.\n * Generates ES256 key pairs and creates did:jwk DIDs.\n */\nexport class UserKeyPairManager {\n /**\n * Generate a new key pair and create a did:jwk DID\n */\n async generateKeyPair(): Promise<KeyPairGenerationResult> {\n const keyPair = await SDJwtClient.generateKeyPair()\n const did = createDidJwk(keyPair.publicKey)\n\n return {\n did,\n publicKey: keyPair.publicKey as JWK,\n privateKey: keyPair.privateKey as JWK,\n }\n }\n\n /**\n * Extract public key info from a did:jwk DID\n * @throws Error if the DID is not in did:jwk format\n */\n extractPublicKeyInfo(did: string): JWK {\n if (!did.startsWith('did:jwk:')) {\n throw new Error('Only did:jwk format is supported')\n }\n return extractPublicKeyFromDid(did)\n }\n}\n","/**\n * Device Enrollment Manager\n *\n * Handles the device code flow for registering a User Root DID\n * without requiring an API key. Supports two modes:\n *\n * Client-generated (local mode):\n * 1. Client calls startDeviceEnrollment() with rootDid + publicKeyJwk\n * 2. Client presents user_code and verification_url to the user\n * 3. User approves in browser\n * 4. Client polls until approved, receives device_session_token\n *\n * Server-generated (remote mode):\n * 1. Client calls startServerSideEnrollment() with clientInfo only\n * 2. Server returns user_code + verification_url (DID generated on approval)\n * 3. User approves in browser\n * 4. Client polls until approved, receives rootDid + device_session_token\n */\n\nexport interface DeviceEnrollStartParams {\n rootDid: string\n publicKeyJwk: {\n kty: string\n crv: string\n x: string\n y?: string\n use?: string\n alg?: string\n }\n clientInfo?: {\n deviceName?: string\n os?: string\n appVersion?: string\n hostname?: string\n [key: string]: any\n }\n purpose?: string\n}\n\nexport interface DeviceEnrollServerSideParams {\n clientInfo?: {\n deviceName?: string\n os?: string\n appVersion?: string\n hostname?: string\n [key: string]: any\n }\n purpose?: string\n}\n\nexport interface DeviceEnrollStartResult {\n requestId: string\n userCode: string\n verificationUrl: string\n expiresAt: string\n}\n\nexport interface DeviceEnrollPollResult {\n status: 'pending' | 'approved' | 'expired' | 'denied'\n deviceSessionToken?: string\n expiresAt?: string\n rootDid?: string // Returned on approval\n}\n\nexport class DeviceEnrollManager {\n private baseUrl: string\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\n }\n\n /**\n * Build common headers for all API requests.\n * Includes User-Agent and ngrok-skip-browser-warning to avoid\n * ngrok free-tier interstitial pages blocking programmatic access.\n */\n private buildHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'User-Agent': 'vess-sdk/1.0',\n 'ngrok-skip-browser-warning': 'true',\n }\n }\n\n /**\n * Start the device enrollment flow.\n * Sends the root DID public key to the Gateway and gets a user code.\n *\n * @param params - Root DID public info and client metadata\n * @returns Request ID, user code, and verification URL\n */\n async startDeviceEnrollment(\n params: DeviceEnrollStartParams\n ): Promise<DeviceEnrollStartResult> {\n const response = await fetch(`${this.baseUrl}/api/v1/device/start`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n rootDid: params.rootDid,\n publicKeyJwk: params.publicKeyJwk,\n clientInfo: params.clientInfo,\n purpose: params.purpose || 'root_did_enrollment',\n }),\n })\n\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(\n `Failed to start device enrollment: ${response.status} - ${errorBody}`\n )\n }\n\n const body = (await response.json()) as { success: boolean; data: DeviceEnrollStartResult }\n if (!body.success) {\n throw new Error(`Failed to start device enrollment: ${JSON.stringify(body)}`)\n }\n\n return body.data\n }\n\n /**\n * Start the device enrollment flow with server-side DID generation.\n * The server generates the real key pair on approval (not at start time).\n * Use this for remote/cloud-managed mode.\n *\n * @param params - Client metadata (no DID or key needed)\n * @returns Request ID, user code, and verification URL\n */\n async startServerSideEnrollment(\n params: DeviceEnrollServerSideParams\n ): Promise<DeviceEnrollStartResult> {\n const response = await fetch(`${this.baseUrl}/api/v1/device/start`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({\n generateServerSide: true,\n clientInfo: params.clientInfo,\n purpose: params.purpose || 'root_did_enrollment',\n }),\n })\n\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(\n `Failed to start device enrollment: ${response.status} - ${errorBody}`\n )\n }\n\n const body = (await response.json()) as { success: boolean; data: DeviceEnrollStartResult }\n if (!body.success) {\n throw new Error(`Failed to start device enrollment: ${JSON.stringify(body)}`)\n }\n\n return body.data\n }\n\n /**\n * Poll for enrollment status.\n * Call this periodically after startDeviceEnrollment() to check if\n * the user has approved the enrollment in the web UI.\n *\n * @param requestId - The request ID from startDeviceEnrollment()\n * @returns Current status and token if approved\n */\n async pollDeviceEnrollment(requestId: string): Promise<DeviceEnrollPollResult> {\n const response = await fetch(`${this.baseUrl}/api/v1/device/poll`, {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify({ requestId }),\n })\n\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(\n `Failed to poll device enrollment: ${response.status} - ${errorBody}`\n )\n }\n\n const body = (await response.json()) as { success: boolean; data: DeviceEnrollPollResult }\n if (!body.success) {\n throw new Error(`Failed to poll device enrollment: ${JSON.stringify(body)}`)\n }\n\n return body.data\n }\n\n /**\n * Convenience method: Start enrollment and poll until completion.\n * Returns the final result (approved, expired, or denied).\n *\n * @param params - Enrollment parameters (client-generated mode)\n * @param onUserCode - Callback when user code is available (present to user)\n * @param pollIntervalMs - Polling interval in ms (default: 3000)\n * @param maxPolls - Maximum number of poll attempts (default: 120)\n */\n async enrollAndWait(\n params: DeviceEnrollStartParams,\n onUserCode: (info: DeviceEnrollStartResult) => void,\n pollIntervalMs: number = 3000,\n maxPolls: number = 120\n ): Promise<DeviceEnrollPollResult> {\n const startResult = await this.startDeviceEnrollment(params)\n return this.pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls)\n }\n\n /**\n * Convenience method: Start server-side enrollment and poll until completion.\n * Returns the final result including the server-generated rootDid on approval.\n *\n * @param params - Client metadata (server-generated mode)\n * @param onUserCode - Callback when user code is available (present to user)\n * @param pollIntervalMs - Polling interval in ms (default: 3000)\n * @param maxPolls - Maximum number of poll attempts (default: 120)\n */\n async enrollServerSideAndWait(\n params: DeviceEnrollServerSideParams,\n onUserCode: (info: DeviceEnrollStartResult) => void,\n pollIntervalMs: number = 3000,\n maxPolls: number = 120\n ): Promise<DeviceEnrollPollResult> {\n const startResult = await this.startServerSideEnrollment(params)\n return this.pollUntilComplete(startResult, onUserCode, pollIntervalMs, maxPolls)\n }\n\n private async pollUntilComplete(\n startResult: DeviceEnrollStartResult,\n onUserCode: (info: DeviceEnrollStartResult) => void,\n pollIntervalMs: number,\n maxPolls: number\n ): Promise<DeviceEnrollPollResult> {\n onUserCode(startResult)\n\n for (let i = 0; i < maxPolls; i++) {\n await new Promise(resolve => setTimeout(resolve, pollIntervalMs))\n\n const pollResult = await this.pollDeviceEnrollment(startResult.requestId)\n\n if (pollResult.status !== 'pending') {\n return pollResult\n }\n }\n\n return { status: 'expired' }\n }\n}\n","import { DIDDocument } from './did'\n\n/**\n * Agent Status enumeration\n */\nexport enum AgentStatus {\n ACTIVE = 'active',\n SUSPENDED = 'suspended', // @deprecated — kept for backward compatibility with existing DB rows\n REVOKED = 'revoked', // @deprecated — kept for backward compatibility with existing DB rows\n DELETED = 'deleted',\n}\n\n/**\n * Agent Type enumeration\n */\nexport enum AgentType {\n AUTONOMOUS = 'autonomous', // Independent AI Agent\n SUB_AGENT = 'sub_agent', // Part of multi-agent system\n TOOL_AGENT = 'tool_agent', // Tool-specific agent\n ASSISTANT = 'assistant', // AI Assistant (Claude Code etc.)\n PROXY = 'proxy' // Proxy for external systems\n}\n\n/**\n * AI Agent Identity representation\n * Agents are AI entities that need identity for permission delegation\n */\nexport interface Agent {\n /** The DID associated with this agent */\n did: string\n /** DID Document for the agent's identity */\n didDocument: DIDDocument\n /** ISO 8601 timestamp of when the agent was created */\n createdAt: string\n /** Optional metadata for the agent */\n metadata?: Record<string, any>\n}\n\n/**\n * Extended Agent interface matching API entity structure\n */\nexport interface APIAgent {\n /** Unique identifier */\n id: string\n /** Agent's DID (Decentralized Identifier) */\n did: string\n /** Agent's display name */\n name: string\n /** Agent type */\n type: AgentType\n /** Agent status */\n status: AgentStatus\n /** Agent information */\n agentInfo: {\n model?: string // AI model (claude-3, gpt-4, etc)\n capabilities?: string[] // Agent capabilities\n configuration?: Record<string, any>\n [key: string]: any\n }\n /** Additional metadata */\n metadata?: Record<string, any>\n /** Owner user ID */\n ownerId?: string\n /** Parent agent ID for hierarchical agents */\n parentAgentId?: string\n /** Whether agent is currently active */\n isActive: boolean\n /** Last activity timestamp */\n lastActiveAt?: Date\n /** Creation timestamp */\n createdAt: Date\n /** Update timestamp */\n updatedAt: Date\n}\n\n/**\n * Agent with unique identifier\n * Used for managing multiple agents with distinct identities\n */\nexport interface AgentWithId extends Agent {\n /** Unique identifier for this agent instance */\n id: string\n}\n\n/**\n * User Identity representation\n * Users are human entities who issue VCs to agents\n */\nexport interface UserIdentity {\n /** The DID associated with this user */\n did: string\n /** DID Document for the user's identity */\n didDocument: DIDDocument\n /** ISO 8601 timestamp of when the user identity was created */\n createdAt: string\n /** Optional metadata for the user */\n metadata?: Record<string, any>\n}\n\n/**\n * Configuration for Agent DID generation\n */\nexport interface AgentDIDConfig {\n /** Whether to auto-generate DID for new agents */\n generateDID: boolean\n /** DID method to use (currently only 'jwk' supported) */\n didMethod: 'jwk'\n /** Key type for cryptographic operations */\n keyType: 'ES256'\n /** Whether agent DIDs are ephemeral (deleted with agent) */\n ephemeral: boolean\n}\n\n/**\n * Configuration for User Identity management\n */\nexport interface UserIdentityConfig {\n /** Whether to auto-create user identity if none exists */\n autoCreate: boolean\n /** DID method to use (currently only 'jwk' supported) */\n didMethod: 'jwk'\n /** Key type for cryptographic operations */\n keyType: 'ES256'\n /** Whether to support external DIDs (future feature) */\n allowExternalDID: boolean\n}\n\n/**\n * Agent creation options\n */\nexport interface AgentCreateOptions {\n /** Optional name for the agent */\n name?: string\n /** Optional metadata to associate with the agent */\n metadata?: Record<string, any>\n /** Override default DID generation behavior */\n generateDID?: boolean\n}\n\n/**\n * User identity creation options\n */\nexport interface UserIdentityCreateOptions {\n /** Optional metadata to associate with the user */\n metadata?: Record<string, any>\n /** Force creation of new identity (replace existing) */\n force?: boolean\n}","/**\n * Credential Type enumeration\n * Used for general credential classification\n */\nexport enum CredentialType {\n PROJECT_ACCESS = 'ProjectAccessCredential',\n TOOL_ACCESS = 'ToolAccessCredential',\n DEVELOPER = 'DeveloperCredential',\n TEMPORARY = 'TemporaryCredential',\n ADMIN = 'AdminCredential',\n RECEIPT = 'ReceiptCredential'\n}\n\n/**\n * Credential Status enumeration\n * Used for general credential status tracking\n */\nexport enum CredentialStatus {\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REVOKED = 'revoked',\n SUSPENDED = 'suspended'\n}\n\n/**\n * VC Type enumeration (for Grant-based VCs)\n * Used specifically for VerifiableCredential entity in the database\n *\n * Maps to:\n * - ACCESS_CREDENTIAL: Pre-execution authorization (similar to TOOL_ACCESS)\n * - RECEIPT: Post-execution proof (similar to ReceiptCredential)\n */\nexport enum VCType {\n ACCESS_CREDENTIAL = 'AccessCredential',\n RECEIPT = 'Receipt'\n}\n\n/**\n * VC Status enumeration (for Grant-based VCs)\n * Used specifically for VerifiableCredential entity in the database\n *\n * Maps to CredentialStatus:\n * - VALID = ACTIVE\n * - EXPIRED = EXPIRED\n * - REVOKED = REVOKED\n * - SUSPENDED = SUSPENDED (temporary revocation, can be reactivated)\n * - EXHAUSTED = Grant invocation limit reached\n */\nexport enum VCStatus {\n VALID = 'valid',\n EXPIRED = 'expired',\n REVOKED = 'revoked',\n SUSPENDED = 'suspended',\n EXHAUSTED = 'exhausted'\n}\n\n/**\n * Utility functions for mapping between CredentialStatus and VCStatus\n */\nexport function credentialStatusToVCStatus(status: CredentialStatus): VCStatus {\n switch (status) {\n case CredentialStatus.ACTIVE:\n return VCStatus.VALID\n case CredentialStatus.EXPIRED:\n return VCStatus.EXPIRED\n case CredentialStatus.REVOKED:\n return VCStatus.REVOKED\n case CredentialStatus.SUSPENDED:\n return VCStatus.SUSPENDED\n default:\n // Type-safe exhaustiveness check\n const _exhaustiveCheck: never = status\n throw new Error(`Unknown CredentialStatus: ${_exhaustiveCheck}`)\n }\n}\n\nexport function vcStatusToCredentialStatus(status: VCStatus): CredentialStatus {\n switch (status) {\n case VCStatus.VALID:\n return CredentialStatus.ACTIVE\n case VCStatus.EXPIRED:\n return CredentialStatus.EXPIRED\n case VCStatus.REVOKED:\n case VCStatus.EXHAUSTED:\n return CredentialStatus.REVOKED\n case VCStatus.SUSPENDED:\n return CredentialStatus.SUSPENDED\n default:\n // Type-safe exhaustiveness check\n const _exhaustiveCheck: never = status\n throw new Error(`Unknown VCStatus: ${_exhaustiveCheck}`)\n }\n}\n\n/**\n * SD-JWT Verifiable Credential interface\n */\nexport interface DelegationVC {\n '@context': string[]\n vct: string\n issuer: string\n iss: string\n iat: number\n exp?: number\n validFrom: string\n validUntil?: string\n name?: string\n description?: string\n credentialSubject: {\n id: string // Subject DID\n [key: string]: any\n }\n credentialStatus?: {\n id: string\n type: string\n statusListIndex: string\n statusListCredential: string\n }\n}\n\n/**\n * API Credential entity interface\n */\nexport interface APICredential {\n /** Unique identifier */\n id: string\n /** Issuer DID */\n issuer: string\n /** Subject DID */\n subject: string\n /** Credential type */\n type: CredentialType\n /** Credential claims */\n claims: {\n permissions?: string[]\n projectId?: string\n tools?: string[]\n authorizedBy?: string\n deviceBinding?: string\n [key: string]: any\n }\n /** Credential status */\n status: CredentialStatus\n /** Raw SD-JWT credential */\n rawCredential?: string\n /** Cryptographic signature */\n signature?: string\n /** Associated project ID */\n projectId?: string\n /** Associated agent ID */\n agentId?: string\n /** Issuance timestamp */\n issuedAt: Date\n /** Expiration timestamp */\n expiresAt?: Date\n /** Revocation timestamp */\n revokedAt?: Date\n /** Revocation reason */\n revocationReason?: string\n /** Creation timestamp */\n createdAt: Date\n /** Update timestamp */\n updatedAt: Date\n}\n\n/**\n * SD-JWT Credential issuance request\n */\nexport interface IssueSDJWTVCRequest {\n /** Issuer DID */\n issuer: string\n /** Subject DID */\n subject: string\n /** Credential type */\n type?: CredentialType\n /** Claims to include */\n claims: Record<string, any>\n /** Expiration date */\n expirationDate?: Date\n /** Project ID */\n projectId?: string\n /** Agent ID */\n agentId?: string\n /** Fields to make selectively disclosable */\n selectiveDisclosureFields?: string[]\n}\n\n/**\n * SD-JWT Credential verification result\n */\nexport interface VerifySDJWTVCResult {\n /** Whether the credential is valid */\n valid: boolean\n /** Decoded payload if valid */\n payload?: {\n iss: string\n sub: string\n vct: string // IETF SD-JWT VC credential type\n exp?: number\n iat?: number\n // Additional claims can be present (dynamic properties)\n [key: string]: any\n }\n /** Error message if invalid */\n error?: string\n}\n\n/**\n * SD-JWT Credential issuance result\n */\nexport interface IssueSDJWTVCResult {\n /** The complete SD-JWT VC */\n credential: string\n /** Issuer DID */\n issuer: string\n /** Subject DID */\n subject: string\n /** Credential type */\n type: CredentialType\n /** Expiration timestamp */\n expiresAt?: Date\n}\n\nexport interface ToolPermissionVC extends DelegationVC {\n credentialSubject: {\n id: string\n tool: string // e.g., \"slack.message.post\"\n resourceScope?: Record<string, any> // e.g., { channel: \"C123\" }\n aud: string // e.g., \"slack\"\n }\n}\n\nexport interface DataAccessVC extends DelegationVC {\n credentialSubject: {\n id: string\n resource: string // e.g., \"agent/did:agent:abc/*\"\n actions: ('read' | 'write' | 'delete')[]\n }\n}\n\nexport interface VCTemplate<T extends DelegationVC = DelegationVC> {\n type: string\n name: string\n description?: string\n defaults?: Partial<T>\n validate?: (vc: T) => boolean\n}\n","export class AIdentityError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: any\n ) {\n super(message)\n this.name = this.constructor.name\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class VCExpiredError extends AIdentityError {\n constructor(message = 'Verifiable Credential has expired', details?: any) {\n super(message, 'VC_EXPIRED', details)\n }\n}\n\nexport class ScopeUnmatchedError extends AIdentityError {\n constructor(message = 'Scope does not match required permissions', details?: any) {\n super(message, 'SCOPE_UNMATCHED', details)\n }\n}\n\nexport class VCRevokedError extends AIdentityError {\n constructor(message = 'Verifiable Credential has been revoked', details?: any) {\n super(message, 'VC_REVOKED', details)\n }\n}\n\nexport class InvalidVPError extends AIdentityError {\n constructor(message = 'Verifiable Presentation is invalid', details?: any) {\n super(message, 'INVALID_VP', details)\n }\n}\n\nexport class AuthenticationError extends AIdentityError {\n constructor(message = 'Authentication failed', details?: any) {\n super(message, 'AUTH_FAILED', details)\n }\n}\n\nexport class NetworkError extends AIdentityError {\n constructor(message = 'Network request failed', details?: any) {\n super(message, 'NETWORK_ERROR', details)\n }\n}","/**\n * Permission VC Claims Schema v2\n *\n * This is the CANONICAL format for Permission Verifiable Credential claims.\n * All VC issuance paths MUST produce claims conforming to this schema.\n * The PolicyEvaluator consumes this schema directly.\n *\n * Design principles:\n * - Grant data is normalized into this format during VC issuance\n * - PermissionRule is the atomic unit of authorization\n * - Resource representation uses provider + type + id/pattern (OPA-compatible)\n * - Constraints are carried per-rule for fine-grained control\n * - Future OPA integration: this schema maps directly to OPA input document\n */\n\n// ---------------------------------------------------------------------------\n// Resource Representation (unified across Grant, VC, and Policy)\n// ---------------------------------------------------------------------------\n\n/**\n * Service provider identifier.\n * @deprecated Import { CanonicalProvider, AnyProvider } from '@vess-id/ai-identity' registry instead.\n * Kept for backward compatibility with existing code.\n */\nexport type Provider = 'slack' | 'github' | 'google' | 'drive' | 'gmail' | 'jira'\n\n/**\n * Resource target within a permission rule.\n *\n * Separates provider from resource type (unlike Grant's combined \"slack:channel\").\n * This enables cleaner OPA policy evaluation and avoids string-parsing at runtime.\n *\n * @example\n * ```typescript\n * // Specific channel\n * { type: 'channel', id: 'C123456' }\n *\n * // Pattern match\n * { type: 'channel', pattern: 'public-*' }\n *\n * // All resources of a type\n * { type: 'channel', id: '*' }\n *\n * // All resource types for a provider\n * { type: '*', id: '*' }\n * ```\n */\nexport interface PermissionResource {\n /** Resource type (e.g., 'channel', 'repo', 'file', 'issue') */\n type: string\n /** Specific resource ID. Use '*' for all resources of this type. */\n id?: string\n /** Glob pattern for resource ID matching (e.g., 'public-*', 'team-?-dev') */\n pattern?: string\n /** Tenant reference (e.g., workspace ID, org ID) */\n tenant_ref?: string\n}\n\n// ---------------------------------------------------------------------------\n// Constraint Representation (unified across Grant, VC, and Policy)\n// ---------------------------------------------------------------------------\n\n/**\n * Time window constraint.\n *\n * Supports both:\n * - Recurring windows (start/end HH:mm with daysOfWeek) - from Grant model\n * - Absolute windows (not_before/not_after unix timestamps) - for VC-level\n *\n * The VC issuance layer converts Grant's recurring windows into the\n * appropriate format based on context.\n */\nexport interface PermissionTimeConstraint {\n /** Absolute not-before (unix timestamp) */\n not_before?: number\n /** Absolute not-after (unix timestamp) */\n not_after?: number\n /** Recurring: allowed time start (HH:mm, UTC unless timezone specified) */\n recurring_start?: string\n /** Recurring: allowed time end (HH:mm, UTC unless timezone specified) */\n recurring_end?: string\n /** Recurring: allowed days of week (0=Sun, 1=Mon...6=Sat) */\n days_of_week?: number[]\n /** Timezone for recurring constraints (default: 'UTC') */\n timezone?: string\n}\n\n/**\n * Rule-level constraints embedded in each PermissionRule.\n *\n * These are evaluated at policy decision time and support both\n * Grant-originated constraints and VC-specific constraints.\n */\nexport interface PermissionConstraints {\n /** Time constraints */\n time?: PermissionTimeConstraint\n /** Maximum invocations for this specific rule */\n max_invocations?: number\n /** Rate limiting (requests per minute) */\n rate_limit_per_min?: number\n /** Allowed IP ranges (CIDR notation) */\n ip_allowlist?: string[]\n /** Maximum risk score threshold (0-100) */\n risk_threshold?: number\n /** Purpose description (for audit trail) */\n purpose?: string\n /** Scope constraints (provider-specific, e.g., { thread_id: 'T123' }) */\n scope?: Record<string, unknown>\n /**\n * Target constraints for secondary destinations (cc, attendees, etc.).\n * Alpha: defined but NOT evaluated by ConstraintEvaluator.\n * Future: evaluated against PolicyInput.request.targets.\n */\n targets?: import('./target-binding').TargetConstraint[]\n}\n\n// ---------------------------------------------------------------------------\n// Policy Reference (Phase 1: Cedar policy binding)\n// ---------------------------------------------------------------------------\n\n/**\n * Inline policy mode — full Cedar policy embedded in the VC.\n *\n * Used for sub-agent re-delegation where the verifier cannot reach the\n * Policy Registry over the network. The inline policy is authoritative;\n * `policy_hash` is a sanity check for tamper-evidence.\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.2\n */\nexport interface PolicyRefInline {\n mode: 'inline'\n /** Full Cedar policy source (PolicySet text, UTF-8). */\n policy_inline: string\n /** sha256 of `policy_inline` (hex), prefixed `sha256-` for tamper-evidence. */\n policy_hash: string\n /**\n * Cedar schema fragment id. **Phase 1 unused** (Cedar wasm schema-less\n * evaluation, Implementation plan §1.1). **Phase 2+ で per-policy schema\n * 切替時に inline モードでは REQUIRED 化** (reference モードは Registry\n * resolve で取得できるため optional のまま).\n */\n schema_id?: string\n}\n\n/**\n * Reference policy mode — policy lives in the Policy Registry.\n *\n * The verifier fetches `policy_uri` (must match the issuer's\n * `/.well-known/policy-registry/:policy_id`), validates `policy_hash`,\n * and evaluates the fetched Cedar policy.\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.2\n */\nexport interface PolicyRefReference {\n mode: 'reference'\n /** Policy Registry id. Format: `pol_<project_id>_<uuidv7>`. */\n policy_id: string\n /** Absolute URL to `/.well-known/policy-registry/:policy_id`. */\n policy_uri: string\n /** sha256 of the served Cedar policy text (hex), prefixed `sha256-`. */\n policy_hash: string\n /**\n * Cedar schema fragment id. Phase 1 unused (Registry resolve で取得可能、\n * schema-less evaluation を使う簡易構成)。Phase 2+ で per-policy schema を\n * 導入したときも reference モードは引き続き OPTIONAL — VC payload に\n * 同梱せず Registry 側で resolve する方針。\n */\n schema_id?: string\n}\n\n/**\n * Tagged union of policy reference shapes. Discriminator: `mode`.\n *\n * Use {@link isPolicyRefInline} / {@link isPolicyRefReference} for runtime\n * narrowing.\n */\nexport type PolicyRef = PolicyRefInline | PolicyRefReference\n\n/** Type guard for {@link PolicyRefInline}. */\nexport function isPolicyRefInline(ref: PolicyRef): ref is PolicyRefInline {\n return ref.mode === 'inline'\n}\n\n/** Type guard for {@link PolicyRefReference}. */\nexport function isPolicyRefReference(ref: PolicyRef): ref is PolicyRefReference {\n return ref.mode === 'reference'\n}\n\n// ---------------------------------------------------------------------------\n// Permission Rule (atomic authorization unit)\n// ---------------------------------------------------------------------------\n\n/**\n * Permission Rule - the atomic unit of authorization.\n *\n * Each rule grants specific actions on specific resources for a specific provider.\n * Rules are evaluated independently during policy evaluation.\n *\n * Phase 1 (Cedar + RAR redesign) extensions:\n * - `effect` widened from `'allow'` only to the 3-valued\n * `'allow' | 'deny' | 'require_approval'` (spec §5).\n * Existing call-sites that only used `'allow'` remain source-compatible.\n * - `priority` field added (optional, used for deterministic ordering when\n * multiple rules match the same request).\n * - `policy_ref` field added (optional in Phase 1 for backward-compat\n * during migration; Phase 2+ will bump the schema to v3.1 and make it\n * required — see spec §3.1 reconciliation note).\n *\n * OPA mapping (legacy `'allow'`-only path, still used while\n * `CEDAR_POLICY_ENABLED != enforce`):\n * ```rego\n * allow {\n * some rule in input.credentials.delegates\n * rule.effect == \"allow\"\n * rule.provider == input.request.provider\n * glob.match(rule.resource.type, [], input.request.resource.type)\n * resource_id_matches(rule.resource, input.request.resource.id)\n * action_matches(rule.actions, input.request.action)\n * constraints_satisfied(rule.constraints, input.environment)\n * }\n * ```\n */\nexport interface PermissionRule {\n /** Rule identifier (for audit trail and matched_rule_id) */\n id?: string\n /**\n * Effect. Phase 1 widens this beyond legacy `'allow'`-only:\n * - `'allow'` — permit the action (legacy default).\n * - `'deny'` — explicit deny (override precedence over allow).\n * - `'require_approval'` — pause and request human approval.\n */\n effect: 'allow' | 'deny' | 'require_approval'\n /**\n * Optional priority for deterministic ordering when multiple rules match.\n * Higher priority wins. Phase 1 evaluator behaviour is unchanged when\n * `priority` is absent.\n */\n priority?: number\n /** Service provider */\n provider: Provider | string\n /** Target resource */\n resource: PermissionResource\n /** Allowed actions (e.g., ['post_message', 'read_history']). '*' for all. */\n actions: string[]\n /** Rule-level constraints */\n constraints?: PermissionConstraints\n /**\n * Cedar policy binding (Phase 1).\n *\n * When present, the policy engine evaluates this delegate via the\n * referenced / inlined Cedar policy in addition to the static constraint\n * check. Optional in Phase 1 for backward-compat during migration; Phase\n * 2+ will bump the schema to v3.1 and make it required.\n */\n policy_ref?: PolicyRef\n /**\n * Cedar policy bindings (複数) — 1 つの委任スコープに複数の policy が AND/OR\n * で適用されるケース (例: calendarDomain 宛先制約 + timeWindow forbid)。\n * 後方互換のため単数 `policy_ref` は維持し、発行時は `policy_refs[0]` を\n * ミラーする。読み手は policy_refs を優先し、無ければ policy_ref を単要素配列に\n * 正規化する。Cedar 評価では全 ref を 1 つの PolicySet に集約 (permit=OR,\n * forbid=override で AND)。\n */\n policy_refs?: PolicyRef[]\n}\n\n// ---------------------------------------------------------------------------\n// Permission VC Claims (the canonical VC payload)\n// ---------------------------------------------------------------------------\n\n/**\n * Permission VC Claims v2 — the pre-Cedar canonical credential claims format.\n *\n * This is what gets signed into the SD-JWT VC. All VC issuance paths\n * (VCService, RemoteVCIssuerService, PermissionVCManager) MUST produce\n * claims conforming to either this interface or {@link PermissionVcClaims_V3}.\n *\n * The Grant → VC normalization layer converts:\n * - GrantResource[] + actions[] → PermissionRule[]\n * - GrantConstraints → PermissionConstraints (per-rule)\n * - Grant metadata → top-level claims fields\n *\n * @remarks Phase 1 Step 2 renamed the original `PermissionVcClaims` to\n * `PermissionVcClaims_V2`. The exported alias {@link PermissionVcClaims}\n * is now a union of V2 + {@link PermissionVcClaims_V3}, preserving\n * existing import sites (they will accept both shapes).\n */\nexport interface PermissionVcClaims_V2 {\n /** Schema version */\n v: '2'\n /** Credential type discriminator */\n type: 'PermissionCredential'\n /** Issuer DID (user who granted permission) */\n iss: string\n /** Subject DID (agent receiving permission) */\n sub: string\n /** Issued at (unix timestamp) */\n iat: number\n /** Not before (unix timestamp) */\n nbf?: number\n /** Expiration (unix timestamp) */\n exp: number\n /** JWT ID (unique credential identifier) */\n jti: string\n /** Project ID */\n project_id: string\n /** User ID (grant owner) */\n user_id?: string\n /** User DID (grant owner) */\n user_did?: string\n /** Source grant IDs (supports multiple grants aggregated into one VC) */\n grant_ids: string[]\n /**\n * Primary grant ID (derived from grant_ids[0]).\n * @deprecated Use grant_ids instead. Kept for backward-compat JWT claims.\n * Always set via {@link buildGrantIdFields} to keep both fields in sync.\n */\n grant_id: string\n /** Session ID (binds VC to specific session) */\n session_id: string\n /** Parent JWT ID for re-delegation chain (not supported in MVP) */\n parent_jti?: string\n /** Confirmation (Proof of Possession binding) */\n cnf?: {\n /** JWK for Proof of Possession (SD-JWT KB-JWT standard) */\n jwk: Record<string, unknown>\n }\n /** Delegated permission rules (the core authorization data) */\n delegates: PermissionRule[]\n}\n\n/**\n * Permission VC Claims v3 — Cedar + RAR Phase 1 schema.\n *\n * Inherits all V2 fields and adds two Phase-1-aware extensions:\n * - `cedar_schema_ref?` — pointer to the Cedar schema fragment the\n * delegates were authored against. **Phase 1 unused** (the SDK ships a\n * single global schema fragment generated by connector-plugin codegen,\n * per Implementation plan §1.1). Reserved for Phase 2+ per-policy schema\n * switching.\n * - `layer?` — chain hierarchy layer. **Phase 2+ only**; Phase 1 issuance\n * pins this to `'agent_permission'` via {@link buildPhase1VcClaims}.\n * Direct assignment is discouraged (ESLint rule planned in Step 5).\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.1\n * - docs/specs/2026-05-23-cedar-rar-implementation-plan-phase1.md Task 2.1 / 2.5\n */\n/**\n * Bug B 真因修正 (β, 2026-05-28) — VC=mandate semantic を invoke 時 Cedar も\n * 信じるため、approval の事実 (誰がいつ何を approve したか) を VC に焼き込む\n * signed self-attestation。SD-protected (`_sd` 経由 disclosure)、SD-JWT 署名で\n * 改竄不可。invoke 時 Cedar context.approval の最優先 source として採用。\n *\n * Forward compat: A2A AP2 Mandate (IntentMandate / CartMandate / PaymentMandate)\n * との projection は Phase 2 spec で別途定義。本 field 名は内部\n * ApprovalContext (snake_case) と一貫。\n *\n * Spec ref: docs/superpowers/plans/2026-05-28-bug-b-fix-beta-vc-embed-approval.md\n */\nexport interface VcApprovalClaim {\n /** `req_<uuid>` — 元 approval-request id (claimVC 元 request の id)。 */\n request_id: string\n /** `outcome_<uuid>` — APPROVAL_OUTCOME audit event id (§11.1 join key)。 */\n outcome_id: string\n /** approver の user id、または 'system' (auto-approve 経路)。最大 128 chars。 */\n granted_by: string\n /** ISO-8601 timestamp of the approval action. */\n granted_at: string\n}\n\nexport interface PermissionVcClaims_V3 extends Omit<PermissionVcClaims_V2, 'v'> {\n /** Schema version — v3 adds Cedar policy_ref support and chain hierarchy fields. */\n v: '3'\n /**\n * Cedar schema fragment reference (Phase 2+ per-policy schema switching).\n * Phase 1: unused; SDK uses connector-plugin codegen global schema.\n */\n cedar_schema_ref?: {\n /** e.g. `cedar_schema_2026_05_23_v1`. */\n schema_id: string\n /** sha256 of the schema fragment (hex). */\n schema_hash: string\n }\n /**\n * 4-layer chain (Org Policy → User Grant → Agent Permission → Sub-Agent Delegation).\n * Phase 1 では `buildPhase1VcClaims()` factory 経由で `'agent_permission'` が固定セットされる。\n * Phase 2+ では本フィールドを **required** に格上げする予定 (V3.1 schema)。\n * 直接代入は禁止 (Phase 1 では factory を使うこと、Phase 2+ では ESLint rule で強制)。\n * 詳細: design spec §3.1, §6.1 / Phase 1 plan Task 2.5。\n */\n layer?: 'org_policy' | 'user_grant' | 'agent_permission' | 'sub_agent_delegation'\n /**\n * Bug B 真因修正 (β, 2026-05-28) — approval メタを VC に焼き込む。\n * VC=mandate なので「この VC が発行されたこと自体が approve の証拠」だが、\n * invoke 時 Cedar に `context.approval.granted == true` を渡せるよう\n * back-ref を明示。本 field 不在 = base path (legacy 互換、Cedar は token-\n * ledger 経由 fallback)。{@link VcApprovalClaim} 参照。\n */\n approval?: VcApprovalClaim\n}\n\n/**\n * Permission VC Claims (canonical union of v2 + v3).\n *\n * All existing import sites referencing `PermissionVcClaims` continue to\n * compile because:\n * - Code that only produced V2 still produces a value assignable to the\n * union.\n * - Code that consumes the union can narrow on `claims.v === '3'` to\n * access V3-only fields.\n */\nexport type PermissionVcClaims = PermissionVcClaims_V2 | PermissionVcClaims_V3\n\n/**\n * Build synchronized grant_id / grant_ids fields for PermissionVcClaims.\n * Guarantees grant_id === grant_ids[0].\n */\nexport function buildGrantIdFields(grantIds: string[]): { grant_ids: string[]; grant_id: string } {\n if (grantIds.length === 0) {\n throw new Error('grantIds must contain at least one element')\n }\n return { grant_ids: grantIds, grant_id: grantIds[0] }\n}\n\n// ---------------------------------------------------------------------------\n// Policy Evaluation Types (OPA-compatible input/output)\n// ---------------------------------------------------------------------------\n\n/**\n * Policy evaluation input document.\n *\n * Designed to map 1:1 to OPA input document for future integration:\n * ```rego\n * package aidentity.authz\n *\n * default allow = false\n *\n * allow {\n * some rule in input.credentials.delegates\n * rule_matches(rule, input.request)\n * constraints_ok(rule.constraints, input.environment)\n * }\n * ```\n */\nexport interface PolicyInput {\n /** Subject (who is requesting) */\n subject: {\n /** Agent DID */\n agent_did: string\n /** Session ID */\n session_id: string\n /** User DID (delegator) */\n user_did?: string\n }\n /** Tenant context */\n tenant: {\n /** Project ID */\n project_id: string\n }\n /** Request details (what is being requested) */\n request: {\n /** Service provider */\n provider: string\n /** Action to perform */\n action: string\n /** Target resource */\n resource: {\n type: string\n id: string\n /** Tenant/workspace reference for multi-account disambiguation (future) */\n tenant_ref?: string\n }\n /** Secondary targets extracted from tool parameters via TargetResolver */\n targets?: import('./target-binding').PolicyTarget[]\n /** Raw tool parameters (for OPA custom policies) */\n params?: Record<string, unknown>\n }\n /** Credential information (from VC) */\n credentials: {\n /** JWT ID */\n jti: string\n /** Source grant IDs */\n grant_ids: string[]\n /** Primary grant ID */\n grant_id: string\n /** Issued at timestamp */\n issued_at: number\n /** Expiration timestamp */\n expires_at: number\n /** Delegated permission rules from VC */\n delegates: PermissionRule[]\n }\n /** Environment context (evaluated at request time) */\n environment: {\n /** Current timestamp (unix) */\n now: number\n /** Client IP address */\n ip_address?: string\n /** Risk score (0-100) */\n risk_score?: number\n /** Current invocation count for the grant */\n invocation_count?: number\n }\n}\n\n/**\n * Policy evaluation result\n */\nexport interface PolicyEvaluationResult {\n /** Whether the action is allowed */\n allowed: boolean\n /** Denial reason if not allowed */\n reason?: string\n /** Error code for programmatic handling */\n reason_code?: string\n /** Matched rule ID (if allowed) */\n matched_rule_id?: string\n /** Which evaluation step failed (for debugging) */\n step_failed?: string\n}\n\n// ---------------------------------------------------------------------------\n// External Action Request (normalized tool invocation request)\n// ---------------------------------------------------------------------------\n\n/**\n * External Action Request - normalized format for tool invocations.\n * Used as the bridge between MCP tool calls and policy evaluation.\n */\nexport interface ExternalActionRequest {\n /** Request ID for idempotency */\n request_id: string\n /** Service provider */\n provider: Provider | string\n /** Action to perform */\n action: string\n /** Target resource */\n resource: {\n type: string\n id: string\n }\n /** Project ID */\n project_id: string\n /** Session ID */\n session_id: string\n /** Action parameters (sanitized) */\n params?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Grant → VC Normalization Utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Parsed provider and resource type from a Grant's combined resource type string.\n *\n * Grant uses \"slack:channel\" format, but VC uses separate provider + resource.type.\n * This interface represents the parsed result.\n */\nexport interface ParsedResourceType {\n provider: string\n resourceType: string\n}\n\n/**\n * Parse a Grant resource type string into provider and resource type.\n *\n * @example\n * parseGrantResourceType('slack:channel') // { provider: 'slack', resourceType: 'channel' }\n * parseGrantResourceType('github:repo') // { provider: 'github', resourceType: 'repo' }\n * parseGrantResourceType('slack') // { provider: 'slack', resourceType: '*' }\n * parseGrantResourceType('*') // { provider: '*', resourceType: '*' }\n */\nexport function parseGrantResourceType(grantType: string): ParsedResourceType {\n if (grantType === '*') {\n return { provider: '*', resourceType: '*' }\n }\n const colonIndex = grantType.indexOf(':')\n if (colonIndex === -1) {\n return { provider: grantType, resourceType: '*' }\n }\n return {\n provider: grantType.substring(0, colonIndex),\n resourceType: grantType.substring(colonIndex + 1),\n }\n}\n\n/**\n * Parse a Grant action string into provider and action.\n *\n * Grant actions use \"provider.resource.operation\" (dot format, canonical) or\n * legacy \"provider:resource.operation\" (colon format).\n * This extracts the provider prefix and the action name.\n *\n * @example\n * parseGrantAction('slack.message.read') // { provider: 'slack', action: 'message.read' }\n * parseGrantAction('slack:channel.post_message') // { provider: 'slack', action: 'channel.post_message' }\n * parseGrantAction('*') // { provider: '*', action: '*' }\n */\nexport function parseGrantAction(grantAction: string): { provider: string; action: string } {\n if (grantAction === '*') {\n return { provider: '*', action: '*' }\n }\n // Try colon format first (legacy): \"slack:channel.post_message\"\n const colonIndex = grantAction.indexOf(':')\n if (colonIndex > 0) {\n return {\n provider: grantAction.substring(0, colonIndex),\n action: grantAction.substring(colonIndex + 1),\n }\n }\n // Try dot format (canonical): \"slack.message.read\"\n const dotIndex = grantAction.indexOf('.')\n if (dotIndex > 0) {\n return {\n provider: grantAction.substring(0, dotIndex),\n action: grantAction.substring(dotIndex + 1),\n }\n }\n return { provider: '*', action: grantAction }\n}\n\n// ---------------------------------------------------------------------------\n// Phase 1 VC issuance factory (layer pinning)\n// ---------------------------------------------------------------------------\n\n/**\n * The single layer value Phase 1 VC issuance is allowed to emit.\n *\n * companion design spec §3.1 defines a 4-layer enum\n * (`'org_policy' | 'user_grant' | 'agent_permission' | 'sub_agent_delegation'`),\n * but Phase 1 only issues at the `agent_permission` layer. The other 3\n * layers unlock in Phase 2+.\n *\n * Spec refs:\n * - docs/specs/2026-05-23-cedar-rar-implementation-plan-phase1.md Task 2.5 (rev 5)\n * - docs/specs/2026-05-23-cedar-rar-permission-redesign.md §3.1 Phase 1 layer 固定 note\n */\nexport const PHASE_1_VC_LAYER = 'agent_permission' as const\n\n/** Literal type of {@link PHASE_1_VC_LAYER}. */\nexport type Phase1VcLayer = typeof PHASE_1_VC_LAYER\n\n/**\n * Build a {@link PermissionVcClaims_V3} object with `layer` pinned to\n * {@link PHASE_1_VC_LAYER} (`'agent_permission'`).\n *\n * **This factory is mandatory for Phase 1 VC issuance.** Direct assignment\n * of `layer` on a V3 claims literal is discouraged and will be guarded by\n * an ESLint rule once Step 5 wires usage in\n * `packages/api/src/grant/services/remote-vc-issuer.service.ts`. Phase 2+\n * will relax or delete this factory when the other 3 layers unlock.\n *\n * The input `base` type explicitly omits `layer` so passing it is a\n * compile-time error — guaranteeing call-sites cannot accidentally\n * smuggle a non-Phase-1 layer value through.\n *\n * @example\n * ```ts\n * import { buildPhase1VcClaims } from '@vess-id/ai-identity'\n *\n * const claims = buildPhase1VcClaims({\n * v: '3',\n * type: 'PermissionCredential',\n * iss: userDid,\n * sub: agentDid,\n * iat: now,\n * exp: now + 3600,\n * jti,\n * project_id,\n * grant_ids,\n * grant_id,\n * session_id,\n * delegates,\n * })\n * // claims.layer is type-narrowed to 'agent_permission'\n * ```\n */\nexport function buildPhase1VcClaims(\n base: Omit<PermissionVcClaims_V3, 'layer'>,\n): PermissionVcClaims_V3 & { layer: Phase1VcLayer } {\n return { ...base, layer: PHASE_1_VC_LAYER }\n}\n","/**\n * Grant(許可)関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\n/**\n * Grant(許可)の状態\n */\nexport enum GrantStatus {\n PENDING = 'pending', // Agent未確定(OAuth後、Agent接続前)\n ACTIVE = 'active',\n EXPIRED = 'expired',\n REVOKED = 'revoked',\n SUSPENDED = 'suspended',\n EXHAUSTED = 'exhausted' // 回数上限到達\n}\n\n/**\n * Grant(許可)のスコープ\n *\n * - PROJECT: プロジェクト全体に適用される Grant(全メンバーが継承)\n * - USER: 特定ユーザーのみに適用される Grant\n */\nexport enum GrantScope {\n PROJECT = 'project', // Project-level Grant (全メンバーに適用)\n USER = 'user' // User-level Grant (特定ユーザーのみ)\n}\n\n/**\n * リソースタイプ\n */\nexport enum GrantResourceType {\n // Slack\n SLACK_CHANNEL = 'slack:channel',\n SLACK_USER = 'slack:user',\n SLACK_WORKSPACE = 'slack:workspace',\n // GitHub\n GITHUB_REPO = 'github:repo',\n GITHUB_ORG = 'github:org',\n GITHUB_ISSUE = 'github:issue',\n // Google Drive\n GOOGLE_DRIVE_FILE = 'google:drive:file',\n GOOGLE_DRIVE_FOLDER = 'google:drive:folder',\n // Gmail\n GMAIL_THREAD = 'gmail:thread',\n GMAIL_LABEL = 'gmail:label',\n // JIRA\n JIRA_PROJECT = 'jira:project',\n JIRA_BOARD = 'jira:board',\n JIRA_ISSUE = 'jira:issue',\n // OS (local)\n OS_SECRET = 'os:secret',\n // Generic\n ANY = '*'\n}\n\n/**\n * 許可されたリソース範囲\n *\n * Grant(許可)で指定するリソースの範囲を定義します。\n * type、id、patternの組み合わせにより、柔軟なアクセス制御を実現します。\n *\n * @example 基本的な使用例\n * ```typescript\n * // 1. 完全一致: 特定のリソースIDのみ許可\n * const resource1: GrantResource = {\n * type: \"slack:channel\",\n * id: \"C123456\",\n * name: \"general\"\n * }\n *\n * // 2. タイプ全体: 特定タイプの全リソースを許可(セキュリティ注意)\n * const resource2: GrantResource = {\n * type: \"slack:channel\" // 全チャンネルへのアクセスを許可\n * }\n *\n * // 3. パターンマッチ: ワイルドカードを使用\n * const resource3: GrantResource = {\n * type: \"slack:channel\",\n * pattern: \"public-*\", // \"public-\"で始まる全チャンネル\n * name: \"Public channels\"\n * }\n * ```\n *\n * @example 階層的タイプマッチング\n * ```typescript\n * // ベースタイプは全サブタイプにマッチ(セキュリティ注意)\n * const baseType: GrantResource = {\n * type: \"slack\" // \"slack:channel\", \"slack:message\", \"slack:file\" など全てを許可\n * }\n *\n * // ワイルドカードサフィックス\n * const wildcardType: GrantResource = {\n * type: \"slack:*\" // \"slack:channel\", \"slack:message\" など slack: 配下の全タイプを許可\n * }\n *\n * // 具体的なタイプ(推奨)\n * const specificType: GrantResource = {\n * type: \"slack:channel\", // チャンネルのみ\n * pattern: \"team-*\" // さらにパターンで制約\n * }\n * ```\n *\n * @example セキュリティベストプラクティス\n * ```typescript\n * // ❌ 避けるべき設定\n * const bad1: GrantResource = {\n * type: \"*\" // 全リソースタイプへのアクセス(最高リスク)\n * }\n *\n * const bad2: GrantResource = {\n * type: \"slack\" // 全Slackリソースへのアクセス(高リスク)\n * }\n *\n * // ✅ 推奨される設定\n * const good1: GrantResource = {\n * type: \"slack:channel\",\n * id: \"C123456\" // 特定チャンネルのみ(最も安全)\n * }\n *\n * const good2: GrantResource = {\n * type: \"slack:channel\",\n * pattern: \"public-*\" // パターンで制約(比較的安全)\n * }\n *\n * const good3: GrantResource = {\n * type: \"github:repo\",\n * pattern: \"org-name/*\" // 特定組織のリポジトリのみ\n * }\n * ```\n *\n * @security セキュリティガイドライン\n *\n * 1. **最小権限の原則**: 必要最小限のアクセス権限のみを付与\n * - 可能な限り具体的な type を使用\n * - id または pattern で範囲を制限\n *\n * 2. **ベースタイプの危険性**:\n * - type: \"slack\" は \"slack:channel\", \"slack:message\" など全てを許可\n * - 意図しない広範なアクセスを与える可能性\n *\n * 3. **ワイルドカード使用の注意**:\n * - type: \"*\" は全リソースタイプにマッチ(本番環境では避ける)\n * - pattern: \"*\" は全IDにマッチ(極めて慎重に使用)\n *\n * 4. **パターン構文**:\n * - '*' = 0文字以上の任意の文字列(例: \"test-*\" → \"test-1\", \"test-abc\")\n * - '?' = 1文字の任意の文字(例: \"test-?\" → \"test-1\", \"test-a\")\n * - 正規表現として評価されるため、特殊文字のエスケープに注意\n *\n * 5. **ID/pattern未指定の影響**:\n * - id も pattern も未指定の場合、そのタイプの全リソースへのアクセスを許可\n * - 必ず適切な制約を設定することを推奨\n */\nexport interface GrantResource {\n /**\n * リソースタイプ\n *\n * リソースの種類を指定します。階層的な記法をサポート。\n *\n * 形式:\n * - 単純: \"slack\", \"github\"\n * - 階層的: \"slack:channel\", \"github:repo\", \"drive:file\"\n * - ワイルドカード: \"*\", \"slack:*\"\n *\n * @example\n * - \"slack\" → 全Slackリソース(channel, message, file等)\n * - \"slack:channel\" → Slackチャンネルのみ\n * - \"slack:*\" → slack:配下の全タイプ\n * - \"*\" → 全リソースタイプ\n */\n type: GrantResourceType | string\n\n /**\n * 特定リソースID(省略時はそのタイプの全リソースを許可)\n *\n * 具体的なリソースの識別子を指定します。\n * 最も厳格なアクセス制御方法です。\n *\n * @example\n * - \"C123456\" → 特定のSlackチャンネルID\n * - \"repo123\" → 特定のGitHubリポジトリ\n * - undefined → タイプの全リソースを許可(セキュリティ注意)\n */\n id?: string\n\n /**\n * パターンマッチ(例: \"general-*\", \"team-?\")\n *\n * ワイルドカードを使用したパターンマッチングを指定します。\n * id よりも柔軟ですが、より広範なアクセスを許可します。\n *\n * パターン構文:\n * - '*' = 0文字以上の任意の文字列\n * - '?' = 1文字の任意の文字\n *\n * @example\n * - \"public-*\" → \"public-general\", \"public-test\" など\n * - \"team-*-dev\" → \"team-frontend-dev\", \"team-backend-dev\" など\n * - \"C??????\" → Cで始まる6文字のID\n * - \"*\" → 全ID(極めて慎重に使用)\n */\n pattern?: string\n\n /**\n * 表示用名称\n *\n * UIなどでの表示に使用される人間が読める名前です。\n * アクセス制御には影響しません。\n *\n * @example\n * - \"General channel\"\n * - \"Public channels\"\n * - \"Production repositories\"\n */\n name?: string\n\n /**\n * テナント/ワークスペース参照\n *\n * 同一プロバイダーの複数アカウントを区別するための識別子。\n * 例: SlackのworkspaceId, JiraのcloudId, GitHubのorg名\n *\n * Alpha: 定義のみ、評価ロジックなし。\n * 将来のマルチアカウント対応で使用。\n */\n tenant_ref?: string\n}\n\n/**\n * 時間帯制約\n */\nexport interface TimeWindowConstraint {\n /** 許可時間帯開始(HH:mm形式) */\n start?: string\n /** 許可時間帯終了(HH:mm形式) */\n end?: string\n /** タイムゾーン(デフォルト: UTC) */\n timezone?: string\n /** 許可曜日(0=日, 1=月...6=土) */\n daysOfWeek?: number[]\n}\n\n/**\n * 自動承認設定\n * low-riskアクションをapprove.htmlなしで自動的にVC発行する\n */\nexport interface AutoApproveConfig {\n /** 自動承認を有効にするか */\n enabled: boolean\n /** 自動承認を許可するリスクレベル上限 (default: 'low') */\n maxRiskLevel?: 'low' | 'medium'\n /** 自動発行VCの最大有効期間(時間) (default: 24) */\n maxDurationHours?: number\n}\n\n/**\n * Grant制約\n */\nexport interface GrantConstraints {\n /** 最大実行回数 */\n maxInvocations?: number\n /** 時間帯制約 */\n timeWindow?: TimeWindowConstraint\n /** 有効期限(ISO 8601) - constraintsレベルでも指定可能 */\n expiresAt?: string\n /** 許可IPレンジ(CIDR表記) */\n ipAllowlist?: string[]\n /** 許容リスクスコア上限(0-100) */\n riskThreshold?: number\n /** Target constraints for secondary destinations (alpha: type only) */\n targets?: import('./target-binding').TargetConstraint[]\n /** 自動承認設定 */\n autoApprove?: AutoApproveConfig\n /**\n * Cedar 一元化 Step 4 — data-in-policy 許可パターン (Cedar `like` wildcard).\n *\n * 例: `[\"*@vess.id\", \"*@vesslabs.ai\"]` → 各 recipient.address に対し\n * `like \"*@vess.id\" || like \"*@vesslabs.ai\"` の Cedar permit rule が emit される.\n *\n * Spec: docs/specs/2026-05-24-cedar-unification-design.md §4.1 / §13 Step 4\n *\n * Phase 1 では primarily Gmail recipient address のために使う (recipient.address).\n * Phase 2+ で per-target-binding な格納先 (channel.id 等) に拡張する.\n */\n allow_patterns?: string[]\n /**\n * Cedar 一元化 Step 4 — data-in-policy 拒否パターン (Cedar `like` wildcard).\n *\n * 例: `[\"*@competitor.com\"]` → 該当 recipient で Cedar `forbid` rule が emit される.\n * Cedar forbid-overrides-permit semantics により approval があっても denied.\n *\n * Spec: docs/specs/2026-05-24-cedar-unification-design.md §4.1 / §4.2 / §13 Step 4\n */\n deny_patterns?: string[]\n}\n\n/**\n * Grant作成リクエスト\n */\nexport interface CreateGrantRequest {\n /** 許可名(表示用) */\n name: string\n /** 説明 */\n description?: string\n /** Grantのスコープ (project or user) */\n grantScope?: GrantScope\n /** 対象ユーザーID(USER scopeの場合は必須、PROJECT scopeの場合はnull) */\n userId?: string\n /** 許可するリソース範囲 */\n resources: GrantResource[]\n /** 許可するアクション(例: slack:channel.post_message) */\n actions: string[]\n /** 制約 */\n constraints: GrantConstraints\n /** 関連プロジェクトID */\n projectId?: string\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Grant更新リクエスト\n */\nexport interface UpdateGrantRequest {\n /** 許可名 */\n name?: string\n /** 説明 */\n description?: string\n /** リソース範囲 */\n resources?: GrantResource[]\n /** アクション */\n actions?: string[]\n /** 制約 */\n constraints?: GrantConstraints\n /** ステータス */\n status?: GrantStatus\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Grant\n */\nexport interface Grant {\n /** 一意識別子 */\n id: string\n /** 許可名 */\n name: string\n /** 説明 */\n description?: string\n /** 許可を与えた人のDID */\n issuerDid: string\n /** 許可を与えた人の名前 */\n issuerName?: string\n /** Grantのスコープ (project or user) */\n grantScope: GrantScope\n /** 対象ユーザーID(USER scopeの場合のみ、PROJECT scopeの場合はnull) */\n userId?: string\n /** ステータス */\n status: GrantStatus\n /** リソース範囲 */\n resources: GrantResource[]\n /** 許可アクション */\n actions: string[]\n /** 制約 */\n constraints: GrantConstraints\n /** 現在の実行回数 */\n currentInvocations: number\n /** 関連プロジェクトID */\n projectId?: string\n /** 関連プロジェクト名 */\n projectName?: string\n /** 作成日時 */\n createdAt: string\n /** 更新日時 */\n updatedAt: string\n /** 有効期限 */\n expiresAt?: string\n /** 失効日時 */\n revokedAt?: string\n /** 失効理由 */\n revocationReason?: string\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Grant使用状況\n */\nexport interface GrantUsage {\n /** GrantのID */\n grantId: string\n /** 実行回数 */\n invocationCount: number\n /** 最終使用日時 */\n lastUsedAt?: string\n /** 残り実行回数(maxInvocationsが設定されている場合) */\n remainingInvocations?: number\n}\n\n/**\n * Grant権限チェックリクエスト\n */\nexport interface CheckGrantPermissionRequest {\n /** チェック対象のAgent DID */\n agentDid: string\n /** チェックするアクション */\n action: string\n /** チェックするリソース */\n resource?: {\n type: string\n id?: string\n }\n /** 評価コンテキスト */\n context?: {\n ipAddress?: string\n timestamp?: string\n }\n}\n\n/**\n * Grant権限チェック結果\n */\nexport interface CheckGrantPermissionResult {\n /** 許可されているか */\n allowed: boolean\n /** マッチしたGrantのID */\n grantId?: string\n /** 拒否理由(allowedがfalseの場合) */\n reason?: string\n /** 残り実行回数 */\n remainingInvocations?: number\n /** 警告メッセージ */\n warnings?: string[]\n}\n\n// ---------------------------------------------------------------------------\n// Grant → PermissionRule normalization\n// ---------------------------------------------------------------------------\n\nimport {\n PermissionRule,\n PermissionConstraints,\n PermissionResource,\n parseGrantResourceType,\n parseGrantAction,\n} from './permission-vc'\n\n/**\n * Convert Grant's GrantConstraints to PermissionConstraints format.\n *\n * Maps Grant-level constraints to per-rule PermissionConstraints:\n * - maxInvocations → max_invocations\n * - timeWindow → time (recurring)\n * - ipAllowlist → ip_allowlist\n * - riskThreshold → risk_threshold\n */\nexport function grantConstraintsToPermissionConstraints(\n constraints: GrantConstraints\n): PermissionConstraints | undefined {\n const result: PermissionConstraints = {}\n let hasValue = false\n\n if (constraints.maxInvocations !== undefined) {\n result.max_invocations = constraints.maxInvocations\n hasValue = true\n }\n\n if (constraints.timeWindow) {\n result.time = {}\n if (constraints.timeWindow.start) {\n result.time.recurring_start = constraints.timeWindow.start\n }\n if (constraints.timeWindow.end) {\n result.time.recurring_end = constraints.timeWindow.end\n }\n if (constraints.timeWindow.daysOfWeek) {\n result.time.days_of_week = constraints.timeWindow.daysOfWeek\n }\n if (constraints.timeWindow.timezone) {\n result.time.timezone = constraints.timeWindow.timezone\n }\n hasValue = true\n }\n\n if (constraints.ipAllowlist && constraints.ipAllowlist.length > 0) {\n result.ip_allowlist = constraints.ipAllowlist\n hasValue = true\n }\n\n if (constraints.riskThreshold !== undefined) {\n result.risk_threshold = constraints.riskThreshold\n hasValue = true\n }\n\n if (constraints.targets && constraints.targets.length > 0) {\n result.targets = constraints.targets\n hasValue = true\n }\n\n return hasValue ? result : undefined\n}\n\n/**\n * Normalize Grant data into PermissionRule[] for VC claims.\n *\n * This is the core normalization function that bridges the Grant model\n * (user-facing, \"slack:channel\" combined format) to the VC model\n * (machine-evaluated, separated provider + resource.type format).\n *\n * Algorithm:\n * 1. Group actions by provider prefix (slack:*, github:*, etc.)\n * 2. For each provider, create rules combining resources of that provider\n * 3. Attach normalized constraints to each rule\n *\n * @example\n * ```typescript\n * const grant = {\n * resources: [{ type: 'slack:channel', id: 'C123' }],\n * actions: ['slack:channel.post_message', 'slack:channel.read_history'],\n * constraints: { maxInvocations: 100, timeWindow: { start: '09:00', end: '18:00' } }\n * }\n *\n * const rules = grantToPermissionRules(grant.resources, grant.actions, grant.constraints)\n * // Result:\n * // [{\n * // effect: 'allow',\n * // provider: 'slack',\n * // resource: { type: 'channel', id: 'C123' },\n * // actions: ['channel.post_message', 'channel.read_history'],\n * // constraints: { max_invocations: 100, time: { recurring_start: '09:00', ... } }\n * // }]\n * ```\n */\nexport function grantToPermissionRules(\n resources: GrantResource[],\n actions: string[],\n constraints: GrantConstraints,\n grantId?: string\n): PermissionRule[] {\n const permConstraints = grantConstraintsToPermissionConstraints(constraints)\n\n // Group actions by provider\n const actionsByProvider = new Map<string, string[]>()\n for (const action of actions) {\n const parsed = parseGrantAction(action)\n const existing = actionsByProvider.get(parsed.provider) || []\n existing.push(parsed.action)\n actionsByProvider.set(parsed.provider, existing)\n }\n\n // Group resources by provider\n const resourcesByProvider = new Map<string, PermissionResource[]>()\n for (const resource of resources) {\n const parsed = parseGrantResourceType(resource.type as string)\n const existing = resourcesByProvider.get(parsed.provider) || []\n const permResource: PermissionResource = {\n type: parsed.resourceType,\n }\n if (resource.id) {\n permResource.id = resource.id\n }\n if (resource.pattern) {\n permResource.pattern = resource.pattern\n }\n if (resource.tenant_ref) {\n permResource.tenant_ref = resource.tenant_ref\n }\n existing.push(permResource)\n resourcesByProvider.set(parsed.provider, existing)\n }\n\n // Create rules: for each provider, combine its actions with its resources.\n // Wildcard ('*') entries are NOT emitted as standalone rules; they serve as\n // fallbacks for concrete providers that lack their own actions/resources.\n const rules: PermissionRule[] = []\n let ruleIndex = 0\n\n // Collect concrete (non-wildcard) providers from both maps\n const concreteProviders = new Set<string>()\n for (const key of actionsByProvider.keys()) {\n if (key !== '*') concreteProviders.add(key)\n }\n for (const key of resourcesByProvider.keys()) {\n if (key !== '*') concreteProviders.add(key)\n }\n\n // If there are NO concrete providers at all (everything is '*'), emit a\n // single wildcard rule so the grant still has effect.\n if (concreteProviders.size === 0) {\n concreteProviders.add('*')\n }\n\n for (const provider of concreteProviders) {\n const providerActions = actionsByProvider.get(provider) || actionsByProvider.get('*') || ['*']\n const providerResources = resourcesByProvider.get(provider) || resourcesByProvider.get('*') || [{ type: '*', id: '*' }]\n\n for (const resource of providerResources) {\n ruleIndex++\n const rule: PermissionRule = {\n id: grantId ? `${grantId}:r${ruleIndex}` : `r${ruleIndex}`,\n effect: 'allow',\n provider,\n resource,\n actions: providerActions,\n }\n if (permConstraints) {\n rule.constraints = permConstraints\n }\n rules.push(rule)\n }\n }\n\n return rules\n}\n\n/**\n * ApprovalContext — Cedar 一元化 Step 3.5.\n *\n * Spec refs:\n * - docs/specs/2026-05-24-cedar-unification-design.md §6 (approvalContext\n * DTO + token ledger)\n * - docs/specs/2026-05-24-cedar-unification-design.md §7.2 (Cedar\n * context.approval shape)\n * - docs/specs/2026-05-24-cedar-unification-design.md §11.1\n * (`via_approval` event lifecycle)\n *\n * Carried in the body of the VC issuance API on the **retry path** (i.e.\n * after a user clicked 承認 in the approval UI). The server consumes the\n * single-use `token` against the approval-token ledger atomically and then\n * injects `{ granted: true, request_id, outcome_id }` into the Cedar\n * `context.approval` so a policy that previously returned `auth_required`\n * now returns `permit`.\n *\n * Identifier formats (canonical, enforced upstream):\n * - `request_id` : `'req_' + uuid`\n * - `outcome_id` : `'outcome_' + uuid`\n * - `token` : `'tok_' + uuid`\n * - `granted_at` : ISO-8601 timestamp\n * - `granted_by` : user id, or the literal `'system'` for auto-approve\n *\n * Replay protection invariant (spec §6):\n * The `token` is **single-use**. Once consumed by the ledger, a second\n * submission MUST be rejected as `denied_by_user` (ephemeral — does not\n * poison subsequent fresh requests; §5.1 OpenQ-D1 resolution).\n */\nexport interface ApprovalContext {\n /** `req_<uuid>` — the approval-request id embedded in the initial\n * `auth_required` audit event. Used to reverse-link the outcome to the\n * triggering invocation. */\n request_id: string\n /** `outcome_<uuid>` — the approval_outcome event id (Step 6 surfaces this\n * as a first-class row, Step 3.5 only carries it through the ledger). */\n outcome_id: string\n /** `tok_<uuid>` — single-use token. Consumed atomically. */\n token: string\n /** True for 承認, false for 拒否. Step 3.5 only honors `true` (the `false`\n * path is handled by emitting `denied_by_user` directly in the UI). */\n granted: boolean\n /** ISO-8601 timestamp of the approval action. */\n granted_at: string\n /** user id or `'system'` for auto-approve. */\n granted_by: string\n}\n","/**\n * Receipt(証跡)関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\nimport { Grant } from './grant'\n\n/**\n * Receipt(証跡)の状態\n */\nexport enum ReceiptStatus {\n VALID = 'valid',\n EXPIRED = 'expired',\n REVOKED = 'revoked'\n}\n\n/**\n * 実行結果\n */\nexport type ReceiptOutcome = 'success' | 'failure' | 'denied'\n\n/**\n * Receipt(証跡)\n * 許可に基づく実行であることを示す検証可能な記録\n */\nexport interface Receipt {\n /** 一意識別子 */\n id: string\n /** 基となったGrantのID */\n grantId: string\n /** Grant名(参照用) */\n grantName?: string\n /** 対応するAuditEventのID */\n auditEventId: string\n /** Intent内容のハッシュ(SHA-256) */\n intentHash: string\n /** 実行結果 */\n outcome: ReceiptOutcome\n /** 発行者による署名(JWS形式) */\n signature: string\n /** 署名者DID */\n issuerDid: string\n /** 実行したAgent/User DID */\n executorDid: string\n /** 実行アクション */\n action: string\n /** 対象リソース */\n resource?: string\n /** 発行日時 */\n issuedAt: string\n /** 検証日時 */\n verifiedAt?: string\n /** ステータス */\n status: ReceiptStatus\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Receipt作成リクエスト\n */\nexport interface CreateReceiptRequest {\n /** GrantのID */\n grantId: string\n /** AuditEventのID */\n auditEventId: string\n /** Intent内容 */\n intent: {\n action: string\n resource?: string\n parameters?: Record<string, unknown>\n }\n /** 実行結果 */\n outcome: ReceiptOutcome\n /** 実行者DID */\n executorDid: string\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Receipt検証リクエスト\n */\nexport interface VerifyReceiptRequest {\n /** ReceiptのID(署名から検証する場合は省略可) */\n receiptId?: string\n /** 署名(IDから検証する場合は省略可) */\n signature?: string\n}\n\n/**\n * Receipt検証結果\n */\nexport interface VerifyReceiptResult {\n /** 検証結果 */\n valid: boolean\n /** Receipt情報 */\n receipt?: Receipt\n /** 関連Grant情報 */\n grant?: Grant\n /** エラーメッセージ */\n error?: string\n /** 検証日時 */\n verifiedAt?: string\n}\n\n/**\n * Receipt検索クエリ\n */\nexport interface ReceiptSearchQuery {\n /** GrantのIDでフィルタ */\n grantId?: string\n /** 実行者DIDでフィルタ */\n executorDid?: string\n /** アクションでフィルタ */\n action?: string\n /** 結果でフィルタ */\n outcome?: ReceiptOutcome\n /** 開始日時 */\n startDate?: string\n /** 終了日時 */\n endDate?: string\n /** 取得件数上限 */\n limit?: number\n /** オフセット */\n offset?: number\n}\n\n/**\n * Receipt一覧結果\n */\nexport interface ReceiptListResult {\n /** Receipt一覧 */\n receipts: Receipt[]\n /** 総件数 */\n total: number\n /** 取得件数上限 */\n limit: number\n /** オフセット */\n offset: number\n}\n","/**\n * Intent(操作意図)関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\n/**\n * リソース情報\n */\nexport interface IntentResource {\n /** リソースタイプ(SlackChannel, DriveFile等) */\n type: string\n /** リソース識別子 */\n id?: string\n /** ワークスペース/フォルダ等の範囲 */\n scope?: string\n /** 追加のリソース属性 */\n attributes?: Record<string, unknown>\n}\n\n/**\n * Intent(操作意図)\n * SaaS依存を最小化した「操作意図」の正規化表現\n */\nexport interface Intent {\n /** 権限主体のDID(誰の代わりに実行するか) */\n subject: string\n /** 実行者のDID(Agent/User) */\n actor: string\n /** 正規化アクション名(例: slack:channel.post_message) */\n action: string\n /** リソース情報 */\n resource: IntentResource\n /** パラメータ */\n parameters: Record<string, unknown>\n /** タイムスタンプ(ISO 8601) */\n timestamp: string\n /** 相関ID(トレース用) */\n traceId?: string\n}\n\n/**\n * 正規化されたIntent\n */\nexport interface NormalizedIntent extends Intent {\n /** 元のツール名 */\n originalToolName: string\n /** 元のアクション名 */\n originalAction: string\n /** 正規化後のアクション名 */\n normalizedAction: string\n /** コネクタ固有データ(SaaS固有情報を隔離) */\n connectorSpecificData?: Record<string, unknown>\n}\n\n/**\n * Intent正規化リクエスト\n */\nexport interface NormalizeIntentRequest {\n /** ツール名(slack, github, drive等) */\n toolName: string\n /** アクション名(postMessage, createIssue等) */\n action: string\n /** パラメータ */\n parameters: Record<string, unknown>\n /** 実行者DID */\n actorDid: string\n /** 権限主体DID(省略時はactorDid) */\n subjectDid?: string\n /** 相関ID */\n traceId?: string\n}\n\n/**\n * アクションマッピング\n * 各コネクタのアクションを正規化アクションにマッピング\n */\nexport interface ActionMapping {\n /** コネクタ名 */\n connector: string\n /** 元のアクション名 */\n originalAction: string\n /** 正規化アクション名 */\n normalizedAction: string\n /** リソースタイプ */\n resourceType: string\n /** 説明 */\n description?: string\n}\n\n/**\n * Intent評価結果\n */\nexport interface IntentEvaluationResult {\n /** 許可されているか */\n allowed: boolean\n /** マッチしたGrantのID */\n matchedGrantId?: string\n /** 拒否理由 */\n reason?: string\n /** Obligations(追加要件) */\n obligations?: IntentObligation[]\n /** 警告 */\n warnings?: string[]\n}\n\n/**\n * Obligation(追加要件)\n */\nexport interface IntentObligation {\n /** Obligationタイプ */\n type: 'audit_enhanced' | 'mask_data' | 'require_approval' | 'rate_limit' | 'notify'\n /** 詳細設定 */\n config?: Record<string, unknown>\n /** 説明 */\n description?: string\n}\n\n/**\n * 標準アクション定義\n * 各コネクタで共通して使用可能なアクションカテゴリ\n */\nexport enum StandardActionCategory {\n READ = 'read',\n WRITE = 'write',\n DELETE = 'delete',\n LIST = 'list',\n SEARCH = 'search',\n SHARE = 'share',\n ADMIN = 'admin'\n}\n\n/**\n * 標準アクションプレフィックス\n */\nexport const ACTION_PREFIXES = {\n SLACK: 'slack',\n GITHUB: 'github',\n GMAIL: 'gmail',\n CALENDAR: 'calendar',\n JIRA: 'jira',\n} as const\n","/**\n * OAuth関連の型定義\n * VESS AI Agent Permission Gateway MVP\n */\n\n/**\n * OAuthプロバイダー\n */\nexport enum OAuthProvider {\n SLACK = 'slack',\n GITHUB = 'github',\n GOOGLE = 'google',\n JIRA = 'jira'\n}\n\n/**\n * OAuthトークン情報\n */\nexport interface OAuthToken {\n /** アクセストークン */\n accessToken: string\n /** リフレッシュトークン */\n refreshToken?: string\n /** トークンタイプ(通常 'Bearer') */\n tokenType: string\n /** 有効期限(秒) */\n expiresIn?: number\n /** 有効期限(ISO 8601) */\n expiresAt?: string\n /** スコープ */\n scope?: string[]\n}\n\n/**\n * OAuth接続状態\n */\nexport interface OAuthConnection {\n /** プロバイダー */\n provider: OAuthProvider\n /** 接続済みか */\n connected: boolean\n /** 接続日時 */\n connectedAt?: string\n /** ユーザー情報(プロバイダー固有) */\n userInfo?: Record<string, unknown>\n /** メタデータ */\n metadata?: Record<string, unknown>\n}\n\n/**\n * OAuth認可リクエスト\n */\nexport interface OAuthAuthorizeRequest {\n /** プロバイダー */\n provider: OAuthProvider\n /** リダイレクトURI */\n redirectUri: string\n /** スコープ */\n scope?: string[]\n /** 状態パラメータ */\n state?: string\n}\n\n/**\n * OAuthコールバックパラメータ\n */\nexport interface OAuthCallbackParams {\n /** 認可コード */\n code: string\n /** 状態パラメータ */\n state?: string\n /** エラー */\n error?: string\n /** エラー詳細 */\n errorDescription?: string\n}\n","/**\n * Invitation - User invitation to a project\n */\n\n/**\n * Status of an invitation\n */\nexport enum InvitationStatus {\n PENDING = 'pending',\n ACCEPTED = 'accepted',\n EXPIRED = 'expired',\n REVOKED = 'revoked'\n}\n\n/**\n * Role assigned to an invited user\n */\nexport type InvitationRole = 'admin' | 'member' | 'viewer'\n\n/**\n * Represents a user invitation to a project\n */\nexport interface Invitation {\n /** Unique identifier for the invitation */\n id: string\n /** Unique token used for accepting the invitation */\n token: string\n /** ID of the project the user is invited to */\n projectId: string\n /** Name of the project (optional) */\n projectName?: string\n /** Email address of the invited user */\n email: string\n /** Role assigned to the user upon accepting */\n role: InvitationRole\n /** User ID of the person who sent the invitation */\n invitedBy: string\n /** Name of the person who sent the invitation (optional) */\n invitedByName?: string\n /** Current status of the invitation */\n status: InvitationStatus\n /** Date when the invitation expires */\n expiresAt: Date\n /** Date when the invitation was accepted (if accepted) */\n acceptedAt?: Date\n /** Date when the invitation was created */\n createdAt: Date\n /** Date when the invitation was last updated */\n updatedAt: Date\n /** Additional metadata associated with the invitation */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Request payload for creating a new invitation\n */\nexport interface CreateInvitationRequest {\n /** ID of the project to invite the user to */\n projectId: string\n /** Email address of the user to invite */\n email: string\n /** Role to assign to the user (defaults to 'member') */\n role?: InvitationRole\n /** Number of hours until the invitation expires */\n expiresInHours?: number\n /** Additional metadata to attach to the invitation */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Request payload for accepting an invitation\n */\nexport interface AcceptInvitationRequest {\n /** Invitation token from the invitation link */\n token: string\n /** Email address of the user accepting the invitation */\n email: string\n /** Password for the new user account */\n password: string\n /** First name of the user (optional) */\n firstName?: string\n /** Last name of the user (optional) */\n lastName?: string\n}\n\n/**\n * Response returned when verifying an invitation token\n */\nexport interface VerifyInvitationResponse {\n /** Email address the invitation was sent to */\n email: string\n /** ID of the project the user is invited to */\n projectId: string\n /** Name of the project (optional) */\n projectName?: string\n /** Role that will be assigned upon accepting */\n role: InvitationRole\n /** Name of the person who sent the invitation (optional) */\n invitedBy?: string\n /** Date when the invitation expires */\n expiresAt: Date\n}\n","/**\n * Permission Mode Types\n * プロジェクトのGrant管理モード定義\n */\n\n/**\n * パーミッションモード\n * - strict: 全て明示的Grant必要(デフォルト・現在の動作)\n * - assisted: OAuth認証後に推奨Grantを提案、ユーザーが承認\n * - permissive: デフォルト権限有効(警告付き)\n */\nexport type PermissionMode = 'strict' | 'assisted' | 'permissive'\n\n/**\n * Grant提案用のリスクレベル(action-registryと整合)\n */\nexport type SuggestionRiskLevel = 'low' | 'medium' | 'high' | 'critical'\n\n/**\n * 推奨アクション(リスクレベル付き)\n */\nexport interface SuggestedAction {\n /** アクション名 (例: slack:channel.post_message) */\n action: string\n /** リスクレベル */\n riskLevel: SuggestionRiskLevel\n /** 表示用説明 */\n description?: string\n /** 必要なOAuthスコープ */\n requiredScopes: string[]\n /** 含まれるcapability */\n capability?: string\n /** 推奨されたかどうか(ユーザーが調整可能) */\n selected: boolean\n}\n\n/**\n * 推奨リソース\n */\nexport interface SuggestedResource {\n /** リソースタイプ */\n type: string\n /** 特定リソースID */\n id?: string\n /** パターンマッチ */\n pattern?: string\n /** 表示用名称 */\n name?: string\n /** 選択されているか */\n selected: boolean\n}\n\n/**\n * 推奨制約\n */\nexport interface SuggestedConstraints {\n /** 最大実行回数 */\n maxInvocations?: number\n /** 有効期限(日数) */\n expiresInDays?: number\n /** 時間帯制約 */\n timeWindow?: {\n start: string\n end: string\n timezone: string\n daysOfWeek: number[]\n }\n}\n\n/**\n * 推奨Grant\n */\nexport interface SuggestedGrant {\n /** 一時ID(セッション内で識別) */\n suggestionId: string\n /** 推奨Grant名 */\n name: string\n /** 説明 */\n description?: string\n /** 対象ユーザーID */\n userId?: string\n /** プロジェクトID */\n projectId: string\n /** OAuthプロバイダー */\n provider: string\n /** 推奨アクション一覧 */\n suggestedActions: SuggestedAction[]\n /** 推奨リソース */\n suggestedResources: SuggestedResource[]\n /** 推奨制約 */\n suggestedConstraints: SuggestedConstraints\n /** OAuthトークンID参照 */\n oauthTokenId: string\n /** 元のOAuthスコープ */\n originalScopes: string[]\n /** 有効期限(この提案自体の) */\n expiresAt: string\n /** 作成日時 */\n createdAt: string\n /** 作成されたGrant ID(createPending時) */\n grantId?: string\n}\n\n/**\n * Grant提案リクエスト\n */\nexport interface SuggestGrantRequest {\n /** OAuthトークンID */\n oauthTokenId: string\n /** 対象ユーザーID(必須) */\n userId: string\n /** プロジェクトID */\n projectId: string\n}\n\n/**\n * Grant提案確認リクエスト\n */\nexport interface ConfirmGrantSuggestionRequest {\n /** 推奨Grant ID */\n suggestionId: string\n /** 選択したアクション */\n selectedActions: string[]\n /** 選択したリソース */\n selectedResources: SuggestedResource[]\n /** 調整した制約 */\n constraints: {\n maxInvocations?: number\n expiresAt?: string\n timeWindow?: {\n start: string\n end: string\n timezone: string\n daysOfWeek: number[]\n }\n }\n /** カスタムGrant名 */\n name?: string\n /** カスタム説明 */\n description?: string\n}\n\n/**\n * リスクレベルに基づくデフォルト制約マッピング\n */\nexport const DEFAULT_CONSTRAINTS_BY_RISK: Record<SuggestionRiskLevel, SuggestedConstraints> = {\n low: {\n maxInvocations: 1000,\n expiresInDays: 90,\n },\n medium: {\n maxInvocations: 200,\n expiresInDays: 30,\n },\n high: {\n maxInvocations: 50,\n expiresInDays: 7,\n timeWindow: {\n start: '09:00',\n end: '18:00',\n timezone: 'UTC',\n daysOfWeek: [1, 2, 3, 4, 5], // 平日のみ\n },\n },\n critical: {\n maxInvocations: 10,\n expiresInDays: 1,\n timeWindow: {\n start: '09:00',\n end: '17:00',\n timezone: 'UTC',\n daysOfWeek: [1, 2, 3, 4, 5], // 平日のみ\n },\n },\n}\n","export type UserTier = 'free' | 'pro' | 'team'\n\nexport interface TierLimits {\n maxProjects: number\n maxWritesPerMonth: number\n maxWriteVcTtlMinutes: number\n readAutoApproveMaxRiskLevel: 'low' | 'medium' | 'none'\n readAutoApproveTtlMinutes: number\n writeAutoApproveEnabled: boolean\n auditRetentionDays: number\n auditExportEnabled: boolean\n}\n\nexport const TIER_LIMITS: Record<UserTier, TierLimits> = {\n free: {\n maxProjects: 1,\n // GTM doc §3 Tier 構成: Free = 100 writes/月. Raised from 50 to 100\n // (2026-05-14 tier drift fix) so Aha 到達前にユーザーを枯渇させない。\n maxWritesPerMonth: 100,\n maxWriteVcTtlMinutes: 5,\n readAutoApproveMaxRiskLevel: 'low',\n readAutoApproveTtlMinutes: 30,\n writeAutoApproveEnabled: false,\n auditRetentionDays: 7,\n auditExportEnabled: false,\n },\n pro: {\n maxProjects: 3,\n // GTM doc §3 Tier 構成: Pro = 2,000 writes/月. Raised from 300 to 2,000\n // (2026-05-14 tier drift fix) — backend was 6.7x below the published GTM\n // commitment. Overage billing ($0.07 / action) kicks in beyond 2,000.\n maxWritesPerMonth: 2000,\n maxWriteVcTtlMinutes: 1440, // 24h\n readAutoApproveMaxRiskLevel: 'medium',\n readAutoApproveTtlMinutes: 1440, // 24h\n writeAutoApproveEnabled: true, // SESSION_GRANT for low-risk\n auditRetentionDays: 30,\n auditExportEnabled: true,\n },\n team: {\n maxProjects: -1, // unlimited\n // GTM doc §3 Tier 構成: Team = 10,000 writes/月 (team 合計). Per-user\n // enforcement is intentionally unlimited (-1) in M1 Closed Beta; the\n // team-aggregate 10K cap is deferred to M2 (requires team-scoped quota\n // ledger). Documented in GTM doc §3 annotation.\n maxWritesPerMonth: -1, // unlimited (M1 fair use; M2 enforces 10K team total)\n maxWriteVcTtlMinutes: 10080, // 168h\n readAutoApproveMaxRiskLevel: 'medium',\n readAutoApproveTtlMinutes: 10080, // 168h\n writeAutoApproveEnabled: true,\n // GTM doc §3 commits to 90-day audit retention for Team; implementation\n // exceeds this with 365 days as a customer-favorable bonus (documented\n // in GTM doc §3 annotation).\n auditRetentionDays: 365,\n auditExportEnabled: true,\n },\n}\n","import { CredentialType } from '../types'\n\nexport interface DisclosureFields {\n selectiveFields: string[]\n mandatoryFields: string[]\n neverDisclose: string[]\n decoyCount: number\n}\n\nconst DEFAULT_NEVER_DISCLOSE = ['privateKey', 'secret']\n\nconst DEFAULT_DISCLOSURE_CONFIGS: Record<CredentialType, Omit<DisclosureFields, 'decoyCount'>> = {\n [CredentialType.PROJECT_ACCESS]: {\n selectiveFields: ['permissions', 'projectId'],\n mandatoryFields: ['role'],\n neverDisclose: DEFAULT_NEVER_DISCLOSE,\n },\n [CredentialType.TOOL_ACCESS]: {\n selectiveFields: ['actions', 'tool', 'resourceScope'],\n mandatoryFields: [],\n neverDisclose: DEFAULT_NEVER_DISCLOSE,\n },\n [CredentialType.ADMIN]: {\n selectiveFields: ['adminLevel', 'scope'],\n mandatoryFields: ['authorizedBy'],\n neverDisclose: [...DEFAULT_NEVER_DISCLOSE, 'internalId'],\n },\n [CredentialType.DEVELOPER]: {\n selectiveFields: ['skills', 'experience', 'projects'],\n mandatoryFields: ['name'],\n neverDisclose: ['salary', 'privateInfo'],\n },\n [CredentialType.TEMPORARY]: {\n selectiveFields: [],\n mandatoryFields: [],\n neverDisclose: DEFAULT_NEVER_DISCLOSE,\n },\n [CredentialType.RECEIPT]: {\n selectiveFields: ['action', 'resource', 'outcome', 'amount', 'description', 'date', 'transactionId'],\n mandatoryFields: ['grantId', 'auditEventId', 'receiptType'],\n neverDisclose: [...DEFAULT_NEVER_DISCLOSE, 'signature', 'internalReference'],\n },\n}\n\n/**\n * Get selective disclosure fields for a given credential type.\n * If requestedFields is provided, they are filtered against the neverDisclose list.\n */\nexport function getDefaultDisclosureFields(\n credentialType: CredentialType,\n requestedFields?: string[]\n): DisclosureFields {\n const config = DEFAULT_DISCLOSURE_CONFIGS[credentialType] || DEFAULT_DISCLOSURE_CONFIGS[CredentialType.TEMPORARY]\n\n let selectiveFields = requestedFields || config.selectiveFields\n selectiveFields = selectiveFields.filter(field => !config.neverDisclose.includes(field))\n\n return {\n selectiveFields,\n mandatoryFields: config.mandatoryFields,\n neverDisclose: config.neverDisclose,\n decoyCount: 0,\n }\n}\n","import {\n IssueSDJWTVCRequest,\n IssueSDJWTVCResult,\n VerifySDJWTVCResult,\n CredentialType\n} from '../types'\nimport { KeyManager } from '../did/key-manager'\nimport { SDJwtClient } from '../utils/sdjwt-client'\nimport { getDefaultDisclosureFields } from '../utils/sdjwt-disclosure'\n\n/**\n * API-focused VC Manager for server-side operations\n * Provides stateless SD-JWT operations without local persistence\n */\nexport class APIVCManager {\n private keyManager: KeyManager\n\n constructor(keyManager?: KeyManager) {\n this.keyManager = keyManager || new KeyManager()\n // Set the KeyManager for SDJwtClient static methods\n SDJwtClient.setKeyManager(this.keyManager)\n }\n\n /**\n * Issue an SD-JWT VC with selective disclosure\n */\n async issueSDJWTVC(request: IssueSDJWTVCRequest): Promise<IssueSDJWTVCResult> {\n // Validate request\n if (!request.issuer || !request.subject) {\n throw new Error('Issuer and subject DIDs are required')\n }\n\n // Get issuer's private key\n const privateKey = await this.keyManager.getKey(request.issuer)\n if (!privateKey) {\n throw new Error(`Private key not found for issuer: ${request.issuer}`)\n }\n\n // Prepare credential payload\n const now = new Date()\n const iat = Math.floor(now.getTime() / 1000)\n\n // Set expiration: use provided date, or default to 24 hours from now\n const expirationDate = request.expirationDate || new Date(now.getTime() + 24 * 60 * 60 * 1000)\n const exp = Math.floor(expirationDate.getTime() / 1000)\n\n // Build IETF SD-JWT VC payload (no W3C VC wrapper)\n const vcPayload = {\n iss: request.issuer,\n sub: request.subject,\n iat,\n exp,\n vct: request.type || CredentialType.TEMPORARY, // IETF SD-JWT VC credential type\n // Direct claims (can be selectively disclosed)\n ...request.claims\n }\n\n // Get selective disclosure configuration based on credential type\n const disclosureConfig = getDefaultDisclosureFields(\n request.type || CredentialType.TEMPORARY,\n request.selectiveDisclosureFields\n )\n\n // Issue SD-JWT VC with selective disclosure\n const credential = await SDJwtClient.issueSDJWT(\n vcPayload,\n privateKey,\n disclosureConfig.selectiveFields\n )\n\n return {\n credential,\n issuer: request.issuer,\n subject: request.subject,\n type: request.type || CredentialType.TEMPORARY,\n expiresAt: expirationDate\n }\n }\n\n /**\n * Verify an SD-JWT VC\n */\n async verifySDJWTVC(credential: string): Promise<VerifySDJWTVCResult> {\n try {\n // Basic format validation\n if (!credential || typeof credential !== 'string') {\n return {\n valid: false,\n error: 'Invalid credential format'\n }\n }\n\n // Verify the SD-JWT VC\n const result = await SDJwtClient.verifySDJWT(credential)\n\n if (!result.valid || !result.payload) {\n return {\n valid: false,\n error: result.error || 'Verification failed'\n }\n }\n\n return {\n valid: true,\n payload: {\n iss: result.payload.iss,\n sub: result.payload.sub,\n vct: result.payload.vct,\n exp: result.payload.exp,\n iat: result.payload.iat,\n // Include any other claims from the payload\n ...Object.fromEntries(\n Object.entries(result.payload).filter(([key]) =>\n !['iss', 'sub', 'vct', 'exp', 'iat'].includes(key)\n )\n )\n }\n }\n } catch (error) {\n return {\n valid: false,\n error: `Verification error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n }\n }\n\n /**\n * Issue a project access credential\n */\n async issueProjectAccessCredential(\n agentDid: string,\n projectId: string,\n permissions: string[],\n issuerDid: string,\n expirationHours = 24\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.PROJECT_ACCESS,\n claims: {\n projectId,\n permissions,\n role: 'developer'\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['permissions']\n })\n }\n\n /**\n * Issue a tool access credential\n */\n async issueToolAccessCredential(\n agentDid: string,\n toolName: string,\n actions: string[],\n projectId: string,\n issuerDid: string,\n expirationHours = 24\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.TOOL_ACCESS,\n claims: {\n tool: toolName,\n actions,\n projectId\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['actions', 'tool']\n })\n }\n\n /**\n * Issue a multi-tool access credential\n */\n async issueMultiToolCredential(\n agentDid: string,\n toolPermissions: Array<{ tool: string; actions: string[] }>,\n projectId: string,\n issuerDid: string,\n expirationHours = 24\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.TOOL_ACCESS,\n claims: {\n toolPermissions,\n projectId\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['toolPermissions']\n })\n }\n\n /**\n * Issue an admin credential\n */\n async issueAdminCredential(\n agentDid: string,\n scope: 'project' | 'global',\n projectId: string | undefined,\n issuerDid: string,\n expirationHours = 8\n ): Promise<IssueSDJWTVCResult> {\n const expirationDate = new Date(Date.now() + expirationHours * 60 * 60 * 1000)\n\n return this.issueSDJWTVC({\n issuer: issuerDid,\n subject: agentDid,\n type: CredentialType.ADMIN,\n claims: {\n scope,\n projectId,\n adminLevel: scope === 'global' ? 'super' : 'project'\n },\n expirationDate,\n projectId,\n selectiveDisclosureFields: ['adminLevel', 'scope']\n })\n }\n}","/**\n * ConstraintEvaluator\n * Grant制約の評価ロジック\n */\n\nimport {\n GrantConstraints,\n TimeWindowConstraint,\n EvaluationContext,\n ConstraintEvaluationResult,\n ConstraintViolation,\n ConstraintWarning,\n PermissionConstraints,\n PermissionTimeConstraint,\n} from '../types'\n\nexport interface ConstraintEvaluatorOptions {\n /** 警告を発する残り実行回数の閾値 */\n invocationWarningThreshold?: number\n /** 警告を発するリスクスコアの閾値(riskThresholdに対する割合) */\n riskWarningRatio?: number\n /** デフォルトタイムゾーン */\n defaultTimezone?: string\n}\n\nconst DEFAULT_OPTIONS: ConstraintEvaluatorOptions = {\n invocationWarningThreshold: 5,\n riskWarningRatio: 0.8,\n defaultTimezone: 'UTC'\n}\n\n/**\n * 制約評価クラス\n */\nexport class ConstraintEvaluator {\n private options: ConstraintEvaluatorOptions\n\n constructor(options?: Partial<ConstraintEvaluatorOptions>) {\n this.options = { ...DEFAULT_OPTIONS, ...options }\n }\n\n /**\n * 制約を総合評価\n */\n evaluate(\n constraints: GrantConstraints,\n context: EvaluationContext,\n currentInvocations: number,\n expiresAt?: Date\n ): ConstraintEvaluationResult {\n const violations: ConstraintViolation[] = []\n const warnings: ConstraintWarning[] = []\n\n // 1. 期限チェック\n const expirationResult = this.checkExpiration(expiresAt, constraints.expiresAt)\n if (expirationResult.violation) {\n violations.push(expirationResult.violation)\n }\n\n // 2. 回数上限チェック\n const invocationResult = this.checkInvocationLimit(\n constraints.maxInvocations,\n currentInvocations\n )\n if (invocationResult.violation) {\n violations.push(invocationResult.violation)\n }\n if (invocationResult.warning) {\n warnings.push(invocationResult.warning)\n }\n\n // 3. 時間帯チェック\n if (constraints.timeWindow) {\n const timeResult = this.checkTimeWindow(\n constraints.timeWindow,\n new Date(context.timestamp)\n )\n if (timeResult.violation) {\n violations.push(timeResult.violation)\n }\n if (timeResult.warning) {\n warnings.push(timeResult.warning)\n }\n }\n\n // 4. IPアドレスチェック\n if (constraints.ipAllowlist && constraints.ipAllowlist.length > 0 && context.ipAddress) {\n const ipResult = this.checkIpAllowlist(constraints.ipAllowlist, context.ipAddress)\n if (ipResult.violation) {\n violations.push(ipResult.violation)\n }\n }\n\n // 5. リスクスコアチェック\n if (constraints.riskThreshold !== undefined && context.riskScore !== undefined) {\n const riskResult = this.checkRiskThreshold(constraints.riskThreshold, context.riskScore)\n if (riskResult.violation) {\n violations.push(riskResult.violation)\n }\n if (riskResult.warning) {\n warnings.push(riskResult.warning)\n }\n }\n\n return {\n allowed: violations.length === 0,\n violations,\n warnings,\n evaluatedAt: new Date().toISOString(),\n context\n }\n }\n\n /**\n * 期限チェック\n */\n checkExpiration(\n grantExpiresAt?: Date,\n constraintExpiresAt?: string\n ): { violation?: ConstraintViolation } {\n const now = new Date()\n\n // Grantレベルの有効期限\n if (grantExpiresAt && new Date(grantExpiresAt) < now) {\n return {\n violation: {\n type: 'expired',\n message: `Grant expired at ${grantExpiresAt.toISOString()}`,\n details: { expiresAt: grantExpiresAt.toISOString(), now: now.toISOString() }\n }\n }\n }\n\n // Constraintレベルの有効期限\n if (constraintExpiresAt && new Date(constraintExpiresAt) < now) {\n return {\n violation: {\n type: 'expired',\n message: `Constraint expired at ${constraintExpiresAt}`,\n details: { expiresAt: constraintExpiresAt, now: now.toISOString() }\n }\n }\n }\n\n return {}\n }\n\n /**\n * 実行回数チェック\n */\n checkInvocationLimit(\n maxInvocations?: number,\n currentInvocations?: number\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n if (maxInvocations === undefined || currentInvocations === undefined) {\n return {}\n }\n\n const remaining = maxInvocations - currentInvocations\n\n if (remaining <= 0) {\n return {\n violation: {\n type: 'max_invocations',\n message: `Invocation limit reached (${maxInvocations} max, ${currentInvocations} used)`,\n details: { maxInvocations, currentInvocations, remaining: 0 }\n }\n }\n }\n\n if (remaining <= this.options.invocationWarningThreshold!) {\n return {\n warning: {\n type: 'approaching_limit',\n message: `Only ${remaining} invocations remaining out of ${maxInvocations}`,\n details: { maxInvocations, currentInvocations, remaining }\n }\n }\n }\n\n return {}\n }\n\n /**\n * 時間帯チェック\n */\n checkTimeWindow(\n timeWindow: TimeWindowConstraint,\n currentTime: Date\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n const timezone = timeWindow.timezone || this.options.defaultTimezone!\n\n // 曜日チェック\n if (timeWindow.daysOfWeek && timeWindow.daysOfWeek.length > 0) {\n const currentDay = this.getDayOfWeekInTimezone(currentTime, timezone)\n if (!timeWindow.daysOfWeek.includes(currentDay)) {\n return {\n violation: {\n type: 'time_window',\n message: `Current day (${this.getDayName(currentDay)}) is not in allowed days`,\n details: {\n currentDay,\n allowedDays: timeWindow.daysOfWeek,\n allowedDayNames: timeWindow.daysOfWeek.map((d: number) => this.getDayName(d))\n }\n }\n }\n }\n }\n\n // 時間帯チェック\n if (timeWindow.start && timeWindow.end) {\n const currentTimeStr = this.getTimeInTimezone(currentTime, timezone)\n\n // 通常の時間帯(例: 09:00-17:00)\n if (timeWindow.start <= timeWindow.end) {\n if (currentTimeStr < timeWindow.start || currentTimeStr > timeWindow.end) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time (${currentTimeStr}) is outside allowed window (${timeWindow.start}-${timeWindow.end})`,\n details: { currentTime: currentTimeStr, start: timeWindow.start, end: timeWindow.end, timezone }\n }\n }\n }\n } else {\n // 日をまたぐ時間帯(例: 22:00-06:00)\n if (currentTimeStr < timeWindow.start && currentTimeStr > timeWindow.end) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time (${currentTimeStr}) is outside allowed window (${timeWindow.start}-${timeWindow.end})`,\n details: { currentTime: currentTimeStr, start: timeWindow.start, end: timeWindow.end, timezone }\n }\n }\n }\n }\n\n // 営業時間外間近の警告(終了1時間前)\n const endMinutes = this.timeToMinutes(timeWindow.end)\n const currentMinutes = this.timeToMinutes(currentTimeStr)\n const minutesUntilEnd = endMinutes - currentMinutes\n\n if (minutesUntilEnd > 0 && minutesUntilEnd <= 60) {\n return {\n warning: {\n type: 'unusual_time',\n message: `Only ${minutesUntilEnd} minutes remaining in allowed time window`,\n details: { minutesUntilEnd, windowEnd: timeWindow.end }\n }\n }\n }\n }\n\n return {}\n }\n\n /**\n * IPアドレスチェック\n */\n checkIpAllowlist(\n allowlist: string[],\n ipAddress: string\n ): { violation?: ConstraintViolation } {\n // ワイルドカードチェック\n if (allowlist.includes('*')) {\n return {}\n }\n\n // 完全一致チェック\n if (allowlist.includes(ipAddress)) {\n return {}\n }\n\n // CIDRマッチングチェック\n for (const entry of allowlist) {\n if (entry.includes('/')) {\n if (this.isIpInCidr(ipAddress, entry)) {\n return {}\n }\n }\n }\n\n return {\n violation: {\n type: 'ip_allowlist',\n message: `IP address ${ipAddress} is not in the allowlist`,\n details: { ipAddress, allowlist }\n }\n }\n }\n\n /**\n * リスクスコアチェック\n */\n checkRiskThreshold(\n threshold: number,\n currentScore: number\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n if (currentScore > threshold) {\n return {\n violation: {\n type: 'risk_threshold',\n message: `Risk score ${currentScore} exceeds threshold ${threshold}`,\n details: { currentScore, threshold }\n }\n }\n }\n\n const warningThreshold = threshold * this.options.riskWarningRatio!\n if (currentScore > warningThreshold) {\n return {\n warning: {\n type: 'high_risk',\n message: `Risk score ${currentScore} is approaching threshold ${threshold}`,\n details: { currentScore, threshold, warningThreshold }\n }\n }\n }\n\n return {}\n }\n\n // ============================================================================\n // PermissionConstraints evaluation (VC-level constraints from PermissionRule)\n // ============================================================================\n\n /**\n * Evaluate PermissionConstraints from a PermissionRule.\n *\n * This is the VC-level constraint evaluator that works with the\n * normalized PermissionConstraints format (as opposed to GrantConstraints).\n *\n * Used by the PolicyEvaluator after rule matching to verify\n * rule-level constraints are satisfied.\n */\n evaluatePermissionConstraints(\n constraints: PermissionConstraints,\n context: {\n now: number\n ipAddress?: string\n riskScore?: number\n invocationCount?: number\n }\n ): { allowed: boolean; violations: ConstraintViolation[]; warnings: ConstraintWarning[] } {\n const violations: ConstraintViolation[] = []\n const warnings: ConstraintWarning[] = []\n\n // 1. Time constraints\n if (constraints.time) {\n const timeResult = this.checkPermissionTimeConstraint(\n constraints.time,\n new Date(context.now * 1000)\n )\n if (timeResult.violation) violations.push(timeResult.violation)\n if (timeResult.warning) warnings.push(timeResult.warning)\n }\n\n // 2. Invocation limit\n if (constraints.max_invocations !== undefined && context.invocationCount !== undefined) {\n const invResult = this.checkInvocationLimit(\n constraints.max_invocations,\n context.invocationCount\n )\n if (invResult.violation) violations.push(invResult.violation)\n if (invResult.warning) warnings.push(invResult.warning)\n }\n\n // 3. IP allowlist\n if (constraints.ip_allowlist && constraints.ip_allowlist.length > 0 && context.ipAddress) {\n const ipResult = this.checkIpAllowlist(constraints.ip_allowlist, context.ipAddress)\n if (ipResult.violation) violations.push(ipResult.violation)\n }\n\n // 4. Risk threshold\n if (constraints.risk_threshold !== undefined && context.riskScore !== undefined) {\n const riskResult = this.checkRiskThreshold(constraints.risk_threshold, context.riskScore)\n if (riskResult.violation) violations.push(riskResult.violation)\n if (riskResult.warning) warnings.push(riskResult.warning)\n }\n\n return {\n allowed: violations.length === 0,\n violations,\n warnings,\n }\n }\n\n /**\n * Check PermissionTimeConstraint (supports both absolute and recurring)\n */\n checkPermissionTimeConstraint(\n time: PermissionTimeConstraint,\n currentTime: Date\n ): { violation?: ConstraintViolation; warning?: ConstraintWarning } {\n const nowUnix = Math.floor(currentTime.getTime() / 1000)\n\n // Absolute constraints\n if (time.not_before !== undefined && nowUnix < time.not_before) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time is before not_before (${new Date(time.not_before * 1000).toISOString()})`,\n details: { now: nowUnix, not_before: time.not_before }\n }\n }\n }\n if (time.not_after !== undefined && nowUnix > time.not_after) {\n return {\n violation: {\n type: 'time_window',\n message: `Current time is after not_after (${new Date(time.not_after * 1000).toISOString()})`,\n details: { now: nowUnix, not_after: time.not_after }\n }\n }\n }\n\n // Recurring constraints\n const timezone = time.timezone || this.options.defaultTimezone!\n if (time.days_of_week && time.days_of_week.length > 0) {\n const currentDay = this.getDayOfWeekInTimezone(currentTime, timezone)\n if (!time.days_of_week.includes(currentDay)) {\n return {\n violation: {\n type: 'time_window',\n message: `Current day (${this.getDayName(currentDay)}) is not in allowed days`,\n details: { currentDay, allowedDays: time.days_of_week }\n }\n }\n }\n }\n\n if (time.recurring_start && time.recurring_end) {\n const tw: TimeWindowConstraint = {\n start: time.recurring_start,\n end: time.recurring_end,\n timezone,\n }\n return this.checkTimeWindow(tw, currentTime)\n }\n\n return {}\n }\n\n // ============================================================================\n // Helper Methods\n // ============================================================================\n\n private getDayOfWeekInTimezone(date: Date, timezone: string): number {\n try {\n const options: Intl.DateTimeFormatOptions = { weekday: 'short', timeZone: timezone }\n const dayStr = date.toLocaleDateString('en-US', options)\n const dayMap: Record<string, number> = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 }\n return dayMap[dayStr] ?? date.getDay()\n } catch {\n return date.getDay()\n }\n }\n\n private getTimeInTimezone(date: Date, timezone: string): string {\n try {\n const options: Intl.DateTimeFormatOptions = {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n timeZone: timezone\n }\n return date.toLocaleTimeString('en-US', options)\n } catch {\n return date.toISOString().slice(11, 16)\n }\n }\n\n private getDayName(day: number): string {\n const names = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n return names[day] || 'Unknown'\n }\n\n private timeToMinutes(time: string): number {\n const [hours, minutes] = time.split(':').map(Number)\n return hours * 60 + minutes\n }\n\n /**\n * Check if an IP address is within a CIDR range or matches exactly.\n * Uses unsigned 32-bit arithmetic to avoid sign-bit issues.\n * Public for reuse by other services (e.g., LocalPolicyEvaluatorService).\n */\n isIpInCidr(ip: string, cidr: string): boolean {\n try {\n if (!cidr.includes('/')) {\n return ip === cidr\n }\n const [range, bits] = cidr.split('/')\n const prefix = parseInt(bits, 10)\n if (isNaN(prefix)) return false\n\n const ipNum = this.ipToNumber(ip)\n const rangeNum = this.ipToNumber(range)\n if (ipNum === null || rangeNum === null) return false\n\n const mask = prefix === 0 ? 0 : (~0 << (32 - prefix)) >>> 0\n return (ipNum & mask) === (rangeNum & mask)\n } catch {\n return false\n }\n }\n\n private ipToNumber(ip: string): number | null {\n const parts = ip.split('.')\n if (parts.length !== 4) return null\n let result = 0\n for (const part of parts) {\n const n = parseInt(part, 10)\n if (isNaN(n) || n < 0 || n > 255) return null\n result = (result << 8) | n\n }\n return result >>> 0\n }\n}\n\n/**\n * デフォルトのConstraintEvaluatorインスタンス\n */\nexport const defaultConstraintEvaluator = new ConstraintEvaluator()\n\n/**\n * 簡易評価関数\n */\nexport function evaluateConstraints(\n constraints: GrantConstraints,\n context: EvaluationContext,\n currentInvocations: number,\n expiresAt?: Date\n): ConstraintEvaluationResult {\n return defaultConstraintEvaluator.evaluate(constraints, context, currentInvocations, expiresAt)\n}\n","import * as fs from 'fs/promises'\nimport * as path from 'path'\nimport * as os from 'os'\nimport { IStateStore } from './state-store.interface'\n\n/**\n * JSON file-based state store.\n * Stores state in ~/.vess/state.json by default.\n * Uses atomic write (temp file → rename) for safety.\n */\nexport class JsonStateStore implements IStateStore {\n private filePath: string\n private data: Record<string, unknown> | null = null\n\n constructor(filePath?: string) {\n this.filePath = filePath || path.join(os.homedir(), '.vess', 'state.json')\n }\n\n async get<T = unknown>(key: string): Promise<T | undefined> {\n const data = await this.load()\n return getNestedValue(data, key) as T | undefined\n }\n\n async set<T = unknown>(key: string, value: T): Promise<void> {\n const data = await this.load()\n setNestedValue(data, key, value)\n await this.save(data)\n }\n\n async delete(key: string): Promise<boolean> {\n const data = await this.load()\n const existed = getNestedValue(data, key) !== undefined\n if (existed) {\n deleteNestedValue(data, key)\n await this.save(data)\n }\n return existed\n }\n\n async has(key: string): Promise<boolean> {\n const data = await this.load()\n return getNestedValue(data, key) !== undefined\n }\n\n async getAll(): Promise<Record<string, unknown>> {\n return { ...(await this.load()) }\n }\n\n async clear(): Promise<void> {\n this.data = {}\n await this.save(this.data)\n }\n\n /**\n * Get the file path used by this store (useful for diagnostics)\n */\n getFilePath(): string {\n return this.filePath\n }\n\n private async load(): Promise<Record<string, unknown>> {\n if (this.data !== null) {\n return this.data\n }\n try {\n const raw = await fs.readFile(this.filePath, 'utf-8')\n this.data = JSON.parse(raw) as Record<string, unknown>\n } catch (err: any) {\n if (err.code === 'ENOENT') {\n this.data = {}\n } else if (err instanceof SyntaxError) {\n // Corrupted JSON — start fresh rather than crashing\n this.data = {}\n } else {\n throw err\n }\n }\n return this.data!\n }\n\n private async save(data: Record<string, unknown>): Promise<void> {\n this.data = data\n const dir = path.dirname(this.filePath)\n await fs.mkdir(dir, { recursive: true, mode: 0o700 })\n\n // Atomic write: write to temp file, then rename\n const tmpPath = this.filePath + '.tmp'\n await fs.writeFile(tmpPath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 })\n await fs.rename(tmpPath, this.filePath)\n }\n}\n\n// --- Nested key helpers ---\n\nfunction getNestedValue(obj: Record<string, unknown>, key: string): unknown {\n const parts = key.split('.')\n let current: unknown = obj\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined\n }\n current = (current as Record<string, unknown>)[part]\n }\n return current\n}\n\nfunction setNestedValue(obj: Record<string, unknown>, key: string, value: unknown): void {\n const parts = key.split('.')\n let current: Record<string, unknown> = obj\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (current[part] === undefined || current[part] === null || typeof current[part] !== 'object') {\n current[part] = {}\n }\n current = current[part] as Record<string, unknown>\n }\n current[parts[parts.length - 1]] = value\n}\n\nfunction deleteNestedValue(obj: Record<string, unknown>, key: string): void {\n const parts = key.split('.')\n let current: Record<string, unknown> = obj\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (current[part] === undefined || typeof current[part] !== 'object') {\n return\n }\n current = current[part] as Record<string, unknown>\n }\n delete current[parts[parts.length - 1]]\n}\n","import { IStateStore } from '../state/state-store.interface'\n\n/**\n * Event returned from the Gateway /events endpoint\n */\nexport interface GatewayEvent {\n id: string\n type: string\n source: string\n timestamp: string\n data: Record<string, unknown>\n metadata?: Record<string, unknown>\n}\n\n/**\n * Response from getEvents\n */\nexport interface GetEventsResponse {\n events: GatewayEvent[]\n cursor?: string\n hasMore: boolean\n}\n\n/**\n * Response from ackEvent\n */\nexport interface AckEventResponse {\n success: boolean\n eventId: string\n}\n\n/**\n * Options for getEvents\n */\nexport interface GetEventsOptions {\n cursor?: string\n limit?: number\n /** Long-poll wait time in seconds (0 = no wait) */\n waitSeconds?: number\n}\n\n/**\n * Gateway API client for event-based communication.\n * Used by CLI (runner/daemon) and any other consumer that needs\n * to long-poll for events and acknowledge them.\n *\n * baseUrl should be the API root without trailing path segments\n * (e.g. \"https://api.aidentity.io\" or \"http://localhost:3000\").\n */\nexport class GatewayClient {\n private baseUrl: string\n private stateStore?: IStateStore\n private apiKey?: string\n private sessionToken?: string\n\n constructor(options: {\n baseUrl: string\n stateStore?: IStateStore\n apiKey?: string\n sessionToken?: string\n }) {\n // Strip trailing slashes and any trailing /v1 path so callers can pass\n // either \"https://api.aidentity.io\" or \"https://api.aidentity.io/v1\".\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '').replace(/\\/v1$/, '')\n this.stateStore = options.stateStore\n this.apiKey = options.apiKey\n this.sessionToken = options.sessionToken\n }\n\n /**\n * Set session token for authenticated requests\n */\n setSessionToken(token: string): void {\n this.sessionToken = token\n }\n\n /**\n * Fetch events from the Gateway.\n * If cursor is not provided, attempts to load it from StateStore.\n *\n * NOTE: The /events long-poll endpoint may not be implemented on the API server yet.\n * This client is designed to work once the endpoint is available.\n */\n async getEvents(options: GetEventsOptions = {}): Promise<GetEventsResponse> {\n // Load cursor from state if not provided\n let cursor = options.cursor\n if (!cursor && this.stateStore) {\n cursor = await this.stateStore.get<string>('events.cursor')\n }\n\n const params = new URLSearchParams()\n if (cursor) params.set('cursor', cursor)\n if (options.limit) params.set('limit', String(options.limit))\n if (options.waitSeconds !== undefined) params.set('wait', String(options.waitSeconds))\n\n const url = `${this.baseUrl}/api/v1/events?${params.toString()}`\n\n const response = await fetch(url, {\n method: 'GET',\n headers: this.buildHeaders(),\n })\n\n if (!response.ok) {\n const body = await response.text().catch(() => '')\n throw new GatewayError(\n `getEvents failed: ${response.status} ${response.statusText}`,\n response.status,\n body\n )\n }\n\n const result = (await response.json()) as GetEventsResponse\n\n // Persist cursor if stateStore is available\n if (result.cursor && this.stateStore) {\n await this.stateStore.set('events.cursor', result.cursor)\n }\n\n return result\n }\n\n /**\n * Acknowledge an event (mark as processed).\n *\n * NOTE: The /events/:id/ack endpoint may not be implemented on the API server yet.\n */\n async ackEvent(eventId: string): Promise<AckEventResponse> {\n const url = `${this.baseUrl}/api/v1/events/${encodeURIComponent(eventId)}/ack`\n\n const response = await fetch(url, {\n method: 'POST',\n headers: this.buildHeaders(),\n })\n\n if (!response.ok) {\n const body = await response.text().catch(() => '')\n throw new GatewayError(\n `ackEvent failed: ${response.status} ${response.statusText}`,\n response.status,\n body\n )\n }\n\n return (await response.json()) as AckEventResponse\n }\n\n /**\n * Validate an API key against the Gateway.\n *\n * @param apiKey API key to validate\n * @param projectId Optional project scope\n * @param requiredScopes Scopes the caller needs — callers should pass the\n * scopes relevant to their context (e.g. MCP passes\n * ['mcp:tools:*', 'mcp:memory:*']).\n */\n async validateApiKey(\n apiKey: string,\n projectId?: string,\n requiredScopes?: string[]\n ): Promise<ApiKeyValidationResult> {\n const url = `${this.baseUrl}/api/mcp/api-keys/validate`\n\n const body: Record<string, unknown> = { projectId }\n if (requiredScopes && requiredScopes.length > 0) {\n body.requiredScopes = requiredScopes\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': apiKey,\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n return { valid: false }\n }\n\n return (await response.json()) as ApiKeyValidationResult\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n if (this.apiKey) {\n headers['X-API-Key'] = this.apiKey\n }\n if (this.sessionToken) {\n headers['Authorization'] = `Bearer ${this.sessionToken}`\n }\n return headers\n }\n}\n\n/**\n * Result of API key validation\n */\nexport interface ApiKeyValidationResult {\n valid: boolean\n userId?: string\n projectId?: string\n scopes?: string[]\n}\n\n/**\n * Error class for Gateway API errors\n */\nexport class GatewayError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody: string\n ) {\n super(message)\n this.name = 'GatewayError'\n }\n}\n","import { IStateStore } from '../state/state-store.interface'\nimport { GatewayClient, ApiKeyValidationResult } from '../gateway/gateway-client'\n\n/**\n * Authentication state persisted in the StateStore\n */\nexport interface AuthState {\n apiKey: string\n apiUrl: string\n userId?: string\n projectId?: string\n scopes?: string[]\n authenticatedAt: string\n}\n\n/**\n * Authentication provider that validates API keys and persists auth state.\n * Used by CLI and MCP to authenticate against the Gateway API.\n */\nexport class AuthProvider {\n private stateStore: IStateStore\n private gatewayClient: GatewayClient\n\n constructor(stateStore: IStateStore, gatewayClient: GatewayClient) {\n this.stateStore = stateStore\n this.gatewayClient = gatewayClient\n }\n\n /**\n * Authenticate with an API key. Validates against the Gateway and\n * persists the result in the StateStore.\n *\n * @returns The validation result\n */\n async login(apiKey: string, apiUrl: string, projectId?: string): Promise<ApiKeyValidationResult> {\n const result = await this.gatewayClient.validateApiKey(apiKey, projectId)\n\n if (result.valid) {\n const authState: AuthState = {\n apiKey,\n apiUrl,\n userId: result.userId,\n projectId: result.projectId || projectId,\n scopes: result.scopes,\n authenticatedAt: new Date().toISOString(),\n }\n await this.stateStore.set('auth', authState)\n }\n\n return result\n }\n\n /**\n * Get the current auth state from the StateStore.\n * Returns undefined if not authenticated.\n */\n async getAuthState(): Promise<AuthState | undefined> {\n return this.stateStore.get<AuthState>('auth')\n }\n\n /**\n * Check if we have stored auth credentials\n */\n async isAuthenticated(): Promise<boolean> {\n const auth = await this.getAuthState()\n return auth !== undefined && auth.apiKey !== undefined\n }\n\n /**\n * Clear auth state (logout)\n */\n async logout(): Promise<void> {\n await this.stateStore.delete('auth')\n }\n\n /**\n * Get the stored API key, or undefined if not authenticated\n */\n async getApiKey(): Promise<string | undefined> {\n const auth = await this.getAuthState()\n return auth?.apiKey\n }\n\n /**\n * Get the stored API URL, or undefined if not authenticated\n */\n async getApiUrl(): Promise<string | undefined> {\n const auth = await this.getAuthState()\n return auth?.apiUrl\n }\n}\n","// action-registry.ts\n// ------------------------------------------------------------\n// Action Registry 型定義 + Ajv バリデーション + ローダ\n// ------------------------------------------------------------\n\n/* ===== 1) 型定義 ===== */\n\nimport { RiskLevel } from '../types/context'\nimport { TargetBindings } from '../types/target-binding'\nexport type { RiskLevel }\nexport type Relation = 'viewer' | 'editor' | 'admin' | 'owner' | 'act_as'\n\n/** Resource type in canonical `provider:resource` format */\nexport type ResourceType = string\n\n/** JSON Schema を受け取るための型。Ajvで別途メタ検証します。 */\nexport type JsonSchema = Record<string, unknown>\n\nexport interface ActionMeta {\n action: string // e.g., \"slack:channel.post_message\"\n resource_type: ResourceType\n required_relations: Relation[] // OR解釈を想定(どれか1つ満たせばOK)\n required_scopes: string[] // プロバイダ生スコープ(例:chat:write, repo)\n capability?: string // 論理バンドル名\n input_schema?: JsonSchema // 入力JSONのSchema(任意)\n constraints?: Record<string, unknown> // rate_bucket, max_size_mb など任意\n effects?: string[] // 監査の説明用\n risk: RiskLevel // registry-driven risk resolution (§4.1); schema-required\n target_bindings?: TargetBindings // Declarative resource binding definitions\n version: string // \"1.0.0\" など\n}\n\nexport interface CapabilityMeta {\n capability: string // e.g., \"slack.messaging.basic\"\n description?: string\n includes: string[] // アクション名の配列\n version: string\n}\n\nexport interface ActionRegistry {\n registry_version: string // 例: \"2025-09-28\"\n actions: ActionMeta[]\n capabilities?: CapabilityMeta[]\n}\n\n/* ===== 2) Ajv スキーマ ===== */\n\nimport Ajv, { DefinedError } from 'ajv'\nimport addFormats from 'ajv-formats'\n\n/** 型定義に対応するJSON Schema(input_schema自体は別メタ検証) */\nconst actionMetaSchema = {\n $id: 'https://vess.ai/schemas/action-meta.json',\n type: 'object',\n additionalProperties: false,\n required: ['action', 'resource_type', 'required_relations', 'required_scopes', 'risk', 'version'],\n properties: {\n action: { type: 'string', minLength: 1 },\n resource_type: {\n type: 'string',\n minLength: 1,\n },\n required_relations: {\n type: 'array',\n minItems: 1,\n items: {\n type: 'string',\n enum: ['viewer', 'editor', 'admin', 'owner', 'act_as'],\n },\n },\n required_scopes: {\n type: 'array',\n minItems: 1,\n items: { type: 'string', minLength: 1 },\n },\n capability: { type: 'string' },\n input_schema: { type: 'object' }, // ← ここは後段で「JSON Schemaとして」別検証\n constraints: { type: 'object', additionalProperties: true },\n effects: {\n type: 'array',\n items: { type: 'string', minLength: 1 },\n },\n risk: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },\n target_bindings: { type: 'object' },\n version: { type: 'string', minLength: 1 },\n },\n} as const\n\nconst capabilityMetaSchema = {\n $id: 'https://vess.ai/schemas/capability-meta.json',\n type: 'object',\n additionalProperties: false,\n required: ['capability', 'includes', 'version'],\n properties: {\n capability: { type: 'string', minLength: 1 },\n description: { type: 'string' },\n includes: {\n type: 'array',\n minItems: 1,\n items: { type: 'string', minLength: 1 },\n },\n version: { type: 'string', minLength: 1 },\n },\n} as const\n\nconst registrySchema = {\n $id: 'https://vess.ai/schemas/action-registry.json',\n type: 'object',\n additionalProperties: false,\n required: ['registry_version', 'actions'],\n properties: {\n registry_version: { type: 'string', minLength: 1 },\n actions: {\n type: 'array',\n minItems: 1,\n items: { $ref: 'https://vess.ai/schemas/action-meta.json' },\n },\n capabilities: {\n type: 'array',\n items: { $ref: 'https://vess.ai/schemas/capability-meta.json' },\n },\n },\n} as const\n\n/* ===== 3) バリデータ構築(input_schemaのメタ検証込み) ===== */\n\n/**\n * Ajv インスタンスを作成。\n * - 本体スキーマ(registry/actions/capabilities)を登録\n * - formats 追加\n * - $id付きで利用\n */\nexport function createAjv(): Ajv {\n const ajv = new Ajv({\n allErrors: true,\n strict: true,\n allowUnionTypes: true,\n // draft-2020-12 デフォルト。input_schema のメタ検証に使う。\n })\n addFormats(ajv)\n\n ajv.addSchema(actionMetaSchema)\n ajv.addSchema(capabilityMetaSchema)\n ajv.addSchema(registrySchema)\n\n return ajv\n}\n\n/**\n * Registry全体の構文検証 + 各Actionの input_schema を「JSON Schemaとして」検証。\n * @returns { ok, errors } 失敗時は diag を含む\n */\nexport function validateRegistryObject(registry: unknown): {\n ok: boolean\n errors?: string[]\n} {\n const ajv = createAjv()\n\n // 1) レジストリ本体の検証\n const validate = ajv.getSchema<ActionRegistry>('https://vess.ai/schemas/action-registry.json')\n if (!validate) {\n return { ok: false, errors: ['Ajv schema not loaded'] }\n }\n const valid = validate(registry)\n if (!valid) {\n return {\n ok: false,\n errors: validate.errors ? formatAjvErrors(validate.errors as DefinedError[]) : [],\n }\n }\n\n const typed = registry as ActionRegistry\n\n // 2) 各action.input_schema を JSON Schema としてメタ検証\n // Ajv は meta-schema を内部保持しているので、compileで検証可能。\n const schemaErrors: string[] = []\n for (const a of typed.actions) {\n if (a.input_schema) {\n try {\n // 個別スキーマとしてコンパイル(不正なら例外 or errors)\n const local = new Ajv({ strict: true, allErrors: true })\n addFormats(local)\n const compiled = local.compile(a.input_schema)\n // コンパイルは成功しても errors が残ることはない想定\n if (compiled.errors?.length) {\n schemaErrors.push(\n `[${a.action}] input_schema errors: ${formatAjvErrors(\n compiled.errors as DefinedError[]\n ).join('; ')}`\n )\n }\n } catch (e: any) {\n schemaErrors.push(`[${a.action}] input_schema invalid: ${e?.message ?? String(e)}`)\n }\n }\n }\n\n if (schemaErrors.length) {\n return { ok: false, errors: schemaErrors }\n }\n\n // 3) capabilities.includes が存在する action に一致するか軽く検証\n if (typed.capabilities?.length) {\n const actionsSet = new Set(typed.actions.map(x => x.action))\n for (const c of typed.capabilities) {\n for (const act of c.includes) {\n if (!actionsSet.has(act)) {\n schemaErrors.push(`[capability:${c.capability}] includes unknown action: ${act}`)\n }\n }\n }\n }\n\n if (schemaErrors.length) {\n return { ok: false, errors: schemaErrors }\n }\n\n return { ok: true }\n}\n\nfunction formatAjvErrors(errors?: DefinedError[] | null): string[] {\n if (!errors?.length) return []\n return errors.map(e => {\n const instancePath = e.instancePath || '/'\n const msg = e.message || 'invalid'\n const params = e.params && Object.keys(e.params).length ? ` (${JSON.stringify(e.params)})` : ''\n return `${instancePath}: ${msg}${params}`\n })\n}\n\n/* ===== 4) ロード関数(ファイル/オブジェクト) ===== */\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * JSONファイルからAction Registryを読み込み、完全検証して返す。\n * @throws Error 検証エラー時は詳細メッセージ付きでthrow\n */\nexport async function loadActionRegistryFromFile(filePath: string): Promise<ActionRegistry> {\n const abs = path.resolve(filePath)\n const raw = await fs.readFile(abs, 'utf8')\n const json = JSON.parse(raw)\n\n const result = validateRegistryObject(json)\n if (!result.ok) {\n const errs = result.errors?.join('\\n - ') || ''\n throw new Error(`ActionRegistry validation failed:\\n - ${errs}`)\n }\n return json as ActionRegistry\n}\n\n/**\n * 既にパース済みのオブジェクトを検証して返す。\n * @throws Error 検証エラー時は詳細メッセージ付きでthrow\n */\nexport function loadActionRegistryFromObject(obj: unknown): ActionRegistry {\n const result = validateRegistryObject(obj)\n if (!result.ok) {\n const errs = result.errors?.join('\\n - ') || ''\n throw new Error(`ActionRegistry validation failed:\\n - ${errs}`)\n }\n return obj as ActionRegistry\n}\n\n/* ===== 5) ヘルパ ===== */\n\n/** アクション名→ActionMeta のルックアップを作成 */\nexport function indexActions(reg: ActionRegistry): Map<string, ActionMeta> {\n const map = new Map<string, ActionMeta>()\n for (const a of reg.actions) map.set(a.action, a)\n return map\n}\n\n/** Capability名→CapabilityMeta のルックアップを作成 */\nexport function indexCapabilities(reg: ActionRegistry): Map<string, CapabilityMeta> {\n const map = new Map<string, CapabilityMeta>()\n for (const c of reg.capabilities ?? []) map.set(c.capability, c)\n return map\n}\n\n/** 指定アクションの required_scopes を取得(無ければ空配列) */\nexport function getRequiredScopes(regIndex: Map<string, ActionMeta>, action: string): string[] {\n return regIndex.get(action)?.required_scopes ?? []\n}\n\n/** 指定アクションの required_relations(OR解釈)を取得(無ければ空配列) */\nexport function getRequiredRelations(\n regIndex: Map<string, ActionMeta>,\n action: string\n): Relation[] {\n return (regIndex.get(action)?.required_relations ?? []) as Relation[]\n}\n\n/* ===== 6) 使い方サンプル(コメント) =====\nimport { loadActionRegistryFromFile, indexActions, getRequiredScopes } from \"./action-registry\";\n\n(async () => {\n const reg = await loadActionRegistryFromFile(\"./action-registry.json\");\n const idx = indexActions(reg);\n\n const action = \"slack:channel.post_message\";\n console.log(\"required scopes:\", getRequiredScopes(idx, action));\n})();\n========================================================== */\n","/**\n * Canonical Provider definitions — single source of truth.\n *\n * All packages (API, remote-mcp, SDK) should import provider constants from here.\n */\n\n/** Canonical provider identifiers */\nexport type CanonicalProvider = 'slack' | 'github' | 'gmail' | 'calendar' | 'jira' | 'os'\n\n/** All valid provider identifiers */\nexport type AnyProvider = CanonicalProvider\n\n/** Ordered list of canonical providers */\nexport const CANONICAL_PROVIDERS: readonly CanonicalProvider[] = [\n 'slack',\n 'github',\n 'gmail',\n 'calendar',\n 'jira',\n 'os',\n] as const\n\n/** Provider alias → canonical provider mapping (empty — no aliases in new format) */\nexport const PROVIDER_ALIASES: Readonly<Record<string, CanonicalProvider>> = {} as const\n\n/**\n * Resolve any provider string to its canonical form.\n *\n * In the new `provider.resource.operation` format, each provider is its own\n * canonical name (e.g., 'gmail', 'calendar', 'github'). No aliases are used.\n *\n * @param provider - raw provider string\n * @param _resolveSubProviders - unused, kept for API compatibility\n */\nexport function resolveProvider(\n provider: string,\n _resolveSubProviders = false,\n): string {\n // Check aliases (currently empty — no aliases in new format)\n const aliased = PROVIDER_ALIASES[provider]\n if (aliased) return aliased\n\n return provider\n}\n\n/**\n * Check if a string is a valid canonical provider.\n */\nexport function isCanonicalProvider(value: string): value is CanonicalProvider {\n return (CANONICAL_PROVIDERS as readonly string[]).includes(value)\n}\n\n/**\n * Check if a string is a valid provider (canonical).\n */\nexport function isValidProvider(value: string): value is AnyProvider {\n return isCanonicalProvider(value)\n}\n","// access-orchestrator.ts\n// ------------------------------------------------------------\n// VC発行時:要求アクションの解決・絞り込み\n// VP時 :権限判定(ReBAC→Delegation(VC)→ABAC→Scope/Cred)\n// ------------------------------------------------------------\n\nimport {\n ActionRegistry,\n ActionMeta,\n CapabilityMeta,\n Relation,\n ResourceType,\n indexActions,\n indexCapabilities,\n getRequiredRelations,\n getRequiredScopes,\n} from './action-registry'\nimport { resolveProvider as _resolveProvider } from './providers'\n\n/* ========== 1) 依存インターフェース(差し替えポイント) ========== */\n\n/** ReBAC: 関係性チェック(SpiceDB/Zanzibar想定)。OR解釈で複数relationのいずれか成立でtrue */\nexport interface ReBACChecker {\n check(\n subjectDid: string, // User DID or Agent DID\n relations: Relation[], // [\"editor\",\"act_as\"] など\n resourceRef: ResourceRef // リソース参照\n ): Promise<boolean>\n}\n\n/** ABAC: 条件判定(Cerbos/OPA想定)。trueなら許可。 */\nexport interface ABACPolicyEngine {\n evaluate(input: AbacInput): Promise<AbacDecision>\n}\nexport interface AbacInput {\n principal: {\n id: string // DID(Agent/User)\n roles?: string[]\n claims?: Record<string, unknown> // VC由来クレームなど\n }\n resource: {\n kind: ResourceType\n id: string // プロバイダのリソースID\n attr?: Record<string, unknown>\n }\n action: string // 標準化アクション名\n context?: Record<string, unknown> // time/ip/riskなど\n}\nexport interface AbacDecision {\n allow: boolean\n ruleId?: string\n reason?: string\n}\n\n/** Credential選択:最小スコープを満たす外部トークンを取得(Bot/Installation/OAuth) */\nexport interface CredentialStore {\n pickMinimal(\n provider: Provider, // \"slack\" | \"github\" | \"gmail\" | \"calendar\" | \"jira\"\n iaId: string, // IntegrationAccount ID\n requiredScopes: string[],\n subjectDid: string // 実行主体(Agent/User)\n ): Promise<CredentialRef | null>\n}\nexport type { CanonicalProvider as Provider } from './providers'\nimport type { CanonicalProvider as Provider } from './providers'\nexport interface CredentialRef {\n id: string\n provider: Provider\n scopes: string[]\n // DPoP/MTLSの鍵バインド対応していれば JWK Thumbprint等も\n}\n\n/** VP検証(SD-JWT/ISO 23220/mdoc/OID4VP):成功時にVCクレームを返す */\nexport interface VpVerifier {\n verifyAndExtractClaims(vpToken: string): Promise<VerifiedVcClaims>\n}\n/** 発行した Delegation VC に含めることを想定した最小構造 */\nexport interface VerifiedVcClaims {\n // 権限表明\n allowed_actions: string[] // 標準化アクション名\n resource_scope: ResourceScope[] // 対象スコープ(Workspace/Resource/IA 単位など)\n expires_at?: string // ISO日時\n actor?: string // on_behalf_of 等(任意)\n assurance_level?: number // ABACで使う\n // キー・バインド(DPoP等)\n cnf?: { jwk_thumbprint?: string }\n // 追加クレーム\n [k: string]: unknown\n}\n\n/* ========== 2) ドメイン補助型 ========== */\n\nexport interface ResourceRef {\n /** プロバイダ別のリソース識別子(例:Slack channel id, GitHub repo full_name, Drive file id) */\n id: string\n type: ResourceType\n /** 紐づくIntegrationAccountのID(どのSlackワークスペース/どのGitHub Orgか) */\n iaId: string\n /** 追加属性(機密度など) */\n attr?: Record<string, unknown>\n}\n\n/** VCに刻む「スコープ」表現の一例(最小定義) */\nexport type ResourceScope =\n | { kind: 'Workspace'; id: string }\n | { kind: 'IntegrationAccount'; id: string }\n | { kind: 'Resource'; type: ResourceType; id: string }\n\n/** 監査用の判定理由 */\nexport interface DecisionTrace {\n rebac?: { ok: boolean; relations: Relation[] }\n delegation?: {\n ok: boolean\n matched_action?: boolean\n in_scope?: boolean\n notExpired?: boolean\n }\n abac?: { ok: boolean; ruleId?: string; reason?: string }\n scope?: { ok: boolean; required: string[]; chosenCredentialId?: string }\n}\n\n/* ========== 3) アクション解決ユーティリティ ========== */\n\n/** Capability名やAction名(混在OK)から、実アクション配列に解決 */\nexport function resolveActionsFromSelection(\n registry: ActionRegistry,\n selection: string[] // [\"slack.messaging.basic\", \"github:repo.create_issue\", ...]\n): string[] {\n const aIndex = indexActions(registry)\n const cIndex = indexCapabilities(registry)\n\n const out = new Set<string>()\n for (const item of selection) {\n if (aIndex.has(item)) {\n out.add(item)\n continue\n }\n const cap = cIndex.get(item)\n if (cap) {\n for (const act of cap.includes) out.add(act)\n continue\n }\n // 未知の名前はスキップ(ログには出してよい)\n }\n return [...out]\n}\n\n/* ========== 4) VC発行計画(発行前チェック & 絞り込み) ========== */\n\nexport interface PlanDelegationInput {\n registry: ActionRegistry\n issuerUserDid: string // 委任元(人間)のDID\n delegateAgentDid: string // 委任先(AI Agent)のDID\n /** ユーザーが UI 等で選んだアクション/ケイパビリティ */\n requested: string[] // action or capability\n /** この委任が及ぶスコープ(Workspace/IA/Resource) */\n resourceScope: ResourceScope[]\n /** 有効期限(ISO) */\n expiresAt?: string\n /** ABAC前提で要求する最小アシュアランス等(必要なら) */\n minAssuranceLevel?: number\n /** ABAC/Cerbos用のruntime context(時間帯/場所/リスク等) */\n context?: Record<string, unknown>\n /** Provider 推測のためのヒント(Credential選択時に使う) */\n providerByIa?: Record<string, Provider> // iaId -> provider\n /** 実行時に用いるReBAC/ABAC/Credentialのハンドラ */\n rebac: ReBACChecker\n abac: ABACPolicyEngine\n creds: CredentialStore\n}\n\nexport interface PlanDelegationResult {\n granted_actions: string[] // VCに刻める実アクション(最終)\n rejected_actions: string[] // 却下されたアクション(理由はtraceで)\n traceByAction: Record<string, DecisionTrace>\n}\n\n/**\n * VC発行前に、リクエストされたアクション群を\n * - Registryに存在\n * - ReBAC(委任元=issuerUserDid が十分な関係を持つ)\n * - ABACポリシー適合\n * - 必要スコープを満たすクレデンシャルが存在\n * の観点で絞り込み、発行して良いものだけ返す。\n */\nexport async function planDelegationForVC(\n input: PlanDelegationInput\n): Promise<PlanDelegationResult> {\n const {\n registry,\n issuerUserDid,\n requested,\n resourceScope,\n rebac,\n abac,\n creds,\n providerByIa = {},\n context,\n } = input\n\n // 1) capability展開 → 実アクションへ\n const requestedActions = resolveActionsFromSelection(registry, requested)\n const aIndex = indexActions(registry)\n\n const granted: string[] = []\n const rejected: string[] = []\n const traceByAction: Record<string, DecisionTrace> = {}\n\n // resourceScopeに Resource 単位が無い場合は、Workspace/IA スコープとして評価し、\n // VC自体は scope をそのまま入れる運用を想定。\n // ここでは「代表リソース」を特定できるケースを優先(Resource Scopeが与えられた場合)\n const resourceScopes = resourceScope.filter(s => s.kind === 'Resource') as {\n kind: 'Resource'\n id: string\n type: ResourceType\n }[]\n\n for (const action of requestedActions) {\n const meta = aIndex.get(action)\n const t: DecisionTrace = {}\n traceByAction[action] = t\n\n if (!meta) {\n rejected.push(action)\n continue\n }\n // 2) ReBACチェック(issuerがそもそも対象を委任できるか)\n // Resourceスコープが与えられていればそれで、無ければスキップ(Workspace/IAは発行時はOKとする運用可)\n if (resourceScopes.length) {\n let rebacOk = false\n for (const rs of resourceScopes) {\n const rels = getRequiredRelations(aIndex, action)\n const ok = await rebac.check(\n issuerUserDid,\n rels.length ? rels : ['owner', 'admin', 'editor', 'viewer'],\n {\n id: rs.id,\n type: rs.type,\n iaId: '', // 発行時点では空でもOK。持っているなら入れる。\n }\n )\n if (ok) {\n rebacOk = true\n break\n }\n }\n t.rebac = { ok: rebacOk, relations: getRequiredRelations(aIndex, action) }\n if (!rebacOk) {\n rejected.push(action)\n continue\n }\n }\n\n // 3) ABAC(発行時の基本ルール:高リスクは委任不可等)\n const abacDec = await abac.evaluate({\n principal: { id: issuerUserDid, roles: ['user'] },\n resource: {\n kind: resourceScopes[0]?.type ?? meta.resource_type,\n id: resourceScopes[0]?.id ?? 'SCOPE_ONLY',\n attr: {},\n },\n action,\n context,\n })\n t.abac = { ok: abacDec.allow, ruleId: abacDec.ruleId, reason: abacDec.reason }\n if (!abacDec.allow) {\n rejected.push(action)\n continue\n }\n\n // 4) Credential存在チェック(最低限:将来の実行で使える見込みか)\n // scope→provider解決は iaId→provider を使う。Resource scope が無ければスキップ可。\n let scopeOk = true\n const required = getRequiredScopes(aIndex, action)\n if (resourceScopes.length && required.length) {\n // どれかのResourceで必要スコープを満たすCredentialが取れればOK\n scopeOk = false\n for (const rs of resourceScopes) {\n const provider = inferProviderByResourceType(rs.type)\n const cred = await creds.pickMinimal(provider, '', required, issuerUserDid)\n if (cred) {\n scopeOk = true\n break\n }\n }\n }\n t.scope = { ok: scopeOk, required }\n if (!scopeOk) {\n rejected.push(action)\n continue\n }\n\n granted.push(action)\n }\n\n return { granted_actions: granted, rejected_actions: rejected, traceByAction }\n}\n\nfunction inferProviderByResourceType(rt: ResourceType): Provider {\n // Canonical format: provider:resource (e.g., 'slack:channel', 'github:repo')\n const colonIdx = rt.indexOf(':')\n if (colonIdx > 0) {\n const provider = rt.substring(0, colonIdx)\n return _resolveProvider(provider, true) as Provider\n }\n // Legacy CamelCase fallback\n switch (rt) {\n case 'SlackChannel':\n return 'slack'\n case 'GitHubRepo':\n return 'github'\n default:\n return 'slack' // fallback\n }\n}\n\n/* ========== 5) 実行時判定(VP提示での許可/拒否) ========== */\n\nexport interface CheckPermissionInput {\n registry: ActionRegistry\n actorDid: string // 実行主体(Agent DID推奨)\n onBehalfOfDid?: string // 人の代理で実行する場合に\n action: string // 標準化アクション\n resource: ResourceRef // 対象リソース\n vpToken: string // 委任VCのVP(SD-JWT/mdoc/OID4VP)\n context?: Record<string, unknown> // ABAC用(時間/場所/リスク等)\n rebac: ReBACChecker\n abac: ABACPolicyEngine\n creds: CredentialStore\n vpVerifier: VpVerifier\n}\n\nexport interface CheckPermissionResult {\n allow: boolean\n reason?: string\n trace: DecisionTrace\n credential?: CredentialRef | null\n}\n\n/**\n * 実行直前のフル判定。\n * 1) ReBAC: actor がresourceに対する 基本関係/act_as を満たすか\n * 2) Delegation(VC): actionがallowedか / resourceがscope内か / 期限内か\n * 3) ABAC: コンテキストやassurance levelに適合するか\n * 4) Scope/Credential: 必要スコープを満たすクレデンシャルが取得できるか\n */\nexport async function checkPermissionWithVP(\n input: CheckPermissionInput\n): Promise<CheckPermissionResult> {\n const { registry, actorDid, action, resource, vpToken, context, rebac, abac, creds, vpVerifier } =\n input\n\n const aIndex = indexActions(registry)\n const meta = aIndex.get(action)\n if (!meta) {\n return { allow: false, reason: 'unknown_action', trace: {} }\n }\n\n const trace: DecisionTrace = {}\n\n // 1) ReBAC\n const rels = getRequiredRelations(aIndex, action)\n const rebacOk = await rebac.check(actorDid, rels.length ? rels : ['viewer'], resource)\n trace.rebac = { ok: rebacOk, relations: rels }\n if (!rebacOk) {\n return { allow: false, reason: 'rebac_denied', trace }\n }\n\n // 2) Delegation(VC/VP)\n const vc = await vpVerifier.verifyAndExtractClaims(vpToken)\n let matchedAction = vc.allowed_actions?.includes(action) ?? false\n // resource scope 判定:VCがWorkspace/IAスコープのみなら、ここではresource.idが含まれるか/包含関係を評価\n let inScope = isResourceInScopes(resource, vc.resource_scope || [])\n // 期限\n const notExpired = !vc.expires_at || new Date(vc.expires_at).getTime() > Date.now()\n\n trace.delegation = {\n ok: matchedAction && inScope && notExpired,\n matched_action: matchedAction,\n in_scope: inScope,\n notExpired,\n }\n if (!trace.delegation.ok) {\n return { allow: false, reason: 'delegation_denied', trace }\n }\n\n // 3) ABAC\n const abacDec = await abac.evaluate({\n principal: {\n id: actorDid,\n roles: ['agent'],\n claims: {\n assurance_level: vc.assurance_level,\n actor: vc.actor,\n },\n },\n resource: {\n kind: resource.type,\n id: resource.id,\n attr: resource.attr || {},\n },\n action,\n context,\n })\n trace.abac = { ok: abacDec.allow, ruleId: abacDec.ruleId, reason: abacDec.reason }\n if (!abacDec.allow) {\n return { allow: false, reason: 'abac_denied', trace }\n }\n\n // 4) 必要スコープを満たすCredential選択\n const provider = inferProviderByResourceType(resource.type)\n const requiredScopes = getRequiredScopes(aIndex, action)\n const cred = await creds.pickMinimal(provider, resource.iaId, requiredScopes, actorDid)\n trace.scope = {\n ok: !!cred,\n required: requiredScopes,\n chosenCredentialId: cred?.id,\n }\n if (!cred) {\n return { allow: false, reason: 'insufficient_scopes', trace, credential: null }\n }\n\n return { allow: true, trace, credential: cred }\n}\n\n/* ========== 6) ヘルパ(スコープ包含) ========== */\n\nfunction isResourceInScopes(resource: ResourceRef, scopes: ResourceScope[]): boolean {\n for (const s of scopes) {\n if (s.kind === 'Resource') {\n if (s.type === resource.type && s.id === resource.id) return true\n } else if (s.kind === 'IntegrationAccount') {\n if (s.id === resource.iaId) return true\n } else if (s.kind === 'Workspace') {\n // Workspace→IA/Resourceの包含をここで判定したければ、マッピングを注入して判定する\n // MVPではWorkspace指定は包括OKとみなす場合は true を返す等、運用方針に合わせて調整\n return true\n }\n }\n return false\n}\n\n/* ========== 7) 例:スタブ実装(MVPテスト用) ========== */\n\n// 開発中の簡易スタブ(本番は各システムに差し替え)\nexport class AllowAllAbac implements ABACPolicyEngine {\n async evaluate(): Promise<AbacDecision> {\n return { allow: true, ruleId: 'allow_all' }\n }\n}\nexport class SimpleRebac implements ReBACChecker {\n constructor(\n private allowRelations: Relation[] = ['viewer', 'editor', 'admin', 'owner', 'act_as']\n ) {}\n async check(_sub: string, relations: Relation[]): Promise<boolean> {\n return relations.some(r => this.allowRelations.includes(r))\n }\n}\nexport class DummyCreds implements CredentialStore {\n async pickMinimal(\n provider: Provider,\n _iaId: string,\n requiredScopes: string[]\n ): Promise<CredentialRef | null> {\n // デモ:githubの'merge'などで'repo'が要れば1個返す、など最小限\n if (!requiredScopes.length) return { id: `${provider}-none`, provider, scopes: [] }\n return { id: `${provider}-demo`, provider, scopes: requiredScopes }\n }\n}\nexport class DummyVpVerifier implements VpVerifier {\n constructor(private vc: VerifiedVcClaims) {}\n async verifyAndExtractClaims(): Promise<VerifiedVcClaims> {\n return this.vc // テスト用:引数無視\n }\n}\n\n/* ========== 8) 使い方(サンプル) ========== */\n/*\n // 1) VC発行計画\n const plan = await planDelegationForVC({\n registry,\n issuerUserDid: \"did:user:alice\",\n delegateAgentDid: \"did:agent:bot1\",\n requested: [\"slack.messaging.basic\", \"github:repo.merge_pr\"],\n resourceScope: [\n { kind: \"IntegrationAccount\", id: \"slack-ia-1\" },\n { kind: \"Resource\", type: \"GitHubRepo\", id: \"vess/awesome\" },\n ],\n rebac: new SimpleRebac([\"owner\", \"admin\", \"editor\"]), // 例えば発行は editor 以上のみ許可\n abac: new AllowAllAbac(),\n creds: new DummyCreds(),\n });\n console.log(plan);\n \n // 2) 実行時判定(VP提示)\n const vpVerifier = new DummyVpVerifier({\n allowed_actions: [\"slack:channel.post_message\", \"github:repo.create_issue\"],\n resource_scope: [\n { kind: \"IntegrationAccount\", id: \"slack-ia-1\" },\n { kind: \"Resource\", type: \"GitHubRepo\", id: \"vess/awesome\" },\n ],\n expires_at: \"2099-12-31T00:00:00Z\",\n assurance_level: 2,\n });\n const res = await checkPermissionWithVP({\n registry,\n actorDid: \"did:agent:bot1\",\n action: \"slack:channel.post_message\",\n resource: { id: \"C123\", type: \"SlackChannel\", iaId: \"slack-ia-1\" },\n vpToken: \"ignored-in-dummy\",\n rebac: new SimpleRebac([\"viewer\", \"editor\", \"act_as\"]),\n abac: new AllowAllAbac(),\n creds: new DummyCreds(),\n vpVerifier,\n });\n console.log(res);\n */\n\n// 適用ポイント(MVPコードへの組み込み)\n// VC発行画面/エンドポイント\n// ユーザーが選んだ capability / action と scope を planDelegationForVC に渡す\n// granted_actions を VC の allowed_actions に、resource_scope と expires_at をそのままVCに含めて発行\n// traceByAction を UI の「なぜ発行不可か」ツールチップにそのまま表示可能\n// 実行ミドルウェア(各 Provider Adapter の前段)\n// リクエストを受けたら checkPermissionWithVP を実行\n// allow=true なら返ってきた credential を使って外部APIを実行\n// trace は監査ログに保存(ReBAC/Delegation/ABAC/Scopeの根拠が揃う)\n// 実装を差し替えるだけ\n// ReBACChecker → SpiceDBの CheckPermission をラップ\n// ABACPolicyEngine → Cerbos/OPAクライアントをラップ\n// CredentialStore → 自前のトークン保管庫\n// VpVerifier → 既存VP検証(SD-JWT/ISO 23220/mdoc/OID4VP)に接続\n","/**\n * Canonical Action Registry — single source of truth.\n *\n * Action names use the `provider.resource.operation` dot format matching\n * the tool adapter implementations in packages/api/src/tool/adapters/.\n *\n * All packages (api, mcp, remote-mcp) MUST reference this registry\n * for action names, scopes, and risk levels.\n */\nexport const ACTION_REGISTRY = {\n registry_version: '2025-09-28',\n actions: [\n // ─── Slack Actions ───\n {\n action: 'slack.message.post',\n resource_type: 'slack:channel',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['chat:write'],\n capability: 'slack.messaging.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID, channel name, or channel name with # prefix' },\n text: { type: 'string', minLength: 1, maxLength: 40000 },\n thread_ts: { type: 'string' },\n username: { type: 'string' },\n icon_emoji: { type: 'string' },\n blocks: { type: 'array' },\n },\n required: ['channel', 'text'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.post' },\n effects: ['Create:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.channel.read',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['channels:read', 'groups:read'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:ChannelList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.user.read',\n resource_type: 'slack:user',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['users:read'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n userId: { type: 'string', description: 'The Slack user ID' },\n },\n required: ['userId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:User'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'userId' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.message.read',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['channels:history', 'groups:history'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID, channel name, or channel name with # prefix' },\n latest: { type: 'string' },\n oldest: { type: 'string' },\n limit: { type: 'integer', minimum: 1, maximum: 30 },\n inclusive: { type: 'boolean' },\n },\n required: ['channel'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.message.read_paginated',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['channels:history', 'groups:history'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID, channel name, or channel name with # prefix' },\n cursor: { type: 'string', description: 'Pagination cursor from previous response' },\n limit: { type: 'integer', minimum: 1, maximum: 30 },\n },\n required: ['channel'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.batch.read',\n resource_type: 'slack:channel',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n // Documentation only — NOT used for runtime access control.\n // Actual permission granting uses parseSlackScopes (oauth.service.ts) with OR-logic:\n // any read scope + any history scope grants slack.batch.read.\n // Tokens with partial scopes (e.g. channels:read + channels:history) will still receive this permission.\n required_scopes: ['channels:read', 'groups:read', 'im:read', 'mpim:read', 'channels:history', 'groups:history', 'im:history', 'mpim:history'],\n capability: 'slack.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID for history retrieval' },\n limit: { type: 'integer', minimum: 1 },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.read' },\n effects: ['Read:ChannelList', 'Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel', required: false },\n },\n version: '1.0.0',\n },\n\n {\n action: 'slack.message.update',\n resource_type: 'slack:channel',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['chat:write'],\n capability: 'slack.messaging.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID containing the message' },\n ts: { type: 'string', description: 'Timestamp of the message to update' },\n text: { type: 'string', minLength: 1, maxLength: 40000 },\n },\n required: ['channel', 'ts', 'text'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.post' },\n effects: ['Update:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n {\n action: 'slack.message.delete',\n resource_type: 'slack:channel',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['chat:write'],\n capability: 'slack.messaging.basic',\n input_schema: {\n type: 'object',\n properties: {\n channel: { type: 'string', description: 'Channel ID containing the message' },\n ts: { type: 'string', description: 'Timestamp of the message to delete' },\n },\n required: ['channel', 'ts'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'slack.post' },\n effects: ['Delete:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'channel' },\n },\n version: '1.0.0',\n },\n\n // ─── GitHub Actions ───\n {\n action: 'github.issue.create',\n resource_type: 'github:repo',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['repo', 'write:issues'],\n capability: 'github.issues.triage',\n input_schema: {\n type: 'object',\n properties: {\n title: { type: 'string', minLength: 1 },\n body: { type: 'string' },\n labels: { type: 'array', items: { type: 'string' } },\n assignees: { type: 'array', items: { type: 'string' } },\n },\n required: ['title'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.write' },\n effects: ['Create:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n {\n action: 'github.issue.list',\n resource_type: 'github:repo',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['repo', 'read:issues'],\n capability: 'github.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n state: { type: 'string', enum: ['open', 'closed', 'all'] },\n labels: { type: 'string' },\n sort: { type: 'string', enum: ['created', 'updated', 'comments'] },\n direction: { type: 'string', enum: ['asc', 'desc'] },\n per_page: { type: 'integer', minimum: 1, maximum: 100 },\n page: { type: 'integer', minimum: 1 },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.read' },\n effects: ['Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n {\n action: 'github.issue.read',\n resource_type: 'github:repo',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['repo', 'read:issues'],\n capability: 'github.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issue_number: { type: 'integer', minimum: 1 },\n },\n required: ['issue_number'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.read' },\n effects: ['Read:Issue'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n {\n action: 'github.issue.update',\n resource_type: 'github:repo',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['repo', 'write:issues'],\n capability: 'github.issues.triage',\n input_schema: {\n type: 'object',\n properties: {\n issue_number: { type: 'integer', minimum: 1 },\n title: { type: 'string' },\n body: { type: 'string' },\n state: { type: 'string', enum: ['open', 'closed'] },\n labels: { type: 'array', items: { type: 'string' } },\n assignees: { type: 'array', items: { type: 'string' } },\n },\n required: ['issue_number'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'github.write' },\n effects: ['Update:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'context' as const, key: 'resource_id' },\n },\n version: '1.0.0',\n },\n\n // ─── Gmail Actions ───\n {\n action: 'gmail.message.search',\n resource_type: 'gmail:thread',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n query: { type: 'string', minLength: 1 },\n maxResults: { type: 'integer', minimum: 1, maximum: 500 },\n },\n required: ['query'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:MessageList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'query', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.message.read',\n resource_type: 'gmail:thread',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n messageId: { type: 'string', minLength: 1 },\n },\n required: ['messageId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:Message'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageId' },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.message.send',\n resource_type: 'gmail:thread',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.compose'],\n capability: 'gmail.compose',\n input_schema: {\n type: 'object',\n properties: {\n to: { type: 'string', minLength: 1 },\n subject: { type: 'string', minLength: 1 },\n body: { type: 'string', minLength: 1 },\n cc: { type: 'string' },\n bcc: { type: 'string' },\n threadId: { type: 'string' },\n inReplyTo: { type: 'string' },\n references: { type: 'string' },\n },\n required: ['to', 'subject', 'body'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Create:Email'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'to', multi: true, separator: ',' },\n secondary: [\n { name: 'cc', source: { source: 'param' as const, param: 'cc' }, type: 'recipient' },\n { name: 'bcc', source: { source: 'param' as const, param: 'bcc' }, type: 'recipient' },\n ],\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.draft.create',\n resource_type: 'gmail:thread',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.compose'],\n capability: 'gmail.compose',\n input_schema: {\n type: 'object',\n properties: {\n to: { type: 'string', minLength: 1 },\n subject: { type: 'string', minLength: 1 },\n body: { type: 'string', minLength: 1 },\n cc: { type: 'string' },\n bcc: { type: 'string' },\n threadId: { type: 'string' },\n inReplyTo: { type: 'string' },\n references: { type: 'string' },\n },\n required: ['to', 'subject', 'body'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Create:Draft'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'to', multi: true, separator: ',' },\n secondary: [\n { name: 'cc', source: { source: 'param' as const, param: 'cc' }, type: 'recipient' },\n { name: 'bcc', source: { source: 'param' as const, param: 'bcc' }, type: 'recipient' },\n ],\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.label.read',\n resource_type: 'gmail:label',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:LabelList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'labelId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.batch.read',\n resource_type: 'gmail:thread',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.readonly'],\n capability: 'gmail.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n messageIds: {\n type: 'array',\n items: { type: 'string', minLength: 1 },\n minItems: 1,\n maxItems: 20,\n },\n },\n required: ['messageIds'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.read' },\n effects: ['Read:MessageBatch'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageIds', required: false },\n },\n version: '1.0.0',\n },\n\n {\n action: 'gmail.message.trash',\n resource_type: 'gmail:message',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.modify'],\n capability: 'gmail.manage',\n input_schema: {\n type: 'object',\n properties: {\n messageId: { type: 'string', minLength: 1 },\n },\n required: ['messageId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Update:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageId' },\n },\n version: '1.0.0',\n },\n {\n action: 'gmail.message.delete',\n resource_type: 'gmail:message',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/gmail.modify'],\n capability: 'gmail.manage',\n input_schema: {\n type: 'object',\n properties: {\n messageId: { type: 'string', minLength: 1 },\n },\n required: ['messageId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'gmail.write' },\n effects: ['Delete:Message'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'messageId' },\n },\n version: '1.0.0',\n },\n\n // ─── Calendar Actions ───\n {\n action: 'calendar.event.list',\n resource_type: 'calendar:event',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/calendar.readonly'],\n capability: 'calendar.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string', description: 'Calendar ID (email address). Defaults to primary calendar.' },\n timeMin: { type: 'string', description: 'Lower bound (inclusive) for event start time, as ISO 8601 datetime, e.g. \"2025-01-15T00:00:00Z\"' },\n timeMax: { type: 'string', description: 'Upper bound (exclusive) for event start time, as ISO 8601 datetime, e.g. \"2025-01-16T00:00:00Z\"' },\n maxResults: { type: 'integer', minimum: 1, maximum: 2500, description: 'Maximum number of events to return' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.read' },\n effects: ['Read:EventList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', required: false, default: 'primary' },\n },\n version: '1.0.0',\n },\n {\n action: 'calendar.event.read',\n resource_type: 'calendar:event',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['https://www.googleapis.com/auth/calendar.readonly'],\n capability: 'calendar.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string' },\n eventId: { type: 'string', minLength: 1 },\n },\n required: ['eventId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.read' },\n effects: ['Read:Event'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'eventId' },\n },\n version: '1.0.0',\n },\n {\n action: 'calendar.event.create',\n resource_type: 'calendar:event',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/calendar'],\n capability: 'calendar.write',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string', description: 'Calendar ID (email address). Defaults to primary calendar.' },\n summary: { type: 'string', minLength: 1, description: 'Event title' },\n description: { type: 'string', description: 'Event description' },\n start: {\n type: 'object',\n description: 'Start time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T10:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-15\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n end: {\n type: 'object',\n description: 'End time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T11:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-16\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n attendees: { type: 'array', description: 'List of attendee objects with email field', items: { type: 'object', properties: { email: { type: 'string' } } } },\n location: { type: 'string', description: 'Event location' },\n },\n required: ['summary', 'start', 'end'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.write' },\n effects: ['Create:Event'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', default: 'primary' },\n secondary: [\n { name: 'attendees', source: { source: 'param' as const, param: 'attendees' }, type: 'participant' },\n ],\n },\n version: '1.0.0',\n },\n {\n action: 'calendar.event.update',\n resource_type: 'calendar:event',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/calendar'],\n capability: 'calendar.write',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string', description: 'Calendar ID (email address). Defaults to primary calendar.' },\n eventId: { type: 'string', minLength: 1, description: 'Event ID to update' },\n summary: { type: 'string', description: 'Event title' },\n description: { type: 'string', description: 'Event description' },\n start: {\n type: 'object',\n description: 'Start time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T10:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-15\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n end: {\n type: 'object',\n description: 'End time. Use dateTime + timeZone for timed events, or date for all-day events.',\n properties: {\n dateTime: { type: 'string', description: 'ISO 8601 datetime, e.g. \"2025-01-15T11:00:00\"' },\n date: { type: 'string', description: 'Date for all-day event, e.g. \"2025-01-16\"' },\n timeZone: { type: 'string', description: 'IANA time zone, e.g. \"Asia/Tokyo\"' },\n },\n },\n attendees: { type: 'array', description: 'List of attendee objects with email field', items: { type: 'object', properties: { email: { type: 'string' } } } },\n location: { type: 'string', description: 'Event location' },\n },\n required: ['eventId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.write' },\n effects: ['Update:Event'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', default: 'primary' },\n secondary: [\n { name: 'attendees', source: { source: 'param' as const, param: 'attendees' }, type: 'participant' },\n ],\n },\n version: '1.0.0',\n },\n\n {\n action: 'calendar.event.delete',\n resource_type: 'calendar:event',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['https://www.googleapis.com/auth/calendar'],\n capability: 'calendar.write',\n input_schema: {\n type: 'object',\n properties: {\n calendarId: { type: 'string' },\n eventId: { type: 'string', minLength: 1 },\n },\n required: ['eventId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'calendar.write' },\n effects: ['Delete:Event'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'calendarId', default: 'primary' },\n },\n version: '1.0.0',\n },\n\n // ─── Jira Actions ───\n {\n action: 'jira.project.read',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n recent: { type: 'number' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:ProjectList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.board.read',\n resource_type: 'jira:board',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n projectKeyOrId: { type: 'string' },\n type: { type: 'string' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:BoardList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.sprint.read',\n resource_type: 'jira:sprint',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n boardId: { type: 'number', minimum: 1 },\n state: { type: 'string' },\n },\n required: ['boardId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:SprintList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'boardId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.list',\n resource_type: 'jira:sprint',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n sprintId: { type: 'number', minimum: 1 },\n maxResults: { type: 'number', minimum: 1, maximum: 100 },\n },\n required: ['sprintId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'sprintId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.search',\n resource_type: 'jira:issue',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n jql: { type: 'string', minLength: 1 },\n maxResults: { type: 'integer', minimum: 1, maximum: 100 },\n startAt: { type: 'integer', minimum: 0 },\n },\n required: ['jql'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'jql', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.worklog.read',\n resource_type: 'jira:issue',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Worklog'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.read',\n resource_type: 'jira:issue',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Issue'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.create',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n projectKey: { type: 'string', minLength: 1 },\n summary: { type: 'string', minLength: 1 },\n description: { type: 'string' },\n issueTypeName: { type: 'string', minLength: 1, description: 'Issue type name (default: Task)' },\n priority: { type: 'string' },\n assigneeAccountId: { type: 'string' },\n labels: { type: 'array', items: { type: 'string' } },\n },\n required: ['projectKey', 'summary'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Create:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKey' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.update',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n summary: { type: 'string' },\n description: { type: 'string' },\n priority: { type: 'string' },\n assigneeAccountId: { type: 'string' },\n labels: { type: 'array', items: { type: 'string' } },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Update:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.delete',\n resource_type: 'jira:project',\n required_relations: ['admin', 'owner', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Delete:Issue'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.comment.create',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n body: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey', 'body'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Create:Comment'],\n // high: comments are publicly visible to all project members, consistent with jira.issue.update\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.comment.read',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'act_as'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Comment'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issue.transition',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n transitionId: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey', 'transitionId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Update:IssueStatus'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.transition.list',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'act_as'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n issueIdOrKey: { type: 'string', minLength: 1 },\n },\n required: ['issueIdOrKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:Transition'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'issueIdOrKey', fallback_param: 'issueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.batch.read',\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {\n projectKeyOrId: { type: 'string' },\n boardId: { type: 'number' },\n sprintId: { type: 'number' },\n jql: { type: 'string' },\n },\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:ProjectList', 'Read:BoardList', 'Read:SprintList', 'Read:IssueList'],\n risk: 'low',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issuelink.create',\n resource_type: 'jira:project',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n typeName: { type: 'string', minLength: 1, description: 'Link type name (e.g. Blocks, Relates)' },\n inwardIssueKey: { type: 'string', minLength: 1 },\n outwardIssueKey: { type: 'string', minLength: 1 },\n commentBody: { type: 'string' },\n },\n required: ['typeName', 'inwardIssueKey', 'outwardIssueKey'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Create:IssueLink'],\n risk: 'high',\n target_bindings: {\n // 両 issue が touch されるが target_bindings は 1 つしか指定できないので\n // outwardIssueKey を主 binding として project_key を導出する。\n // 完全な制御をしたい場合は別途 inwardIssueKey 側も grant チェックする運用を要する。\n resource_id: { source: 'param' as const, param: 'outwardIssueKey', derive: 'project_key' as const },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issuelink.delete',\n resource_type: 'jira:issuelink',\n required_relations: ['editor', 'act_as'],\n required_scopes: ['write:jira-work'],\n capability: 'jira.write.basic',\n input_schema: {\n type: 'object',\n properties: {\n linkId: { type: 'string', minLength: 1, description: 'Internal id of the issue link (from jira.issue.read fields.issuelinks[].id)' },\n },\n required: ['linkId'],\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.write' },\n effects: ['Delete:IssueLink'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'linkId' },\n },\n version: '1.0.0',\n },\n {\n action: 'jira.issuelinktype.list',\n // workspace 全体のメタデータ取得なので、jira.project.read と同様 jira:project\n // resource として扱い、特定 project を要求しないことで全 viewer に許可する。\n resource_type: 'jira:project',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: ['read:jira-work'],\n capability: 'jira.read.basic',\n input_schema: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n constraints: { rate_bucket: 'jira.read' },\n effects: ['Read:IssueLinkTypes'],\n risk: 'low',\n // workspace 全体のメタデータなので resource_id は常に未解決のまま\n // type-only match で評価する (required: false がその挙動)。input_schema には\n // 該当 param が無いため param 値は実行時に必ず undefined になる。\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'projectKeyOrId', required: false },\n },\n version: '1.0.0',\n },\n\n // ─── OS Actions (Local) ───\n {\n action: 'os.secret.read',\n resource_type: 'os:secret',\n required_relations: ['viewer', 'editor', 'admin', 'owner'],\n required_scopes: [],\n input_schema: {\n type: 'object',\n properties: {\n file_path: { type: 'string', description: 'Path to the secret file (e.g., ~/projects/app/.env)' },\n },\n required: ['file_path'],\n additionalProperties: false,\n },\n effects: ['Read:SecretFile'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'file_path' },\n },\n version: '1.0.0',\n },\n {\n action: 'os.secret.write',\n resource_type: 'os:secret',\n required_relations: ['editor', 'admin', 'owner'],\n required_scopes: [],\n input_schema: {\n type: 'object',\n properties: {\n file_path: { type: 'string', description: 'Path to the secret file' },\n content: { type: 'string', description: 'Content to write' },\n },\n required: ['file_path', 'content'],\n additionalProperties: false,\n },\n effects: ['Write:SecretFile'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'file_path' },\n },\n version: '1.0.0',\n },\n {\n action: 'os.process.run',\n resource_type: 'os:process',\n required_relations: ['editor', 'admin', 'owner'],\n required_scopes: [],\n input_schema: {\n type: 'object',\n properties: {\n command: {\n type: 'array',\n items: { type: 'string' },\n description: 'Command and arguments to execute (e.g., [\"pnpm\", \"dev\"])',\n },\n working_directory: {\n type: 'string',\n description: 'Working directory for the process',\n },\n env_profile: {\n type: 'string',\n description: 'VESS env profile name to inject (e.g., \"app_dev\")',\n },\n timeout_seconds: {\n type: 'number',\n description: 'Max execution time in seconds (default: 300)',\n },\n },\n required: ['command'],\n additionalProperties: false,\n },\n effects: ['Execute:Process'],\n risk: 'high',\n target_bindings: {\n resource_id: { source: 'param' as const, param: 'command' },\n },\n version: '1.0.0',\n },\n ],\n capabilities: [\n {\n capability: 'slack.messaging.basic',\n description: 'Post, update, and delete messages in channels',\n includes: ['slack.message.post', 'slack.message.update', 'slack.message.delete'],\n version: '1.0.0',\n },\n {\n capability: 'slack.read.basic',\n description: 'Read channels, messages, and user info',\n includes: ['slack.channel.read', 'slack.user.read', 'slack.message.read', 'slack.message.read_paginated', 'slack.batch.read'],\n version: '1.0.0',\n },\n {\n capability: 'github.read.basic',\n description: 'Read issues from repositories',\n includes: ['github.issue.list', 'github.issue.read'],\n version: '1.0.0',\n },\n {\n capability: 'github.issues.triage',\n description: 'Create and update issues',\n includes: ['github.issue.create', 'github.issue.update'],\n version: '1.0.0',\n },\n {\n capability: 'gmail.read.basic',\n description: 'Read and search Gmail messages and labels',\n includes: ['gmail.message.search', 'gmail.message.read', 'gmail.label.read', 'gmail.batch.read'],\n version: '1.0.0',\n },\n {\n capability: 'gmail.compose',\n description: 'Send emails and create drafts via Gmail',\n includes: ['gmail.message.send', 'gmail.draft.create'],\n version: '1.0.0',\n },\n {\n capability: 'gmail.manage',\n description: 'Trash and permanently delete Gmail messages',\n includes: ['gmail.message.trash', 'gmail.message.delete'],\n version: '1.0.0',\n },\n {\n capability: 'calendar.read.basic',\n description: 'Read and list Google Calendar events',\n includes: ['calendar.event.list', 'calendar.event.read'],\n version: '1.0.0',\n },\n {\n capability: 'calendar.write',\n description: 'Create, update, and delete Google Calendar events',\n includes: ['calendar.event.create', 'calendar.event.update', 'calendar.event.delete'],\n version: '1.0.0',\n },\n {\n capability: 'jira.read.basic',\n description: 'Read Jira issues, projects, boards, sprints, and issue link types',\n includes: ['jira.project.read', 'jira.board.read', 'jira.sprint.read', 'jira.issue.list', 'jira.issue.search', 'jira.worklog.read', 'jira.issue.read', 'jira.batch.read', 'jira.comment.read', 'jira.transition.list', 'jira.issuelinktype.list'],\n version: '1.0.0',\n },\n {\n capability: 'jira.write.basic',\n description: 'Create, update, delete Jira issues, and manage issue links',\n includes: ['jira.issue.create', 'jira.issue.update', 'jira.issue.delete', 'jira.comment.create', 'jira.issue.transition', 'jira.issuelink.create', 'jira.issuelink.delete'],\n version: '1.0.0',\n },\n ],\n}\n","/**\n * Unified ResourceType definitions — single source of truth.\n *\n * Format: `provider:resource` (e.g., 'slack:channel', 'github:repo')\n * For nested resources: `provider:service:resource` (e.g., 'google:drive:file')\n */\n\n/** All known resource types in canonical `provider:resource` format */\nexport const RESOURCE_TYPES = {\n // Slack\n SLACK_CHANNEL: 'slack:channel',\n SLACK_USER: 'slack:user',\n SLACK_WORKSPACE: 'slack:workspace',\n\n // GitHub\n GITHUB_REPO: 'github:repo',\n GITHUB_ORG: 'github:org',\n GITHUB_ISSUE: 'github:issue',\n\n // Google Drive\n GOOGLE_DRIVE_FILE: 'google:drive:file',\n GOOGLE_DRIVE_FOLDER: 'google:drive:folder',\n\n // Gmail\n GMAIL_THREAD: 'gmail:thread',\n GMAIL_LABEL: 'gmail:label',\n\n // Jira\n JIRA_PROJECT: 'jira:project',\n JIRA_BOARD: 'jira:board',\n JIRA_ISSUE: 'jira:issue',\n JIRA_SPRINT: 'jira:sprint',\n\n // OS (local)\n OS_SECRET: 'os:secret',\n OS_PROCESS: 'os:process',\n\n // Wildcard\n ANY: '*',\n} as const\n\nexport type UnifiedResourceType = typeof RESOURCE_TYPES[keyof typeof RESOURCE_TYPES]\n\n/**\n * Legacy CamelCase → canonical resource type mapping.\n * Used for converting Action Registry's resource_type field.\n */\nexport const LEGACY_RESOURCE_TYPE_MAP: Readonly<Record<string, string>> = {\n // Action Registry CamelCase format\n SlackChannel: RESOURCE_TYPES.SLACK_CHANNEL,\n GitHubRepo: RESOURCE_TYPES.GITHUB_REPO,\n DriveFile: RESOURCE_TYPES.GOOGLE_DRIVE_FILE,\n JiraIssue: RESOURCE_TYPES.JIRA_ISSUE,\n JiraProject: RESOURCE_TYPES.JIRA_PROJECT,\n JiraBoard: RESOURCE_TYPES.JIRA_BOARD,\n JiraSprint: RESOURCE_TYPES.JIRA_SPRINT,\n\n // Legacy GrantResourceType format (already canonical — identity mapping)\n 'slack:channel': RESOURCE_TYPES.SLACK_CHANNEL,\n 'slack:user': RESOURCE_TYPES.SLACK_USER,\n 'slack:workspace': RESOURCE_TYPES.SLACK_WORKSPACE,\n 'github:repo': RESOURCE_TYPES.GITHUB_REPO,\n 'github:org': RESOURCE_TYPES.GITHUB_ORG,\n 'github:issue': RESOURCE_TYPES.GITHUB_ISSUE,\n 'jira:project': RESOURCE_TYPES.JIRA_PROJECT,\n 'jira:board': RESOURCE_TYPES.JIRA_BOARD,\n 'jira:issue': RESOURCE_TYPES.JIRA_ISSUE,\n 'jira:sprint': RESOURCE_TYPES.JIRA_SPRINT,\n 'os:secret': RESOURCE_TYPES.OS_SECRET,\n 'os:process': RESOURCE_TYPES.OS_PROCESS,\n\n // Legacy formats with old provider prefixes\n 'gh:repo': RESOURCE_TYPES.GITHUB_REPO,\n 'drive:file': RESOURCE_TYPES.GOOGLE_DRIVE_FILE,\n 'drive:folder': RESOURCE_TYPES.GOOGLE_DRIVE_FOLDER,\n 'google:gmail:thread': RESOURCE_TYPES.GMAIL_THREAD,\n 'google:gmail:label': RESOURCE_TYPES.GMAIL_LABEL,\n}\n\n/**\n * Resolve a resource type string to its canonical form.\n *\n * Handles CamelCase (SlackChannel), legacy prefixes (gh:repo, drive:file),\n * and already-canonical formats (slack:channel).\n */\nexport function resolveResourceType(resourceType: string): string {\n return LEGACY_RESOURCE_TYPE_MAP[resourceType] ?? resourceType\n}\n","/**\n * Centralized action utilities — single source of truth.\n *\n * Canonical action format is `provider.resource.operation` (dot format).\n * Legacy `provider:resource.operation` (colon format) is supported for\n * backward compatibility with existing grants.\n */\n\nimport { resolveProvider } from './providers'\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Canonicalize an action name.\n *\n * Returns the canonical dot format: `provider.resource.operation`.\n * If action already contains the provider prefix, returns as-is.\n *\n * @param provider - Provider name (e.g., 'slack', 'github')\n * @param action - Action name (e.g., 'message.post')\n * @returns Canonical action string (e.g., 'slack.message.post')\n */\nexport function canonicalizeAction(provider: string, action: string): string {\n const canonicalProvider = resolveProvider(provider)\n // If action already starts with provider prefix, return as-is\n if (action.startsWith(`${canonicalProvider}.`)) {\n return action\n }\n return `${canonicalProvider}.${action}`\n}\n\n/**\n * Get aliases for a canonical action.\n *\n * Returns the legacy colon format for backward compatibility.\n */\nexport function getActionAliases(canonicalAction: string): string[] {\n // Generate colon-format alias: \"slack.message.post\" → \"slack:message.post\"\n const dotIdx = canonicalAction.indexOf('.')\n if (dotIdx > 0) {\n const provider = canonicalAction.substring(0, dotIdx)\n const rest = canonicalAction.substring(dotIdx + 1)\n return [`${provider}:${rest}`]\n }\n return []\n}\n\n/**\n * Get all equivalent forms of an action with provider prefix.\n *\n * Returns both dot format (canonical) and colon format (legacy).\n */\nexport function getAllActionForms(provider: string, action: string): string[] {\n const canonicalProvider = resolveProvider(provider)\n const forms: string[] = []\n\n // Dot format (canonical): provider.resource.operation\n if (action.startsWith(`${canonicalProvider}.`)) {\n forms.push(action)\n // Also add colon format\n const rest = action.substring(canonicalProvider.length + 1)\n forms.push(`${canonicalProvider}:${rest}`)\n } else {\n forms.push(`${canonicalProvider}.${action}`)\n forms.push(`${canonicalProvider}:${action}`)\n }\n\n return forms\n}\n\n/**\n * Check if two action strings refer to the same action.\n *\n * Handles both dot and colon separators.\n */\nexport function isActionEquivalent(action1: string, action2: string): boolean {\n if (action1 === action2) return true\n\n const parse = (a: string) => {\n // Try colon first, then dot\n const colonIdx = a.indexOf(':')\n if (colonIdx > 0) {\n return { provider: a.substring(0, colonIdx), action: a.substring(colonIdx + 1) }\n }\n const dotIdx = a.indexOf('.')\n if (dotIdx > 0) {\n return { provider: a.substring(0, dotIdx), action: a.substring(dotIdx + 1) }\n }\n return { provider: '', action: a }\n }\n\n const p1 = parse(action1)\n const p2 = parse(action2)\n\n const np1 = resolveProvider(p1.provider)\n const np2 = resolveProvider(p2.provider)\n\n return np1 === np2 && p1.action === p2.action\n}\n","/**\n * MCP action name normalization — single source of truth.\n *\n * Valid action names are derived from ACTION_REGISTRY, ensuring consistency\n * between grant definitions, MCP tool schemas, and tool adapter implementations.\n *\n * This module provides normalization logic to handle common misformats from LLM clients:\n * - Double prefix: \"calendar.calendar.event.list\" → \"calendar.event.list\"\n * - Colon format: \"slack:message.post\" → \"slack.message.post\"\n * - Missing prefix: \"message.post\" → \"slack.message.post\"\n *\n * `packages/remote-mcp` imports from here to avoid duplication.\n */\n\nimport { ACTION_REGISTRY } from './action-registry-json'\n\n/**\n * Derive valid action names by provider from ACTION_REGISTRY.\n * This ensures VALID_MCP_ACTIONS is always in sync with the registry.\n */\nfunction buildValidActions(): Record<string, string[]> {\n const result: Record<string, string[]> = {}\n for (const entry of ACTION_REGISTRY.actions) {\n const dotIdx = entry.action.indexOf('.')\n if (dotIdx < 0) continue\n const provider = entry.action.substring(0, dotIdx)\n if (!result[provider]) result[provider] = []\n result[provider].push(entry.action)\n }\n return result\n}\n\n/**\n * Valid MCP-facing action names by tool, derived from ACTION_REGISTRY.\n * These are the canonical names that LLM clients should send and that\n * the API grant system uses for permission matching.\n */\nexport const VALID_MCP_ACTIONS: Record<string, string[]> = buildValidActions()\n\n/**\n * All valid MCP tool names.\n */\nexport const VALID_MCP_TOOLS = Object.keys(VALID_MCP_ACTIONS) as string[]\n\n/**\n * Get all valid MCP action names across all tools.\n */\nexport function getAllValidMcpActionNames(): string[] {\n return Object.values(VALID_MCP_ACTIONS).flat()\n}\n\n/**\n * Get valid MCP action names for a specific tool.\n * @returns Array of action names, or empty array if tool is unknown.\n */\nexport function getValidMcpActionNames(toolName: string): string[] {\n return VALID_MCP_ACTIONS[toolName] ?? []\n}\n\n/**\n * Normalize an MCP action name to canonical `provider.resource.operation` format.\n *\n * Handles common misformats from LLM clients:\n * 1. Already valid → return as-is\n * 2. Double prefix: \"calendar.calendar.event.list\" → strip leading \"toolName.\" → \"calendar.event.list\"\n * 3. Colon format: \"slack:message.post\" → replace \":\" with \".\" → \"slack.message.post\"\n * 4. Missing prefix: \"message.post\" → prepend \"toolName.\" → \"slack.message.post\"\n *\n * @param toolName - Tool name (e.g., \"slack\", \"calendar\")\n * @param actionName - Possibly misformatted action name from LLM client\n * @returns Normalized action name, or the original if no valid match found\n */\nexport function normalizeMcpActionName(toolName: string, actionName: string): string {\n if (!actionName) return ''\n if (!toolName) return actionName\n\n const validActions = VALID_MCP_ACTIONS[toolName]\n if (!validActions) return actionName\n\n // 1. Direct match — already correct\n if (validActions.includes(actionName)) {\n return actionName\n }\n\n // 2. Double prefix: \"calendar.calendar.event.list\" → strip \"calendar.\" → \"calendar.event.list\"\n if (actionName.startsWith(`${toolName}.`)) {\n const stripped = actionName.substring(toolName.length + 1)\n if (validActions.includes(stripped)) {\n return stripped\n }\n }\n\n // 3. Colon format: \"slack:message.post\" → \"slack.message.post\"\n if (actionName.includes(':')) {\n const dotFormat = actionName.replace(':', '.')\n if (validActions.includes(dotFormat)) {\n return dotFormat\n }\n }\n\n // 4. Missing prefix: \"message.post\" → \"slack.message.post\"\n if (!actionName.startsWith(`${toolName}.`)) {\n const withPrefix = `${toolName}.${actionName}`\n if (validActions.includes(withPrefix)) {\n return withPrefix\n }\n }\n\n // 5. No match — return original\n return actionName\n}\n","/**\n * Cross-package constants for the reauth pipeline.\n *\n * These string literals are contract-level identifiers shared between:\n * - api (`tool-auth.service.ts`, `token-refresh.service.ts`)\n * - remote-mcp (`mcp-format-result.ts`)\n * - agentd (`gateway-client.ts`, `credential-errors.ts`, `execution-engine.ts`)\n *\n * Hard-coding them at each site made typo bugs silent. Centralizing here\n * means any renames surface as a compile error on every import site.\n */\n\n/**\n * Value for `ToolInvokeResponse.metadata.action` when the api signals a\n * revoked/expired OAuth token. Consumers branch on this to render a reauth\n * prompt (Slack DM card, CLI authUrl, etc.) instead of treating the response\n * as a normal error.\n */\nexport const REAUTH_REQUIRED_ACTION = 'reauth_required' as const\n\n/**\n * Value for `ToolInvokeResult.metadata.action` when an action needs RAR\n * approval (Cedar `RequireApproval`). Consumers (remote-mcp formatter)\n * branch on this to promote `{ approvalUrl, requestId }` into the MCP\n * `structuredContent` / `_meta.aidentity` channel so the URL reaches the\n * client on the FIRST call_tool, not only via a separate request_permission.\n */\nexport const APPROVAL_REQUIRED_ACTION = 'approval_required' as const\n\n/**\n * Error codes emitted by agentd's `gateway-client.invokeTool` to classify\n * failure modes for the ExecutionEngine to branch on. Kept as a const object\n * rather than an enum so it serializes cleanly across the wire and in logs.\n */\nexport const GATEWAY_ERROR_CODE = {\n /** Upstream OAuth token is revoked — the user must re-auth at the SaaS provider. */\n REAUTH_REQUIRED: 'REAUTH_REQUIRED',\n /** Local VC/VP is invalid (expired, malformed, signature mismatch). Try VC reissuance. */\n CREDENTIAL_INVALID: 'CREDENTIAL_INVALID',\n /** VC allowed a different resource than the request targeted. Try a new approval. */\n RESOURCE_MISMATCH: 'RESOURCE_MISMATCH',\n /**\n * Cedar `forbid` rule fired (HTTP 403 `policy_forbidden`) — a HARD deny that\n * approval CANNOT lift (e.g. a timeWindow forbid outside business hours).\n * The ExecutionEngine surfaces this as a TERMINAL denial with NO approval\n * prompt, unlike CREDENTIAL_INVALID / RESOURCE_MISMATCH which re-request.\n */\n POLICY_FORBIDDEN: 'POLICY_FORBIDDEN',\n /**\n * Cedar `RequireApproval` fired at invoke time (HTTP 202 `auth_required`) —\n * the VC was already issued, but the per-request evaluation (e.g. a new\n * recipient that fails the internal-domain fold) still needs approval. Unlike\n * POLICY_FORBIDDEN this IS lift-able: the ExecutionEngine mints an OOB\n * approval URL (`waitingForApproval`) so the user can approve and retry.\n */\n APPROVAL_REQUIRED: 'APPROVAL_REQUIRED',\n} as const\n\nexport type GatewayErrorCode =\n (typeof GATEWAY_ERROR_CODE)[keyof typeof GATEWAY_ERROR_CODE]\n","export interface ActionParamDisplay {\n label: string\n value: string\n}\n\n/**\n * displayFields 1 項目の表示元。\n *\n * - `key` — params[key] を読む単純なケース (string / number など)\n * - `extract` — alias / nested / null など複合 shape を吸収する場合 (jira.* など)\n *\n * extract を指定したケースは key を併用してもよい (fallback として使われる)。\n * 戻り値が undefined / null (Unassign 表現の null は除く) のときは表示しない。\n */\ninterface ActionDisplayField {\n label: string\n key?: string\n extract?: (params: Record<string, any>) => unknown\n}\n\ninterface ActionDisplayConfig {\n summaryTemplate: (params: Record<string, any>) => string\n displayFields: ActionDisplayField[]\n}\n\n/**\n * jira 用: agent が送る 4 つの assignee shape から表示値を抽出する。\n * null は「未アサイン (Unassign)」として明示表示するため特別な戻り値で示す。\n */\nfunction extractJiraAssigneeDisplay(params: Record<string, any>): string | null | undefined {\n const pickFromShape = (value: unknown): string | null | undefined => {\n if (value === null) return null\n if (typeof value === 'string') return value.length > 0 ? value : undefined\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const id = (value as Record<string, unknown>).accountId\n if (id === null) return null\n if (typeof id === 'string' && id.length > 0) return id\n }\n return undefined\n }\n // priority: canonical > top-level alias > nested fields\n if ('assigneeAccountId' in params) {\n const v = params.assigneeAccountId\n if (v === null) return null\n if (typeof v === 'string' && v.length > 0) return v\n }\n if ('assignee' in params) {\n const picked = pickFromShape(params.assignee)\n if (picked !== undefined) return picked\n }\n const fields = params.fields as Record<string, unknown> | undefined\n if (fields && typeof fields === 'object' && 'assignee' in fields) {\n const picked = pickFromShape(fields.assignee)\n if (picked !== undefined) return picked\n }\n return undefined\n}\n\n/**\n * jira 用: nested `fields.X` 形式と top-level canonical の両方をカバーする\n * 汎用 extractor。\n */\nfunction jiraField<T = unknown>(\n params: Record<string, any>,\n topLevelKeys: string[],\n nestedKey: string,\n nestedExtractor?: (v: any) => T,\n): T | undefined {\n for (const k of topLevelKeys) {\n if (params[k] !== undefined && params[k] !== null) return params[k] as T\n }\n const fields = params.fields as Record<string, unknown> | undefined\n if (fields && typeof fields === 'object') {\n const v = fields[nestedKey]\n if (v !== undefined && v !== null) {\n return nestedExtractor ? nestedExtractor(v) : (v as T)\n }\n }\n return undefined\n}\n\nconst ACTION_DISPLAY_CONFIGS: Record<string, ActionDisplayConfig> = {\n 'slack.message.post': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.channel) parts.push(p.channel + ':')\n if (p.text) parts.push(String(p.text))\n return parts.join(' ')\n },\n displayFields: [\n { key: 'channel', label: 'Channel' },\n { key: 'text', label: 'Message' },\n ],\n },\n 'gmail.message.send': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.to) parts.push(`To: ${p.to}`)\n if (p.subject) parts.push(`Subject: ${p.subject}`)\n return parts.join(', ')\n },\n displayFields: [\n { key: 'to', label: 'To' },\n { key: 'subject', label: 'Subject' },\n { key: 'body', label: 'Body' },\n ],\n },\n 'gmail.draft.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.to) parts.push(`To: ${p.to}`)\n if (p.subject) parts.push(`Subject: ${p.subject}`)\n return parts.join(', ')\n },\n displayFields: [\n { key: 'to', label: 'To' },\n { key: 'subject', label: 'Subject' },\n { key: 'body', label: 'Body' },\n ],\n },\n 'calendar.event.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.summary) parts.push(p.summary)\n if (p.start) parts.push(`(${formatValue(p.start)})`)\n return parts.join(' ')\n },\n displayFields: [\n { key: 'summary', label: 'Event' },\n { key: 'start', label: 'Start' },\n { key: 'end', label: 'End' },\n { key: 'attendees', label: 'Attendees' },\n ],\n },\n 'calendar.event.update': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.summary) parts.push(p.summary)\n if (p.start) parts.push(`(${formatValue(p.start)})`)\n return parts.join(' ')\n },\n displayFields: [\n { key: 'summary', label: 'Event' },\n { key: 'start', label: 'Start' },\n { key: 'end', label: 'End' },\n { key: 'attendees', label: 'Attendees' },\n ],\n },\n 'jira.issue.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n const projectKey = jiraField<string>(p, ['projectKey', 'project'], 'project', (v: any) =>\n typeof v === 'string' ? v : v?.key,\n )\n const summary = jiraField<string>(p, ['summary'], 'summary')\n if (projectKey) parts.push(`${projectKey}:`)\n if (summary) parts.push(summary)\n return parts.join(' ')\n },\n // AIDENTITY-54: nested `fields.X` 形式と top-level canonical の両方を\n // 拾えるよう extract を使う。assignee は null (unassign) も表示。\n // legacy alias (project / issuetype 等) も top-level 候補に含めて後方互換を保つ。\n displayFields: [\n {\n label: 'Project',\n extract: (p) =>\n jiraField<string>(p, ['projectKey', 'project'], 'project', (v: any) =>\n typeof v === 'string' ? v : v?.key,\n ),\n },\n {\n label: 'Type',\n extract: (p) =>\n jiraField<string>(p, ['issueTypeName', 'issueType', 'issuetype'], 'issuetype', (v: any) =>\n typeof v === 'string' ? v : v?.name,\n ),\n },\n { label: 'Summary', extract: (p) => jiraField<string>(p, ['summary'], 'summary') },\n { label: 'Description', extract: (p) => jiraField(p, ['description'], 'description') },\n { label: 'Priority', extract: (p) =>\n jiraField<string>(p, ['priority'], 'priority', (v: any) =>\n typeof v === 'string' ? v : v?.name,\n ),\n },\n { label: 'Assignee', extract: extractJiraAssigneeDisplay },\n { label: 'Labels', extract: (p) => jiraField(p, ['labels'], 'labels') },\n ],\n },\n 'jira.issue.update': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n const key = (p.issueIdOrKey ?? p.issueKey) as string | undefined\n const summary = jiraField<string>(p, ['summary'], 'summary')\n if (key) parts.push(`${key}:`)\n if (summary) parts.push(summary)\n return parts.join(' ')\n },\n displayFields: [\n // canonical は issueIdOrKey、agent が issueKey で送ってくる旧仕様も拾う。\n { label: 'Issue', extract: (p) => (p.issueIdOrKey ?? p.issueKey) },\n { label: 'Summary', extract: (p) => jiraField<string>(p, ['summary'], 'summary') },\n { label: 'Description', extract: (p) => jiraField(p, ['description'], 'description') },\n { label: 'Priority', extract: (p) =>\n jiraField<string>(p, ['priority'], 'priority', (v: any) =>\n typeof v === 'string' ? v : v?.name,\n ),\n },\n // AIDENTITY-54: top-level alias (string / object) と null (unassign) も解決。\n { label: 'Assignee', extract: extractJiraAssigneeDisplay },\n { label: 'Labels', extract: (p) => jiraField(p, ['labels'], 'labels') },\n ],\n },\n // AIDENTITY-65: comment 本体は string と ADF document の両方を受けるため、\n // formatValue 側の ADF ハンドリング (extractFirstAdfText) に任せて key 指定で OK。\n 'jira.comment.create': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.issueIdOrKey) parts.push(`${p.issueIdOrKey}:`)\n if (p.body) parts.push(typeof p.body === 'string' ? p.body : '[ADF]')\n return parts.join(' ')\n },\n displayFields: [\n { key: 'issueIdOrKey', label: 'Issue' },\n { key: 'body', label: 'Comment' },\n ],\n },\n // AIDENTITY-65: API enricher が 'Link' label を upsert で書き換える。\n 'jira.issuelink.delete': {\n summaryTemplate: (p) => {\n const parts: string[] = []\n if (p.linkId) parts.push(`Delete link ${p.linkId}`)\n return parts.join(' ')\n },\n displayFields: [\n { key: 'linkId', label: 'Link' },\n ],\n },\n}\n\nfunction truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text\n return text.slice(0, maxLength - 3) + '...'\n}\n\nfunction formatValue(value: unknown): string {\n if (value === undefined) return ''\n // AIDENTITY-54: null は「unset / 未設定 / 削除」意図として、空文字ではなく\n // 明示的なラベルで表示する (assignee=null は unassign、その他 field も同様)。\n // display config 側で意味付けを変えたい場合は extract で string 化することも可能。\n if (value === null) return '(unset)'\n if (Array.isArray(value)) {\n return value.map(item => {\n if (item && typeof item === 'object') {\n // e.g. attendees: [{email: \"a@b.com\"}, {email: \"c@d.com\"}] → \"a@b.com, c@d.com\"\n const email = (item as Record<string, unknown>).email\n if (email) return String(email)\n return JSON.stringify(item)\n }\n return String(item)\n }).join(', ')\n }\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>\n // Google Calendar datetime object: {dateTime: \"...\", timeZone: \"...\"} → \"2025-01-15T10:00:00 (Asia/Tokyo)\"\n if (obj.dateTime) {\n return obj.timeZone ? `${obj.dateTime} (${obj.timeZone})` : String(obj.dateTime)\n }\n // Google Calendar date object: {date: \"2025-01-15\"} → \"2025-01-15\"\n if (obj.date) return String(obj.date)\n // ADF document (Atlassian Jira description / comment): 最初の paragraph の\n // テキストを軽く抽出して読みやすく表示する。完全な ADF 描画は approve UI 側に\n // 任せる発想もあるが、現状の plain textContent では JSON.stringify で読みにくい。\n if (obj.type === 'doc' && Array.isArray(obj.content)) {\n const firstText = extractFirstAdfText(obj.content as unknown[])\n if (firstText) {\n const moreCount = obj.content.length - 1\n const more = moreCount > 0 ? ` … (+${moreCount} block${moreCount > 1 ? 's' : ''})` : ''\n return `${firstText}${more}`\n }\n return '(ADF document)'\n }\n return JSON.stringify(value)\n }\n return String(value)\n}\n\n/** ADF document の最初の paragraph / heading から先頭テキストを抜き出す。 */\nfunction extractFirstAdfText(nodes: unknown[]): string {\n for (const node of nodes) {\n if (!node || typeof node !== 'object') continue\n const n = node as Record<string, unknown>\n if (n.type === 'paragraph' || n.type === 'heading') {\n const inner = (n.content as unknown[]) ?? []\n for (const child of inner) {\n if (child && typeof child === 'object') {\n const c = child as Record<string, unknown>\n if (c.type === 'text' && typeof c.text === 'string') return c.text\n }\n }\n }\n }\n return ''\n}\n\nexport const ACTION_PARAMS_MAX_SIZE = 10_000\n\nexport function generateActionSummary(\n action: string,\n params: Record<string, any> | undefined | null,\n maxLength = 50,\n): string {\n if (!params || Object.keys(params).length === 0) return ''\n\n const config = ACTION_DISPLAY_CONFIGS[action]\n if (config) {\n const raw = config.summaryTemplate(params)\n return raw ? truncate(raw, maxLength) : ''\n }\n\n for (const [key, val] of Object.entries(params)) {\n if (val !== null && val !== undefined && typeof val !== 'object') {\n return truncate(`${key}: ${String(val)}`, maxLength)\n }\n }\n return ''\n}\n\nexport function generateActionParamsDisplay(\n action: string,\n params: Record<string, any> | undefined | null,\n): ActionParamDisplay[] {\n if (!params || Object.keys(params).length === 0) return []\n\n const config = ACTION_DISPLAY_CONFIGS[action]\n if (config) {\n return config.displayFields\n .map(f => {\n // extract が優先。なければ key 経由 (旧仕様)。\n const raw = f.extract ? f.extract(params) : f.key ? params[f.key] : undefined\n return { label: f.label, raw }\n })\n // 値が undefined のフィールドは表示しない。null は許可 (formatValue で\n // \"(unset)\" として表示される — 「明示的に消した」意味を残す)。\n .filter(item => item.raw !== undefined)\n .map(item => ({ label: item.label, value: formatValue(item.raw) }))\n }\n\n return Object.entries(params)\n .filter(([, v]) => v !== undefined && v !== null)\n .slice(0, 3)\n .map(([key, val]) => ({\n label: key,\n value: formatValue(val),\n }))\n}\n","import {\n TargetBindings,\n ResolvedTargets,\n PolicyTarget,\n BindingSource,\n ParamBindingSource,\n} from '../types/target-binding'\n\n/**\n * Regex to extract project key prefix from a Jira issue key (e.g., \"PROJ-123\" → \"PROJ\").\n * Requires 2+ uppercase characters — single-letter keys like \"A-1\" are rejected\n * (Jira project keys must be at least 2 characters).\n */\nconst PROJECT_KEY_PATTERN = /^([A-Z][A-Z0-9_]+)-\\d+$/\n\n/**\n * Extract the project key from a Jira issue key.\n * Returns the project prefix (e.g., \"AIDENTITY\" from \"AIDENTITY-35\") or null if not a valid issue key.\n *\n * @remarks Project keys must be at least 2 uppercase characters, matching Jira's requirement.\n * Single-letter keys (e.g., \"A-1\") return null.\n */\nexport function extractProjectKey(value: string): string | null {\n const match = value.match(PROJECT_KEY_PATTERN)\n return match ? match[1] : null\n}\n\n/**\n * TargetResolver — extracts resource IDs and secondary targets from tool parameters.\n *\n * Pure function with no external dependencies (NestJS, DB, etc.).\n * Used by the API layer to populate PolicyInput.request.resource.id and targets[].\n */\nexport class TargetResolver {\n /**\n * Resolve target bindings against tool invocation parameters.\n *\n * @param bindings - Target binding declarations from ACTION_REGISTRY\n * @param params - Tool invocation parameters\n * @param context - Optional pre-resolved context values (e.g., resource_id from URL)\n */\n resolve(\n bindings: TargetBindings,\n params: Record<string, unknown>,\n context?: Record<string, string>,\n ): ResolvedTargets {\n const isRequired = bindings.resource_id.required !== false\n\n // Resolve primary resource_id\n const { value, values } = this.resolveBinding(bindings.resource_id, params, context)\n\n // Resolve secondary targets (alpha: collect values but not evaluated by policy)\n const targets = this.resolveSecondary(bindings.secondary, params, context)\n\n return {\n resource_id: value,\n resource_id_required: isRequired,\n resource_id_values: values,\n targets,\n }\n }\n\n private resolveBinding(\n binding: BindingSource,\n params: Record<string, unknown>,\n context?: Record<string, string>,\n ): { value: string | null; values?: string[] } {\n if (binding.source === 'context') {\n const val = context?.[binding.key]\n if (typeof val !== 'string') return { value: null }\n return { value: val }\n }\n\n // source === 'param'\n const paramBinding = binding as ParamBindingSource\n let rawValue = params[paramBinding.param]\n\n // Fallback to alternative param name if primary is missing\n if (rawValue == null && paramBinding.fallback_param) {\n rawValue = params[paramBinding.fallback_param]\n }\n\n // Apply default if missing\n if (rawValue == null && paramBinding.default != null) {\n rawValue = paramBinding.default\n }\n\n // Type validation: must be string\n if (rawValue == null) return { value: null }\n if (typeof rawValue !== 'string') return { value: null }\n\n // Apply derive transformation\n let strValue: string = rawValue\n if (paramBinding.derive === 'project_key') {\n strValue = extractProjectKey(strValue) ?? strValue\n }\n\n // Multi-value handling\n if (paramBinding.multi) {\n const separator = paramBinding.separator ?? ','\n const values = strValue.split(separator).map((v: string) => v.trim()).filter((v: string) => v.length > 0)\n return {\n value: values[0] ?? null,\n values,\n }\n }\n\n return { value: strValue }\n }\n\n private resolveSecondary(\n secondary: TargetBindings['secondary'],\n params: Record<string, unknown>,\n context?: Record<string, string>,\n ): PolicyTarget[] {\n if (!secondary || secondary.length === 0) return []\n\n const targets: PolicyTarget[] = []\n for (const binding of secondary) {\n const { value, values } = this.resolveBinding(binding.source, params, context)\n if (value == null) continue\n\n targets.push({\n name: binding.name,\n values: values ?? [value],\n })\n }\n return targets\n }\n}\n","import { ACTION_REGISTRY } from '../registry/action-registry-json'\nimport { indexActions } from '../registry/action-registry'\n\nconst actionIndex = indexActions({\n registry_version: ACTION_REGISTRY.registry_version,\n actions: ACTION_REGISTRY.actions as any,\n})\n\n/**\n * Determine if an action is a write action based on ACTION_REGISTRY effects and risk.\n * Uses effects (Create/Update/Delete/Write/Execute) as primary signal,\n * falls back to risk level (medium/high = write) for unknown actions.\n */\nexport function isWriteAction(action: string): boolean {\n const meta = actionIndex.get(action)\n if (!meta) {\n // Unknown action: treat as write (safe default)\n return true\n }\n\n // Check effects for write semantics\n const writeEffectPrefixes = ['Create:', 'Update:', 'Delete:', 'Write:', 'Execute:']\n if (meta.effects?.some((e: string) => writeEffectPrefixes.some(p => e.startsWith(p)))) {\n return true\n }\n\n // Fallback: medium/high/critical risk = write\n return meta.risk === 'medium' || meta.risk === 'high' || meta.risk === 'critical'\n}\n\n/**\n * Pre-computed list of all write action names from ACTION_REGISTRY.\n * Used for SQL queries where per-row function calls are not practical.\n * Must be re-generated if ACTION_REGISTRY changes (compile-time constant).\n */\nexport const WRITE_ACTION_NAMES: string[] = ACTION_REGISTRY.actions\n .filter((a: any) => isWriteAction(a.action))\n .map((a: any) => a.action)\n","import { UserTier, TierLimits, TIER_LIMITS } from '../types/tier'\n\n/**\n * Check if a tier limit value represents unlimited.\n * In TIER_LIMITS, -1 is used to represent unlimited values.\n */\nexport function isUnlimited(value: number): boolean {\n return value < 0\n}\n\n/**\n * Safely resolve a tier string to a valid UserTier, defaulting to 'free'.\n */\nexport function resolveUserTier(tier: string | undefined | null): UserTier {\n if (tier && tier in TIER_LIMITS) {\n return tier as UserTier\n }\n return 'free'\n}\n\n/**\n * Get tier limits for a user's tier, with safe fallback to free tier.\n */\nexport function getTierLimits(tier: string | undefined | null): TierLimits {\n return TIER_LIMITS[resolveUserTier(tier)]\n}\n","/**\n * フリーメール / コンシューマ向けメールドメインのリスト。\n * grant の internalDomains で「ドメイン全体ワイルドカード (*@<freemail>)」を\n * 許可することを禁止するために使う (個別アドレス x@gmail.com は許可)。\n * 理由: *@gmail.com を「社内ドメイン」として自動許可すると、全 Gmail ユーザー\n * 宛が無条件許可になり危険。\n *\n * 網羅性は完璧でなくてよい (主要なもの)。後から追加可能な Set 構造。\n */\nexport const FREEMAIL_DOMAINS: ReadonlySet<string> = new Set([\n 'gmail.com',\n 'googlemail.com',\n 'outlook.com',\n 'hotmail.com',\n 'live.com',\n 'yahoo.com',\n 'yahoo.co.jp',\n 'ymail.com',\n 'icloud.com',\n 'me.com',\n 'mac.com',\n 'aol.com',\n 'protonmail.com',\n 'proton.me',\n 'pm.me',\n 'gmx.com',\n 'gmx.net',\n 'mail.com',\n 'zoho.com',\n 'yandex.com',\n // 日本の主要キャリア/フリーメール\n 'docomo.ne.jp',\n 'ezweb.ne.jp',\n 'au.com',\n 'softbank.ne.jp',\n 'i.softbank.jp',\n 'nifty.com',\n 'so-net.ne.jp',\n 'biglobe.ne.jp',\n])\n\n/** ドメインがフリーメールか判定 (小文字化して比較)。 */\nexport function isFreemailDomain(domain: string): boolean {\n return FREEMAIL_DOMAINS.has(domain.trim().toLowerCase())\n}\n","import { createHash } from 'crypto'\n\n/**\n * P1-A14a-1 / Threat Model S4 — canonical-string + signature-header\n * helpers for HMAC body signing of internal HTTP requests.\n *\n * Pure module: no NestJS, no I/O, no side effects. SDK is the\n * single source of truth (P1-A14a-2d) — api / remote-mcp /\n * slack-bot all import from `@vess-id/ai-identity`.\n *\n * Header format (Q1 = A, Stripe-style versioned):\n * X-Internal-Signature: v1=<keyId>:<unixSeconds>:<base64(hmac)>\n *\n * Canonical string (Q2 = A, no header inclusion):\n * ${METHOD.toUpperCase()}\\n${path}\\n${unixSeconds}\\n${sha256Hex(rawBody)}\n *\n * Replay window (Q3 = A): 300 seconds — enforced by the api guard,\n * not here. This module is responsible for *constructing* the\n * canonical string and *parsing* the header; freshness is policy.\n */\n\nexport const SIGNATURE_HEADER = 'x-internal-signature'\nexport const SIGNATURE_VERSION_PREFIX = 'v1='\n\n/**\n * SHA-256 hex digest of an arbitrary buffer or string. Hex (not\n * base64) so the canonical string is URL-safe and grep-friendly in\n * logs if a future debug session ever needs to reconstruct it\n * server-side.\n */\nexport function sha256Hex(input: Buffer | string): string {\n return createHash('sha256').update(input).digest('hex')\n}\n\n/**\n * Build the canonical string that gets HMAC'd. The components are\n * separated by `\\n` because no legitimate input contains `\\n` (the\n * method is uppercase ASCII, the path is URL-encoded by the caller,\n * the timestamp is digits, the body hash is hex). Using `\\n` as\n * separator avoids ambiguity that delimiters like `:` would\n * introduce when the path contains a colon.\n *\n * Whitespace is NOT trimmed — input must be exactly what will land\n * on the wire. Caller controls case and encoding.\n */\nexport function buildCanonicalString(args: {\n method: string\n path: string\n unixSeconds: number\n rawBody: Buffer | string\n}): string {\n const { method, path, unixSeconds, rawBody } = args\n return [method.toUpperCase(), path, String(unixSeconds), sha256Hex(rawBody)].join('\\n')\n}\n\n/** Shape of a parsed `X-Internal-Signature` header. */\nexport interface ParsedSignature {\n /** Identifier of the signing key (e.g. `'mcp-v2'`). */\n keyId: string\n /** Unix epoch seconds at signing time. */\n unixSeconds: number\n /** Base64-encoded HMAC-SHA256 digest. */\n signature: string\n}\n\n/**\n * Parse a `X-Internal-Signature` header value. Returns `null` for\n * any malformed shape rather than throwing — the api guard converts\n * `null` to a `401 Unauthorized` so a malformed header never\n * triggers a `500`.\n *\n * Accepted: `v1=<keyId>:<digits>:<base64>`\n *\n * Defensive checks:\n * - Must start with `v1=` (Q1: explicit version prefix)\n * - keyId / signature must be non-empty after split\n * - timestamp must parse to a finite, non-negative integer\n * - keyId must be ASCII identifier-safe ([A-Za-z0-9_-]+) so a\n * malicious header cannot smuggle control chars or whitespace\n * into log lines / metric labels\n * - signature must be valid base64 (only base64 alphabet chars)\n */\nexport function parseSignatureHeader(headerValue: string | undefined): ParsedSignature | null {\n if (typeof headerValue !== 'string' || !headerValue.startsWith(SIGNATURE_VERSION_PREFIX)) {\n return null\n }\n const payload = headerValue.slice(SIGNATURE_VERSION_PREFIX.length)\n const parts = payload.split(':')\n if (parts.length !== 3) return null\n\n const [keyId, tsStr, signature] = parts\n if (!keyId || !tsStr || !signature) return null\n\n // Identifier-safe check on keyId. Mirrors the convention used for\n // OAuth provider IDs — keep this tight; a future PR adding `.` or\n // `:` to the alphabet should be a deliberate decision.\n if (!/^[A-Za-z0-9_-]+$/.test(keyId)) return null\n\n // Timestamp: digits only (forbid '+', '-', '.', exponent, etc.).\n if (!/^\\d+$/.test(tsStr)) return null\n const unixSeconds = Number(tsStr)\n if (!Number.isFinite(unixSeconds) || unixSeconds < 0) return null\n\n // Base64 alphabet check — `Buffer.from(s, 'base64')` is permissive\n // (it silently drops invalid chars) which would let a malformed\n // signature compare-equal to a legitimate one after re-encoding.\n // Reject up front.\n if (!/^[A-Za-z0-9+/]+=*$/.test(signature)) return null\n\n return { keyId, unixSeconds, signature }\n}\n\n/**\n * Format a ParsedSignature back into a header string. Round-trips\n * with `parseSignatureHeader` for any validly-shaped input.\n *\n * Used by the signing side (HTTP client). Keeping it next to the\n * parser pins the format in one place.\n */\nexport function formatSignatureHeader(parsed: ParsedSignature): string {\n return `${SIGNATURE_VERSION_PREFIX}${parsed.keyId}:${parsed.unixSeconds}:${parsed.signature}`\n}\n","import { createHmac } from 'crypto'\nimport {\n buildCanonicalString,\n formatSignatureHeader,\n type ParsedSignature,\n} from './canonical'\n\n/**\n * P1-A14a-2d — pure HMAC signer for outbound /api/internal/**\n * requests. Lives in SDK so remote-mcp and slack-bot (both of which\n * already depend on `@vess-id/ai-identity`) can attach\n * `X-Internal-Signature` to every request without dragging the\n * api package into their dependency graph.\n *\n * Pure (no I/O, no Nest). Mirrors the `utils/crypto.ts` profile:\n * the only Node-builtin used is `crypto.createHmac`.\n *\n * Pairing with the verifier\n * -------------------------\n * The verifier (api side, `HmacKeyset.verify` →\n * `buildCanonicalString` → constant-time compare) reads the same\n * `buildCanonicalString` from this module by construction. As long\n * as both sides pass the same `(method, path, unixSeconds, rawBody)`\n * the HMACs match by definition.\n *\n * Body bytes\n * ----------\n * The caller MUST pass the exact bytes that go on the wire as\n * `rawBody`. Re-running `JSON.stringify(...)` on each side would\n * risk a byte mismatch (object key order is implementation-defined\n * in spec, even though V8 preserves insertion order in practice).\n * The api-client `makeRequest` helper computes `JSON.stringify`\n * once, hands the same string to both `signRequest` and `fetch`.\n */\n\n/**\n * Minimum signer key length in raw bytes. 32 bytes = 256 bits\n * matches HMAC-SHA256's natural block size and the verifier's\n * `MIN_KEY_BYTES`. A truncated env var (accidental newline,\n * copy-paste error) is the realistic failure mode this guards\n * against.\n */\nexport const MIN_SIGNER_KEY_BYTES = 32\n\nexport interface InternalHmacSignerKey {\n /** Stable identifier for the key, e.g. `'mcp-v1'`. Embedded in\n * the X-Internal-Signature header so the verifier can pick the\n * right key. Must match `/^[A-Za-z0-9_-]+$/`. */\n keyId: string\n /** Raw HMAC secret. >= MIN_SIGNER_KEY_BYTES bytes. */\n secret: Buffer\n}\n\nexport interface SignRequestArgs {\n /** HTTP method. Will be upper-cased by `buildCanonicalString`,\n * but callers should pass the uppercase form they use on the\n * wire so signer and `fetch()` stay in lockstep. */\n method: string\n /** URL path with query string already stripped (verifier does\n * `request.originalUrl?.split('?')[0]`; signer must mirror).\n * Path encoding (e.g. `%2F` vs `/`) is caller's responsibility\n * — the canonical string treats them as different bytes. */\n path: string\n /** Wire bytes. The same string/buffer passed to `fetch({body})`\n * must be passed here — `JSON.stringify` runs ONCE per request\n * in the caller. */\n rawBody: Buffer | string\n /** Optional fixed timestamp for testing. Defaults to\n * `Math.floor(Date.now() / 1000)`. */\n unixSeconds?: number\n}\n\n/**\n * Sign an outbound request and return a fully-formatted\n * `X-Internal-Signature` header value. The caller sets the header\n * on the outbound request directly:\n *\n * ```ts\n * headers[SIGNATURE_HEADER] = signRequest(key, { method, path, rawBody })\n * ```\n *\n * Throws if key material is invalid (bad keyId or short secret) —\n * surfacing misconfiguration loudly at request time rather than\n * silently producing a header the verifier will reject.\n */\nexport function signRequest(key: InternalHmacSignerKey, args: SignRequestArgs): string {\n assertKeyMaterial(key)\n const unixSeconds = args.unixSeconds ?? Math.floor(Date.now() / 1000)\n const canonical = buildCanonicalString({\n method: args.method,\n path: args.path,\n unixSeconds,\n rawBody: args.rawBody,\n })\n const signature = createHmac('sha256', key.secret).update(canonical).digest('base64')\n const parsed: ParsedSignature = {\n keyId: key.keyId,\n unixSeconds,\n signature,\n }\n return formatSignatureHeader(parsed)\n}\n\nfunction assertKeyMaterial(k: InternalHmacSignerKey): void {\n if (!k.keyId || !/^[A-Za-z0-9_-]+$/.test(k.keyId)) {\n throw new Error(\n `internal-signature signer: invalid keyId ${JSON.stringify(k.keyId)} (must match /^[A-Za-z0-9_-]+$/)`,\n )\n }\n if (!Buffer.isBuffer(k.secret) || k.secret.length < MIN_SIGNER_KEY_BYTES) {\n throw new Error(\n `internal-signature signer: secret too short for keyId=${k.keyId} ` +\n `(${Buffer.isBuffer(k.secret) ? k.secret.length : 'not a Buffer'} bytes; ` +\n `minimum ${MIN_SIGNER_KEY_BYTES} required)`,\n )\n }\n}\n","/**\n * CedarEngine — minimal wrapper around `@cedar-policy/cedar-wasm/nodejs`.\n *\n * Phase 1 Step 1 scope (server-side / Node-runtime only):\n * - preparseSchema : ingest Cedar schema text → opaque SchemaHandle\n * - preparsePolicySet: ingest Cedar PolicySet text → opaque PolicySetHandle\n * - evaluate : run statefulIsAuthorized against preparsed handles\n *\n * Browser callers receive `CedarEngineUnavailableError` because the\n * `/nodejs` subpath depends on Node `fs` to instantiate the wasm.\n *\n * Performance notes (companion design spec Appendix C, PoC 2026-05-23):\n * - statefulIsAuthorized + preparsed cache: p50 0.067ms / p99 0.076ms\n * (~9x faster than re-parsing every call). The wasm caches preparsed\n * handles internally keyed by string name/id, so the opaque handles\n * we expose are thin wrappers around an auto-generated id.\n *\n * Concurrency / TOCTOU (Cedar design spec rev 5/6, fix C3):\n * - `createCedarEngine()` caches the in-flight Promise (not the resolved\n * engine). Two parallel callers therefore share the same load — no\n * duplicated dynamic import of the 4.1 MB wasm.\n * - On load failure the cached promise is cleared so the next caller can\n * retry. This avoids permanently poisoning the module after a transient\n * failure (e.g. wasm streaming compile blip).\n *\n * Design ref: docs/specs/2026-05-23-cedar-rar-permission-redesign.md\n * Plan ref: docs/specs/2026-05-23-cedar-rar-implementation-plan-phase1.md\n */\n\n// --- Public types -----------------------------------------------------------\n\n/**\n * Decision domain exposed by the wrapper. Cedar's wasm uses lowercase\n * `'allow' | 'deny'`; we normalize to the spec's casing so callers can\n * pattern-match on a single canonical form across the codebase.\n */\nexport type CedarDecision = 'Allow' | 'Deny'\n\n/**\n * Structured error returned for evaluation-time problems (policy execution\n * errors). Parse / schema errors are surfaced at preparse time as thrown\n * `CedarParseError`s instead.\n */\nexport interface CedarError {\n /** Policy id that errored, if attributable. */\n policyId?: string\n /** Human-readable message from Cedar. */\n message: string\n /** Optional structured diagnostic code from Cedar. */\n code?: string\n}\n\n/**\n * Phase 2-1-H — structured policy validation error surfaced by\n * `CedarParseError.validationErrors` (and re-exported as a public type\n * so API / UI callers don't have to re-implement source-location math).\n *\n * One `PolicyValidationError` entry corresponds to one cedar-wasm\n * diagnostic (top-level `errors[]` entries + their `related[]`\n * descendants are flattened into a single list, since callers always\n * want to render every diagnostic — the related chain is metadata about\n * the top-level failure, not a separate parse).\n *\n * Fields:\n * - `code` — machine-readable classification, snake_case. Phase 1\n * surface: `'parse_error'` (default). Future cedar-wasm releases\n * ship structured codes; the classifier here uses message-pattern\n * heuristics until then (see `classifyCedarErrorMessage`).\n * - `message` — cedar-wasm's human-readable English. UI is\n * responsible for i18n / templating; we don't translate here.\n * - `line` / `column` — 1-based caret. Computed from the byte\n * `start` offset in cedar-wasm's `sourceLocations[]` against the\n * ORIGINAL policy text, so the caret matches what the user sees\n * in the textarea / editor.\n * - `context` — the offending byte slice (max 200 chars, truncated\n * with an ellipsis). Lets UIs render an inline highlight without\n * a second round trip.\n * - `offset` — 0-based byte offset (for editors that prefer offsets\n * to line/column; line/column is provided as a convenience).\n */\nexport interface PolicyValidationError {\n /**\n * Machine-readable code, snake_case. Currently a small set:\n * - `'parse_error'` — syntax / grammar failure (default)\n * - `'unexpected_end_of_input'` — incomplete policy\n * - `'unexpected_token'` — token didn't match expected production\n * - `'unknown_extension'` — referenced an unknown extension fn\n * - `'unknown'` — fallback when no heuristic matches\n * Callers that switch on this string MUST default to a generic\n * branch — the set will grow as cedar-wasm exposes structured codes.\n */\n code: string\n /** Cedar's human-readable English diagnostic. */\n message: string\n /** 1-based line in the original policy text where the error starts. */\n line?: number\n /** 1-based column in the line (counts UTF-16 code units, matching JS String). */\n column?: number\n /**\n * The raw policy slice that triggered the error, truncated to 200\n * chars with a trailing ellipsis when longer. Useful for UIs to\n * highlight the offending span without re-computing offsets.\n */\n context?: string\n /** 0-based byte offset into the policy text (when known). */\n offset?: number\n}\n\n/**\n * Opaque handle to a Cedar schema that has been parsed and cached\n * inside the wasm. Returned by `preparseSchema`; pass to `evaluate`.\n *\n * The wasm caches by string name, so the handle carries the auto-generated\n * id. Callers must treat the type as opaque.\n */\nexport interface SchemaHandle {\n readonly __cedar: 'schema'\n readonly name: string\n}\n\n/** Opaque handle to a Cedar PolicySet. Returned by `preparsePolicySet`. */\nexport interface PolicySetHandle {\n readonly __cedar: 'policySet'\n readonly id: string\n}\n\n/**\n * A Cedar entity in the JSON shape expected by the wasm.\n *\n * We keep this as `Record<string, unknown>` rather than importing the\n * detailed `EntityJson` type from `@cedar-policy/cedar-wasm` because the\n * SDK is consumed by browser bundlers; pulling in the d.ts would force\n * the wasm typings into browser builds (the runtime is still lazy-loaded).\n * Callers cast as needed; runtime validation is delegated to the wasm.\n */\nexport type CedarEntity = Record<string, unknown>\n\nexport interface CedarEvaluateRequest {\n /** Cedar entity-uid expression, e.g. `Agent::\"agent-1\"`. */\n principal: string\n /** Cedar entity-uid expression, e.g. `Action::\"gmail.message.send\"`. */\n action: string\n /** Cedar entity-uid expression, e.g. `GmailThread::\"thread-1\"`. */\n resource: string\n /** Free-form context dict (must match the schema's context shape). */\n context: Record<string, unknown>\n}\n\nexport interface EvaluateInput {\n policySetHandle: PolicySetHandle\n schemaHandle?: SchemaHandle\n entities: ReadonlyArray<CedarEntity>\n request: CedarEvaluateRequest\n}\n\nexport interface EvaluateResult {\n decision: CedarDecision\n /** Policy ids that determined the decision (Cedar's `diagnostics.reason`). */\n reasons: string[]\n /** Evaluation-time errors, if any. Empty array on success. */\n errors: CedarError[]\n}\n\nexport interface CedarEngine {\n preparseSchema(schemaText: string): SchemaHandle\n preparsePolicySet(cedarText: string): PolicySetHandle\n evaluate(input: EvaluateInput): EvaluateResult\n}\n\n// --- Errors -----------------------------------------------------------------\n\n/**\n * Thrown when the Cedar wasm module cannot be loaded — typically because\n * the wrapper is running in a browser (the `/nodejs` subpath requires Node\n * `fs`), but also raised for any unexpected load-time failure.\n */\nexport class CedarEngineUnavailableError extends Error {\n override readonly name = 'CedarEngineUnavailableError'\n\n constructor(cause: unknown) {\n // The `cause` option is ES2022 standard; the base Error constructor\n // assigns it to `this.cause` so we don't need a separate field.\n super(\n 'Cedar wasm engine could not be loaded. ' +\n 'This typically happens in non-Node environments (browser) or when ' +\n 'the @cedar-policy/cedar-wasm/nodejs module fails to instantiate.',\n { cause },\n )\n }\n}\n\n/**\n * Thrown by `preparseSchema` / `preparsePolicySet` when Cedar reports a\n * structured `{ type: 'failure', errors: [...] }` answer. Callers (e.g.\n * the Policy Registry lint) can inspect `errors` for diagnostics.\n *\n * Phase 2-1-H — `validationErrors` is a parallel, richer view of the\n * same failures with line / column / context derived against the\n * original policy text. The legacy `errors` field is preserved as-is\n * so call sites that only need the message text don't need to change.\n */\nexport class CedarParseError extends Error {\n override readonly name = 'CedarParseError'\n readonly errors: CedarError[]\n /**\n * Structured diagnostics with `{ code, message, line, column, context,\n * offset }`. Always non-empty when the throw is from cedar-wasm; may\n * be empty when constructed from a non-cedar-wasm path (e.g. when an\n * upstream caller wraps an unexpected throw).\n */\n readonly validationErrors: PolicyValidationError[]\n\n constructor(\n message: string,\n errors: CedarError[],\n validationErrors: PolicyValidationError[] = [],\n ) {\n super(message)\n this.errors = errors\n this.validationErrors = validationErrors\n }\n}\n\n// --- Internal: cedar-wasm minimal surface ----------------------------------\n\n/**\n * Minimal subset of the cedar-wasm module surface we depend on. We type only\n * the shape we use so the SDK's d.ts doesn't accidentally pull in the full\n * upstream typings (which would broaden the public type-surface).\n */\ninterface CedarWasmModule {\n preparseSchema(name: string, schema: string): CedarCheckParseAnswer\n preparsePolicySet(\n psetId: string,\n policies: { staticPolicies: string },\n ): CedarCheckParseAnswer\n statefulIsAuthorized(call: CedarStatefulCall): CedarAuthorizationAnswer\n}\n\ninterface CedarStatefulCall {\n principal: { type: string; id: string }\n action: { type: string; id: string }\n resource: { type: string; id: string }\n context: Record<string, unknown>\n preparsedSchemaName?: string\n preparsedPolicySetId: string\n validateRequest?: boolean\n entities: ReadonlyArray<CedarEntity>\n}\n\ntype CedarCheckParseAnswer =\n | { type: 'success' }\n | { type: 'failure'; errors: CedarDetailedError[] }\n\ntype CedarAuthorizationAnswer =\n | {\n type: 'success'\n response: {\n decision: 'allow' | 'deny'\n diagnostics: { reason: string[]; errors: CedarAuthorizationError[] }\n }\n warnings: CedarDetailedError[]\n }\n | { type: 'failure'; errors: CedarDetailedError[]; warnings: CedarDetailedError[] }\n\ninterface CedarDetailedError {\n message: string\n code?: string | null\n /**\n * Source spans reported by cedar-wasm's miette-backed diagnostic\n * pipeline. `start` / `end` are 0-based byte offsets into the policy\n * text. `label` is a short hint about what was expected. We type only\n * the subset we use; cedar-wasm may include additional fields.\n */\n sourceLocations?: ReadonlyArray<{\n start?: number\n end?: number\n label?: string | null\n }> | null\n /** Cascaded diagnostics — same shape as the top-level error. */\n related?: ReadonlyArray<CedarDetailedError> | null\n}\n\ninterface CedarAuthorizationError {\n policyId: string\n error: CedarDetailedError\n}\n\n// --- Loader cache (C3 TOCTOU-safe) -----------------------------------------\n\ntype CedarLoader = () => Promise<CedarWasmModule>\n\nconst defaultLoader: CedarLoader = async () =>\n // Dynamic import keeps browser bundlers from inlining the Node-only subpath.\n // The cast widens the upstream module to our minimal surface above; we don't\n // re-export the upstream types.\n (await import('@cedar-policy/cedar-wasm/nodejs')) as unknown as CedarWasmModule\n\nlet activeLoader: CedarLoader = defaultLoader\nlet enginePromise: Promise<CedarEngine> | null = null\n\n/**\n * Create (or reuse) the singleton Cedar engine.\n *\n * - First call performs the dynamic import of cedar-wasm.\n * - Subsequent calls return the cached Promise — TOCTOU-safe.\n * - If the in-flight load rejects, the cache is cleared so retries work.\n */\nexport async function createCedarEngine(): Promise<CedarEngine> {\n if (enginePromise) return enginePromise\n\n const inFlight = doCreateCedarEngine(activeLoader).catch((err) => {\n // Clear cache on failure so a subsequent caller can retry.\n if (enginePromise === inFlight) {\n enginePromise = null\n }\n throw err\n })\n enginePromise = inFlight\n return enginePromise\n}\n\nasync function doCreateCedarEngine(loader: CedarLoader): Promise<CedarEngine> {\n let mod: CedarWasmModule\n try {\n mod = await loader()\n } catch (err) {\n throw new CedarEngineUnavailableError(err)\n }\n\n // Auto-generate per-handle ids. Cedar's wasm keys its preparsed cache by\n // string name/id, so we mint a unique one per call. A monotonic counter\n // is sufficient (the engine is process-scoped; ids never need to survive\n // across processes).\n let handleCounter = 0\n const nextId = (kind: string): string =>\n `${kind}-${++handleCounter}-${Date.now().toString(36)}`\n\n const adapter: CedarEngine = {\n preparseSchema(schemaText) {\n const name = nextId('schema')\n const ans = mod.preparseSchema(name, schemaText)\n if (ans.type === 'failure') {\n throw new CedarParseError(\n `Failed to parse Cedar schema: ${ans.errors[0]?.message ?? 'unknown error'}`,\n ans.errors.map(toCedarError),\n buildValidationErrors(ans.errors, schemaText),\n )\n }\n return { __cedar: 'schema', name }\n },\n\n preparsePolicySet(cedarText) {\n const id = nextId('pset')\n const ans = mod.preparsePolicySet(id, { staticPolicies: cedarText })\n if (ans.type === 'failure') {\n throw new CedarParseError(\n `Failed to parse Cedar PolicySet: ${ans.errors[0]?.message ?? 'unknown error'}`,\n ans.errors.map(toCedarError),\n buildValidationErrors(ans.errors, cedarText),\n )\n }\n return { __cedar: 'policySet', id }\n },\n\n evaluate(input) {\n const call: CedarStatefulCall = {\n principal: parseEntityUid(input.request.principal),\n action: parseEntityUid(input.request.action),\n resource: parseEntityUid(input.request.resource),\n context: input.request.context ?? {},\n preparsedPolicySetId: input.policySetHandle.id,\n entities: input.entities,\n }\n if (input.schemaHandle) {\n call.preparsedSchemaName = input.schemaHandle.name\n // Only request validation when a schema is available; without one\n // Cedar treats `validateRequest: true` as an error.\n call.validateRequest = true\n }\n\n const ans = mod.statefulIsAuthorized(call)\n if (ans.type === 'failure') {\n return {\n decision: 'Deny',\n reasons: [],\n errors: ans.errors.map(toCedarError),\n }\n }\n\n return {\n decision: ans.response.decision === 'allow' ? 'Allow' : 'Deny',\n reasons: ans.response.diagnostics.reason ?? [],\n errors: (ans.response.diagnostics.errors ?? []).map((e) => ({\n policyId: e.policyId,\n message: e.error.message,\n code: e.error.code ?? undefined,\n })),\n }\n },\n }\n\n return adapter\n}\n\nfunction toCedarError(e: CedarDetailedError): CedarError {\n return {\n message: e.message,\n code: e.code ?? undefined,\n }\n}\n\n/**\n * Phase 2-1-H — flatten cedar-wasm's `{ message, sourceLocations[],\n * related[] }` tree into a list of `PolicyValidationError` entries\n * with line/column derived against the original policy text.\n *\n * `related[]` entries are walked recursively and emitted as siblings\n * of the top-level error (cedar-wasm uses `related` for \"and also...\"\n * style cascade diagnostics — UIs typically render all of them, not\n * just the head).\n *\n * If cedar-wasm returns no `sourceLocations`, we still emit an entry\n * (without line/column) so the caller always sees at least one error\n * per failure path.\n *\n * @internal — Phase 2-1-H heuristic implementation. Exported for cross-package\n * reuse (API + agentd / remote-mcp future surfaces) and unit tests, but NOT a\n * stable public API. Will be replaced once cedar-wasm exposes structured\n * diagnostic codes upstream (tracked as Phase 2-2-I). Semver of `@vess-id/ai-identity`\n * may remove or rename this function without a major bump.\n */\nexport function buildValidationErrors(\n errors: ReadonlyArray<CedarDetailedError>,\n sourceText: string,\n): PolicyValidationError[] {\n const out: PolicyValidationError[] = []\n // Defensive depth cap — cedar-wasm 4.11.0 produces shallow trees (1-2 levels)\n // in practice, but a malformed/cyclic `related` chain shouldn't blow the stack.\n // Higher levels are dropped silently; UI would not render them anyway.\n const MAX_DEPTH = 10\n const visit = (e: CedarDetailedError, depth: number): void => {\n if (depth >= MAX_DEPTH) return\n const code = classifyCedarErrorMessage(e.message, e.code ?? undefined)\n const loc = (e.sourceLocations ?? []).find(\n (l) => typeof l?.start === 'number',\n )\n const offset = typeof loc?.start === 'number' ? loc.start : undefined\n const end = typeof loc?.end === 'number' ? loc.end : undefined\n const lc = offset !== undefined ? offsetToLineColumn(sourceText, offset) : null\n const context =\n offset !== undefined && end !== undefined && end > offset\n ? truncateContext(sourceText.slice(offset, end))\n : undefined\n out.push({\n code,\n message: e.message,\n ...(lc ? { line: lc.line, column: lc.column } : {}),\n ...(context !== undefined ? { context } : {}),\n ...(offset !== undefined ? { offset } : {}),\n })\n if (e.related && Array.isArray(e.related)) {\n for (const child of e.related) visit(child, depth + 1)\n }\n }\n for (const e of errors) visit(e, 0)\n return out\n}\n\n/**\n * Heuristic classifier mapping cedar-wasm's English message text to a\n * stable snake_case code. cedar-wasm@4.11.0 does not yet expose a\n * structured `code` field (the `code` slot in `CedarDetailedError` is\n * always `null` for parse failures), so we match on substring patterns\n * that have proven stable across recent releases.\n *\n * If `cedarCode` is supplied (future cedar-wasm release) it wins.\n *\n * Returned codes (must stay in sync with the JSDoc on\n * `PolicyValidationError.code`):\n * - `parse_error` — generic parse failure (fallback)\n * - `unexpected_end_of_input` — incomplete policy\n * - `unexpected_token` — token didn't match expected production\n * - `unknown_extension` — referenced unknown extension fn\n * - `unknown` — message didn't match any pattern\n *\n * @internal — Phase 2-1-H heuristic implementation, same caveat as\n * `buildValidationErrors`. Will be replaced once cedar-wasm exposes structured\n * diagnostic codes upstream (Phase 2-2-I).\n */\nexport function classifyCedarErrorMessage(\n message: string,\n cedarCode?: string,\n): string {\n if (cedarCode && cedarCode.length > 0) return cedarCode\n const m = message.toLowerCase()\n if (m.includes('unexpected end of input')) return 'unexpected_end_of_input'\n if (m.includes('unexpected token')) return 'unexpected_token'\n if (m.includes('unknown extension')) return 'unknown_extension'\n if (m.includes('failed to parse')) return 'parse_error'\n return 'unknown'\n}\n\n/**\n * Convert a 0-based byte offset to a 1-based `{ line, column }`.\n *\n * Cedar's `sourceLocations` reports byte offsets, but JS strings are\n * UTF-16; for ASCII Cedar source (the common case) the two coincide.\n * For multi-byte chars in policy text (rare — non-ASCII can appear in\n * quoted string literals, Cedar entity / type names, and policy\n * comments) the column may be slightly off by the UTF-8/UTF-16\n * mismatch. We accept this trade-off because the alternative\n * (decoding the policy text as UTF-8 bytes to find the char boundary)\n * would push the implementation considerably; the resulting caret is\n * \"approximately right\" for UI display, which is what's needed.\n */\nfunction offsetToLineColumn(\n text: string,\n offset: number,\n): { line: number; column: number } {\n // Clamp so an out-of-range offset (cedar-wasm sometimes points one\n // past the end for `unexpected end of input`) doesn't blow up.\n const safe = Math.max(0, Math.min(offset, text.length))\n let line = 1\n let lineStart = 0\n for (let i = 0; i < safe; i++) {\n if (text.charCodeAt(i) === 10 /* \\n */) {\n line += 1\n lineStart = i + 1\n }\n }\n return { line, column: safe - lineStart + 1 }\n}\n\n/**\n * Truncate the offending slice so a 64 KB upstream policy doesn't\n * end up in a 64 KB error response. 200 chars is enough to convey\n * the offending span; a trailing `…` signals truncation.\n */\nfunction truncateContext(slice: string): string {\n const max = 200\n if (slice.length <= max) return slice\n return slice.slice(0, max - 1) + '…'\n}\n\n/**\n * Parse a Cedar entity-uid expression like `Agent::\"agent-1\"` into the\n * `{ type, id }` shape statefulIsAuthorized expects.\n *\n * We accept the textual form because it's the natural representation in\n * policy strings and is easier for callers to construct. Throws if the\n * input doesn't match — this is intentionally strict; downstream code\n * should always pass canonical entity uids.\n */\n// Cedar uses `::` (double colon) as the namespace separator. A single colon\n// in the type prefix is invalid (e.g. `Foo:Bar::\"id\"` should be rejected).\n// We allow optional repeated `::Segment` segments before the final `::\"id\"`.\nconst ENTITY_UID_PATTERN =\n /^([A-Za-z_]\\w*(?:::[A-Za-z_]\\w*)*)::\"((?:[^\"\\\\]|\\\\.)*)\"$/\n\nfunction parseEntityUid(uid: string): { type: string; id: string } {\n // Match `Namespace::\"id\"` with an optional namespace-path prefix.\n // e.g. `Agent::\"a-1\"`, `MyOrg::Agent::\"a-1\"`.\n const m = uid.match(ENTITY_UID_PATTERN)\n if (!m) {\n throw new Error(\n `Invalid Cedar entity uid expression: ${JSON.stringify(uid)}. ` +\n `Expected form: Type::\"id\" (e.g. Agent::\"agent-1\").`,\n )\n }\n return {\n type: m[1] as string,\n // Unescape standard Cedar string escapes (\\\" → \").\n id: (m[2] as string).replace(/\\\\(.)/g, '$1'),\n }\n}\n\n// --- Test-only hooks --------------------------------------------------------\n//\n// These are exported so the unit tests can drive load behaviour\n// deterministically (TOCTOU regression + retry-after-failure). Production\n// code MUST NOT call them.\n\n/** Drop the cached engine Promise. Production callers should never need this. */\nexport function __resetCedarEngineCache(): void {\n enginePromise = null\n}\n\n/**\n * Override the cedar-wasm loader used by `createCedarEngine`. Pass `null` to\n * restore the default dynamic-import loader.\n */\nexport function __setCedarLoaderForTests(loader: CedarLoader | null): void {\n activeLoader = loader ?? defaultLoader\n}\n\n/**\n * Test-only wrapper around the module-internal `parseEntityUid`. Lets the\n * spec assert the entity-uid regex directly (e.g. that single-colon namespace\n * forms are rejected) without contorting `evaluate` invocations.\n *\n * Production code MUST NOT call this — the leading underscores follow the\n * `__resetCedarEngineCache` / `__setCedarLoaderForTests` convention used\n * elsewhere in this module for test-only escape hatches.\n */\nexport function __parseEntityUidForTests(uid: string): {\n type: string\n id: string\n} {\n return parseEntityUid(uid)\n}\n","/**\n * Action risk-level resolver — registry-driven (OpenQ-5 root fix).\n *\n * Spec refs:\n * - docs/specs/2026-05-27-action-risk-registry-driven.md §3\n * - docs/specs/2026-05-24-cedar-unification-design.md §7.2 (original Phase 1\n * suffix heuristic, now retained only as a fallback)\n *\n * Resolution order:\n * 1. If the action exists in ACTION_REGISTRY and declares a `risk`, return\n * that value — ACTION_REGISTRY is the single source of truth (matching\n * CLAUDE.md). This is what Cedar `context.action.risk_level` binds to,\n * so a developer's hand-curated `risk: 'high'` is now authoritative.\n * 2. Otherwise (unknown / not-yet-registered action) fall back to the\n * deterministic suffix heuristic below:\n * - write/send/delete-class suffixes → 'high'\n * - read/list/get-class suffixes → 'low'\n * - everything else → 'medium' (fail-safe)\n *\n * The suffix heuristic classifies by the **last dotted segment** of the\n * action name (e.g., `gmail.message.send` → `send` → 'high').\n *\n * Lookup is case-insensitive: input is lowercased before the registry Map\n * lookup (registry keys are all lowercase), so `gmail.message.TRASH` still\n * hits the registry `high` instead of mis-falling-back to the suffix value.\n */\n\nimport { ACTION_REGISTRY } from './action-registry-json'\n\nexport type ActionRisk = 'low' | 'medium' | 'high'\n\nconst HIGH_RISK_SUFFIXES = new Set([\n 'send',\n 'post',\n 'create',\n 'update',\n 'delete',\n 'remove',\n 'write',\n 'modify',\n 'upload',\n 'invite',\n 'archive',\n 'unarchive',\n 'kick',\n 'rename',\n 'patch',\n 'put',\n])\n\nconst LOW_RISK_SUFFIXES = new Set([\n 'read',\n 'list',\n 'get',\n 'search',\n 'find',\n 'lookup',\n 'show',\n 'view',\n 'fetch',\n 'history',\n 'info',\n])\n\n/**\n * Module-load-time cache: lowercased action name → registry `risk`.\n *\n * Built once so resolveActionRisk does an O(1) Map lookup instead of a\n * linear scan of ACTION_REGISTRY.actions on every call. Keys are lowercased\n * to support case-insensitive lookup.\n */\nconst REGISTRY_RISK_BY_ACTION: ReadonlyMap<string, ActionRisk> = (() => {\n const map = new Map<string, ActionRisk>()\n for (const entry of ACTION_REGISTRY.actions) {\n if (typeof entry.action === 'string' && typeof entry.risk === 'string') {\n map.set(entry.action.toLowerCase(), entry.risk as ActionRisk)\n }\n }\n return map\n})()\n\n/**\n * Suffix-heuristic fallback for actions not present in ACTION_REGISTRY.\n * Classifies by the last dotted segment of an already-lowercased name.\n */\nfunction resolveActionRiskBySuffix(lowerAction: string): ActionRisk {\n const segments = lowerAction.split('.')\n const last = segments[segments.length - 1] ?? ''\n if (!last) return 'medium'\n if (HIGH_RISK_SUFFIXES.has(last)) return 'high'\n if (LOW_RISK_SUFFIXES.has(last)) return 'low'\n return 'medium'\n}\n\n/**\n * Resolve the risk level for a dotted action name.\n *\n * Registry-driven: a registered action returns its declared `risk`\n * (authoritative); unknown actions fall back to the suffix heuristic.\n *\n * Examples:\n * resolveActionRisk('os.secret.read') → 'high' (registry)\n * resolveActionRisk('gmail.message.trash') → 'high' (registry)\n * resolveActionRisk('jira.issue.transition') → 'high' (registry)\n * resolveActionRisk('unknown.connector.send') → 'high' (suffix fallback)\n * resolveActionRisk('unknown.connector.read') → 'low' (suffix fallback)\n * resolveActionRisk('unknown.connector.sync') → 'medium'(suffix fallback)\n *\n * Defensive defaults:\n * - empty / falsy input → 'medium' (fail-safe; never throws)\n * - unknown suffix → 'medium'\n */\nexport function resolveActionRisk(action: string | undefined | null): ActionRisk {\n if (!action || typeof action !== 'string') return 'medium'\n const lower = action.toLowerCase()\n const registryRisk = REGISTRY_RISK_BY_ACTION.get(lower)\n if (registryRisk) return registryRisk\n return resolveActionRiskBySuffix(lower)\n}\n","/**\n * buildCedarEntities — Cedar entity-list builder (Cedar unification Step 1).\n *\n * Spec ref:\n * - docs/specs/2026-05-24-cedar-unification-design.md §7.1\n * Phase 1 採用方針: entity attribute と context の **二重 bind**。本 helper は\n * entity 側のみを組み立て、`context.action.risk_level` は呼び出し側\n * (`CedarDecisionService.buildCedarEvaluateRequest`) が context にも別途\n * 注入する。これは Cedar 4.11.0 が schema-less な entity attribute 直参照を\n * policy text 内では制限するため、policy 内では `context.action.risk_level`\n * 経由を Phase 1 で採用するという rev 3 C1 で確定した設計判断による。\n *\n * Action entity の `attrs.risk_level` は本 helper の責務、\n * `context.action.risk_level` は CedarDecisionService の責務。\n * Phase 2+ で Cedar schema 導入時に context 側を撤去し entity 直参照に統一する。\n */\n\nimport type { CedarEntity } from './cedar-engine'\nimport { resolveActionRisk } from '../registry/action-risk'\n\n/**\n * Principal or resource descriptor accepted by {@link buildCedarEntities}.\n * `type` is the Cedar entity-type name (e.g., `Agent`, `User`, `GmailThread`).\n * `attrs` defaults to `{}` if omitted. `parents` is always `[]` in Phase 1\n * (entity hierarchy is reserved for Phase 2 schema work).\n */\nexport interface CedarEntityDescriptor {\n type: string\n id: string\n attrs?: Record<string, unknown>\n}\n\n/**\n * Input contract for {@link buildCedarEntities}. `action` is the dotted\n * action name (e.g., `'gmail.message.send'`); the helper looks up the\n * Phase 1 risk level via {@link resolveActionRisk} and binds it as\n * `Action::\"<id>\".attrs.risk_level`.\n *\n * Context (including `context.action.risk_level`, `context.approval.granted`,\n * `context.environment.*`) is **not** built here — the caller (typically\n * `CedarDecisionService`) builds context separately because the same entities\n * are reused across Phase A / Phase B (approval=false / approval=true)\n * evaluations.\n */\nexport interface CedarEntitiesInput {\n principal: CedarEntityDescriptor\n action: string\n resource: CedarEntityDescriptor\n}\n\n/**\n * Build the Cedar entity list (principal + action + resource) for a single\n * authorization evaluation.\n *\n * Returns exactly 3 entities, in stable order [principal, action, resource].\n * The Action entity gets `attrs.risk_level` populated from\n * {@link resolveActionRisk}. principal / resource pass through `attrs`\n * unchanged (defaulting to `{}` when omitted).\n *\n * Entity hierarchy (`parents`) is intentionally empty in Phase 1 — Phase 2\n * will introduce schema-driven parents (e.g., GmailThread → GmailLabel).\n */\nexport function buildCedarEntities(input: CedarEntitiesInput): CedarEntity[] {\n const { principal, action, resource } = input\n\n const principalEntity: CedarEntity = {\n uid: { type: principal.type, id: principal.id },\n attrs: principal.attrs ?? {},\n parents: [],\n }\n\n const actionEntity: CedarEntity = {\n uid: { type: 'Action', id: action },\n attrs: { risk_level: resolveActionRisk(action) },\n parents: [],\n }\n\n const resourceEntity: CedarEntity = {\n uid: { type: resource.type, id: resource.id },\n attrs: resource.attrs ?? {},\n parents: [],\n }\n\n return [principalEntity, actionEntity, resourceEntity]\n}\n","/**\n * Decision 7-value enum — A2A / AP2 aligned (Cedar unification Step 1).\n *\n * Spec ref:\n * - docs/specs/2026-05-24-cedar-unification-design.md §3\n * - decision #9 (Locked Decisions §2): A2A 互換 7 値、後方互換破壊 OK\n *\n * HTTP mapping (spec §3, line 169):\n * - `permit` → 200\n * - `auth_required` → 202 (replaces legacy `RequireApproval`)\n * - `input_required` → reserved for Phase 2+\n * - `denied` → 403 (explicit forbid policy match)\n * - `denied_default` → 403 (no permit policy matched)\n * - `denied_by_user` → 403 (HITL UI rejection)\n * - `indeterminate` → 500 (Cedar evaluation error, fail-closed)\n *\n * Phase 1 Step 1 scope: SDK enum + runtime guard only.\n * Step 2 (API layer) will rewire `CedarDecisionService` to emit these values\n * and replace the legacy 3-value `CedarDecisionValue` (`Permit | Forbid |\n * RequireApproval`) over the wire. Both types coexist during the transition.\n */\n\n/**\n * The 7 decision states a permission evaluator may emit. Lowercase + snake_case\n * to match A2A protocol naming conventions.\n */\nexport type Decision =\n | 'permit'\n | 'auth_required'\n | 'input_required'\n | 'denied'\n | 'denied_default'\n | 'denied_by_user'\n | 'indeterminate'\n\n/**\n * Frozen ordered tuple of every {@link Decision} value. Useful for `it.each`\n * test enumeration, exhaustiveness assertions, and audit-log validation.\n *\n * The order is **stable** and is the canonical iteration order (permit first,\n * then approval gate, then input gate, then the 3 denied variants, then the\n * fail-closed indeterminate). Do not rely on alphabetic order.\n */\nexport const DECISION_VALUES = [\n 'permit',\n 'auth_required',\n 'input_required',\n 'denied',\n 'denied_default',\n 'denied_by_user',\n 'indeterminate',\n] as const satisfies ReadonlyArray<Decision>\n\n/**\n * Runtime type guard for {@link Decision}. Returns `true` only if `value` is\n * one of the 7 canonical literals. Use this when validating wire payloads\n * (audit log rows, HTTP bodies, IPC) before narrowing to `Decision`.\n *\n * Legacy 3-value capitalized literals (`Permit`, `Forbid`, `RequireApproval`)\n * are **not** accepted; callers that still need to handle the old wire format\n * must do their own translation (Step 2 will provide the migration helper).\n */\nexport function isDecision(value: unknown): value is Decision {\n return (\n typeof value === 'string' &&\n (DECISION_VALUES as ReadonlyArray<string>).includes(value)\n )\n}\n"],"mappings":"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","names":["path","uuidv4","import_node_crypto","fs","path","os","import_uuid","uuidv4","fs","path","os","import_crypto_nodejs","AgentStatus","AgentType","CredentialType","CredentialStatus","VCType","VCStatus","GrantStatus","GrantScope","GrantResourceType","ReceiptStatus","StandardActionCategory","OAuthProvider","InvitationStatus","fs","path","os","Ajv","addFormats","path","fs","import_crypto","path","import_crypto"]}
|