MCPcopy Create free account
hub / github.com/oboard/claude-code-rev / saveApiKey

Function saveApiKey

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

Source from the content-addressed store, hash-verified

1142}
1143
1144export async function saveApiKey(apiKey: string): Promise<void> {
1145 if (!isValidApiKey(apiKey)) {
1146 throw new Error(
1147 'Invalid API key format. API key must contain only alphanumeric characters, dashes, and underscores.',
1148 )
1149 }
1150
1151 // Store as primary API key
1152 await maybeRemoveApiKeyFromMacOSKeychain()
1153 let savedToKeychain = false
1154 if (process.platform === 'darwin') {
1155 try {
1156 // TODO: migrate to SecureStorage
1157 const storageServiceName = getMacOsKeychainStorageServiceName()
1158 const username = getUsername()
1159
1160 // Convert to hexadecimal to avoid any escaping issues
1161 const hexValue = Buffer.from(apiKey, 'utf-8').toString('hex')
1162
1163 // Use security's interactive mode (-i) with -X (hexadecimal) option
1164 // This ensures credentials never appear in process command-line arguments
1165 // Process monitors only see "security -i", not the password
1166 const command = `add-generic-password -U -a "${username}" -s "${storageServiceName}" -X "${hexValue}"\n`
1167
1168 await execa('security', ['-i'], {
1169 input: command,
1170 reject: false,
1171 })
1172
1173 logEvent('tengu_api_key_saved_to_keychain', {})
1174 savedToKeychain = true
1175 } catch (e) {
1176 logError(e)
1177 logEvent('tengu_api_key_keychain_error', {
1178 error: errorMessage(
1179 e,
1180 ) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
1181 })
1182 logEvent('tengu_api_key_saved_to_config', {})
1183 }
1184 } else {
1185 logEvent('tengu_api_key_saved_to_config', {})
1186 }
1187
1188 const normalizedKey = normalizeApiKeyForConfig(apiKey)
1189
1190 // Save config with all updates
1191 saveGlobalConfig(current => {
1192 const approved = current.customApiKeyResponses?.approved ?? []
1193 return {
1194 ...current,
1195 // Only save to config if keychain save failed or not on darwin
1196 primaryApiKey: savedToKeychain ? current.primaryApiKey : apiKey,
1197 customApiKeyResponses: {
1198 ...current.customApiKeyResponses,
1199 approved: approved.includes(normalizedKey)
1200 ? approved
1201 : [...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