MCPcopy
hub / github.com/codeaashu/claude-code / saveApiKey

Function saveApiKey

src/utils/auth.ts:1094–1160  ·  view source on GitHub ↗
(apiKey: string)

Source from the content-addressed store, hash-verified

1092}
1093
1094export async function saveApiKey(apiKey: string): Promise<void> {
1095 if (!isValidApiKey(apiKey)) {
1096 throw new Error(
1097 'Invalid API key format. API key must contain only alphanumeric characters, dashes, and underscores.',
1098 )
1099 }
1100
1101 // Store as primary API key
1102 await maybeRemoveApiKeyFromMacOSKeychain()
1103 let savedToKeychain = false
1104 if (process.platform === 'darwin') {
1105 try {
1106 // TODO: migrate to SecureStorage
1107 const storageServiceName = getMacOsKeychainStorageServiceName()
1108 const username = getUsername()
1109
1110 // Convert to hexadecimal to avoid any escaping issues
1111 const hexValue = Buffer.from(apiKey, 'utf-8').toString('hex')
1112
1113 // Use security's interactive mode (-i) with -X (hexadecimal) option
1114 // This ensures credentials never appear in process command-line arguments
1115 // Process monitors only see "security -i", not the password
1116 const command = `add-generic-password -U -a "${username}" -s "${storageServiceName}" -X "${hexValue}"\n`
1117
1118 await execa('security', ['-i'], {
1119 input: command,
1120 reject: false,
1121 })
1122
1123 logEvent('tengu_api_key_saved_to_keychain', {})
1124 savedToKeychain = true
1125 } catch (e) {
1126 logError(e)
1127 logEvent('tengu_api_key_keychain_error', {
1128 error: errorMessage(
1129 e,
1130 ) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
1131 })
1132 logEvent('tengu_api_key_saved_to_config', {})
1133 }
1134 } else {
1135 logEvent('tengu_api_key_saved_to_config', {})
1136 }
1137
1138 const normalizedKey = normalizeApiKeyForConfig(apiKey)
1139
1140 // Save config with all updates
1141 saveGlobalConfig(current => {
1142 const approved = current.customApiKeyResponses?.approved ?? []
1143 return {
1144 ...current,
1145 // Only save to config if keychain save failed or not on darwin
1146 primaryApiKey: savedToKeychain ? current.primaryApiKey : apiKey,
1147 customApiKeyResponses: {
1148 ...current.customApiKeyResponses,
1149 approved: approved.includes(normalizedKey)
1150 ? approved
1151 : [...approved, normalizedKey],

Callers 1

createAndStoreApiKeyFunction · 0.85

Calls 12

isValidApiKeyFunction · 0.85
logEventFunction · 0.85
normalizeApiKeyForConfigFunction · 0.85
saveGlobalConfigFunction · 0.85
logErrorFunction · 0.70
errorMessageFunction · 0.70
toStringMethod · 0.65
getUsernameFunction · 0.50
clearMethod · 0.45

Tested by

no test coverage detected