UNPKG

@mondaydotcomorg/atp-protocol

Version:

Core protocol types and interfaces for Agent Tool Protocol

202 lines 7.26 kB
/** * Authentication and credential management types for Agent Tool Protocol */ /** * Credential resolver - resolves auth config to actual credentials */ export class CredentialResolver { providers = new Map(); /** * Registers a runtime credential provider */ registerProvider(provider) { this.providers.set(provider.name, provider); } /** * Resolves auth configuration to credentials */ async resolve(authConfig) { if (authConfig.provider) { const provider = this.providers.get(authConfig.provider); if (!provider) { throw new Error(`Credential provider '${authConfig.provider}' not found`); } return await provider.resolve(); } switch (authConfig.scheme) { case 'apiKey': return this.resolveAPIKey(authConfig); case 'bearer': return this.resolveBearer(authConfig); case 'basic': return this.resolveBasic(authConfig); case 'oauth2': return this.resolveOAuth2(authConfig); case 'custom': return this.resolveCustom(authConfig); case 'composite': return this.resolveComposite(authConfig); default: throw new Error(`Unsupported auth scheme: ${authConfig.scheme}`); } } resolveAPIKey(config) { const value = this.getValue(config); if (!value) { throw new Error(`API key not provided for '${config.name}'`); } if (config.in === 'header') { return { headers: { [config.name]: value } }; } else { return { queryParams: { [config.name]: value } }; } } resolveBearer(config) { const token = this.getValue(config); if (!token) { throw new Error('Bearer token not provided'); } return { headers: { Authorization: `Bearer ${token}`, }, }; } resolveBasic(config) { const username = config.usernameEnvVar ? process.env[config.usernameEnvVar] : config.username; const password = config.passwordEnvVar ? process.env[config.passwordEnvVar] : this.getValue(config); if (!username || !password) { throw new Error('Basic auth username and password not provided'); } const credentials = Buffer.from(`${username}:${password}`).toString('base64'); return { headers: { Authorization: `Basic ${credentials}`, }, }; } async resolveOAuth2(config) { const clientId = config.clientIdEnvVar ? process.env[config.clientIdEnvVar] : config.clientId; const clientSecret = config.clientSecretEnvVar ? process.env[config.clientSecretEnvVar] : undefined; if (!clientId || !clientSecret) { throw new Error('OAuth2 client credentials not provided'); } if (config.flow === 'clientCredentials') { const token = await this.fetchOAuth2Token(config.tokenUrl, clientId, clientSecret, config.scopes); return { headers: { Authorization: `Bearer ${token}`, }, }; } const token = this.getValue(config); if (token) { return { headers: { Authorization: `Bearer ${token}`, }, }; } throw new Error(`OAuth2 flow '${config.flow}' requires manual token setup`); } resolveCustom(config) { const headers = {}; const queryParams = {}; Object.assign(headers, config.headers); if (config.headerEnvVars) { for (const [headerName, envVar] of Object.entries(config.headerEnvVars)) { const value = process.env[envVar]; if (value) { headers[headerName] = value; } } } if (config.queryParams) { Object.assign(queryParams, config.queryParams); } if (config.queryParamEnvVars) { for (const [paramName, envVar] of Object.entries(config.queryParamEnvVars)) { const value = process.env[envVar]; if (value) { queryParams[paramName] = value; } } } return { headers: Object.keys(headers).length > 0 ? headers : undefined, queryParams: Object.keys(queryParams).length > 0 ? queryParams : undefined, }; } resolveComposite(config) { const headers = {}; const queryParams = {}; for (const [credName, credConfig] of Object.entries(config.credentials)) { const value = credConfig.envVar ? process.env[credConfig.envVar] : credConfig.value; if (!value) { if (credConfig.required !== false) { throw new Error(`Required credential '${credName}' not provided`); } continue; } const injectAs = config.injectAs || 'header'; if ((injectAs === 'header' || injectAs === 'both') && credConfig.headerName) { headers[credConfig.headerName] = value; } if ((injectAs === 'query' || injectAs === 'both') && credConfig.queryParamName) { queryParams[credConfig.queryParamName] = value; } if (!credConfig.headerName && !credConfig.queryParamName) { if (injectAs === 'query' || injectAs === 'both') { queryParams[credName] = value; } else { headers[`X-${credName}`] = value; } } } return { headers: Object.keys(headers).length > 0 ? headers : undefined, queryParams: Object.keys(queryParams).length > 0 ? queryParams : undefined, }; } /** * Gets credential value from config (env var or direct value) */ getValue(config) { if (config.envVar) { return process.env[config.envVar]; } return config.value; } /** * Fetches OAuth2 token using client credentials flow */ async fetchOAuth2Token(tokenUrl, clientId, clientSecret, scopes) { const params = new URLSearchParams({ grant_type: 'client_credentials', client_id: clientId, client_secret: clientSecret, }); if (scopes && scopes.length > 0) { params.append('scope', scopes.join(' ')); } const response = await fetch(tokenUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: params.toString(), }); if (!response.ok) { throw new Error(`OAuth2 token fetch failed: ${response.statusText}`); } const data = (await response.json()); return data.access_token; } } //# sourceMappingURL=auth.js.map