computeKeysHash produces a deterministic hash over the bearer API keys and, for Bedrock providers, the access key and secret.
(bearerKeys []string, bedrock *codersdk.AIProviderBedrockSettings)
| 257 | // computeKeysHash produces a deterministic hash over the bearer API |
| 258 | // keys and, for Bedrock providers, the access key and secret. |
| 259 | func computeKeysHash(bearerKeys []string, bedrock *codersdk.AIProviderBedrockSettings) string { |
| 260 | // Collect all credential material in a deterministic order. |
| 261 | // Bearer keys are sorted so reordering in env vars does not |
| 262 | // trigger a false-positive drift. |
| 263 | sorted := make([]string, len(bearerKeys)) |
| 264 | copy(sorted, bearerKeys) |
| 265 | slices.Sort(sorted) |
| 266 | |
| 267 | h := sha256.New() |
| 268 | for _, k := range sorted { |
| 269 | _, _ = h.Write([]byte(k)) |
| 270 | // Separator so "ab"+"c" != "a"+"bc". |
| 271 | _, _ = h.Write([]byte{0}) |
| 272 | } |
| 273 | if bedrock != nil { |
| 274 | if bedrock.AccessKey != nil { |
| 275 | _, _ = h.Write([]byte(*bedrock.AccessKey)) |
| 276 | } |
| 277 | _, _ = h.Write([]byte{0}) |
| 278 | if bedrock.AccessKeySecret != nil { |
| 279 | _, _ = h.Write([]byte(*bedrock.AccessKeySecret)) |
| 280 | } |
| 281 | _, _ = h.Write([]byte{0}) |
| 282 | } |
| 283 | return hex.EncodeToString(h.Sum(nil)) |
| 284 | } |
| 285 | |
| 286 | func computeProviderHash(c canonicalAIProvider) string { |
| 287 | // json.Marshal is deterministic for structs because field order is |