78 lines · 3.5 KB · Swift
RawDownload
import Foundation /// Resolves Bedrock signing credentials + region for the configured auth mode.////// Shared by the main usage fetch (`BedrockAPIFetchStrategy`) and the daily/// cost-history refresh (`CostUsageFetcher`) so both honor AWS-profile auth/// identically instead of the history path silently requiring static keys.enum BedrockCredentialResolver {    struct Resolved {        let credentials: BedrockAWSSigner.Credentials        let region: String    }     static func resolve(        environment: [String: String],        resolveAWSBinary: ([String: String]) -> String? = { BinaryLocator.resolveAWSBinary(env: $0) },        makeProvider: (String) -> BedrockProfileCredentialProvider = {            BedrockProfileCredentialProvider.live(awsBinaryPath: $0)        }) async throws -> Resolved    {        switch BedrockSettingsReader.authMode(environment: environment) {        case .keys:            guard let accessKeyID = BedrockSettingsReader.accessKeyID(environment: environment),                  let secretAccessKey = BedrockSettingsReader.secretAccessKey(environment: environment)            else {                throw BedrockUsageError.missingCredentials            }            let credentials = BedrockAWSSigner.Credentials(                accessKeyID: accessKeyID,                secretAccessKey: secretAccessKey,                sessionToken: BedrockSettingsReader.sessionToken(environment: environment))            return Resolved(                credentials: credentials,                region: BedrockSettingsReader.region(environment: environment))         case .profile:            guard let profile = BedrockSettingsReader.profile(environment: environment) else {                throw BedrockUsageError.missingCredentials            }            guard let awsBinary = resolveAWSBinary(environment) else {                throw BedrockUsageError.awsCLINotFound            }            let cliEnvironment = Self.profileCLIEnvironment(environment)            let provider = makeProvider(awsBinary)            let credentials = try await provider.exportCredentials(profile: profile, environment: cliEnvironment)            let region = try await Self.resolveRegion(                provider: provider,                profile: profile,                environment: cliEnvironment)            return Resolved(credentials: credentials, region: region)        }    }     private static func profileCLIEnvironment(_ environment: [String: String]) -> [String: String] {        var cliEnvironment = environment        // `--profile` selects the requested profile. Leaving AWS_PROFILE set can        // break assume-role profiles that use `credential_source = Environment`;        // keep the source credential variables themselves available.        cliEnvironment[BedrockSettingsReader.profileKey] = nil        return cliEnvironment    }     private static func resolveRegion(        provider: BedrockProfileCredentialProvider,        profile: String,        environment: [String: String]) async throws -> String    {        if let explicit = BedrockSettingsReader.cleaned(environment[BedrockSettingsReader.regionKeys[0]])            ?? BedrockSettingsReader.cleaned(environment[BedrockSettingsReader.regionKeys[1]])        {            return explicit        }        if let derived = try await provider.resolveRegion(profile: profile, environment: environment) {            return derived        }        return BedrockSettingsReader.defaultRegion    }}