Skip to content

Commit

Permalink
Try #621:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored May 10, 2023
2 parents 2e48bf7 + 67c7f3c commit 8b0f1e8
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 55 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "AWS"
uuid = "fbe9abb3-538b-5e4e-ba9e-bc94f4f92ebc"
license = "MIT"
version = "1.85.0"
version = "1.86.0"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
57 changes: 45 additions & 12 deletions src/AWSCredentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export AWSCredentials,
external_process_credentials,
localhost_is_ec2,
localhost_is_lambda,
localhost_maybe_ec2
localhost_maybe_ec2,
sso_credentials

function localhost_maybe_ec2()
return localhost_is_ec2() || isfile("/sys/devices/virtual/dmi/id/product_uuid")
Expand Down Expand Up @@ -110,12 +111,14 @@ Checks credential locations in the order:
function AWSCredentials(; profile=nothing, throw_cred_error=true)
creds = nothing
credential_function = () -> nothing
explicit_profile = !isnothing(profile)
profile = @something profile _aws_get_profile()

# Define our search options, expected to be callable with no arguments.
# Throw NoCredentials if none are found
# Define the credential preference order
# https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html#cli-chap-authentication-precedence
functions = [
env_var_credentials,
() -> env_var_credentials(explicit_profile),
() -> sso_credentials(profile),
() -> dot_aws_credentials(profile),
() -> dot_aws_config(profile),
credentials_from_webtoken,
Expand Down Expand Up @@ -355,12 +358,15 @@ function ecs_instance_credentials()
end

"""
env_var_credentials() -> Union{AWSCredential, Nothing}
env_var_credentials(explicit_profile::Bool=false) -> Union{AWSCredential, Nothing}
Use AWS environmental variables (e.g. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.)
to create AWSCredentials.
"""
function env_var_credentials()
function env_var_credentials(explicit_profile::Bool=false)
# Skip using environmental variables when a profile has been explicitly set
explicit_profile && return nothing

if haskey(ENV, "AWS_ACCESS_KEY_ID") && haskey(ENV, "AWS_SECRET_ACCESS_KEY")
return AWSCredentials(
ENV["AWS_ACCESS_KEY_ID"],
Expand Down Expand Up @@ -404,12 +410,43 @@ function dot_aws_credentials_file()
end
end

"""
sso_credentials(profile=nothing) -> Union{AWSCredential, Nothing}
Retrieve credentials via AWS single sign-on settings defined in the `profile` within the AWS
config file. If no SSO settings are found for the `profile` `nothing` is returned.
# Arguments
- `profile`: Specific profile used to get `AWSCredential`s, default is `nothing`
"""
function sso_credentials(profile=nothing)
config_file = @mock dot_aws_config_file()

if isfile(config_file)
ini = read(Inifile(), config_file)
p = @something profile _aws_get_profile()

# get all the fields for that profile
settings = _aws_profile_config(ini, p)
isempty(settings) && return nothing

sso_start_url = get(settings, "sso_start_url", nothing)

if !isnothing(sso_start_url)
access_key, secret_key, token, expiry = _aws_get_sso_credential_details(p, ini)
return AWSCredentials(access_key, secret_key, token; expiry=expiry)
end
end

return nothing
end

"""
dot_aws_config(profile=nothing) -> Union{AWSCredential, Nothing}
Retrieve AWSCredentials for the default or specified profile from the `~/.aws/config` file.
Single sign-on profiles are also valid. If this fails, try to retrieve credentials from
`_aws_get_role()`, otherwise return `nothing`
If this fails, try to retrieve credentials from `_aws_get_role()`, otherwise return
`nothing`.
# Arguments
- `profile`: Specific profile used to get AWSCredentials, default is `nothing`
Expand All @@ -427,17 +464,13 @@ function dot_aws_config(profile=nothing)

credential_process = get(settings, "credential_process", nothing)
access_key = get(settings, "aws_access_key_id", nothing)
sso_start_url = get(settings, "sso_start_url", nothing)

if !isnothing(credential_process)
cmd = Cmd(Base.shell_split(credential_process))
return external_process_credentials(cmd)
elseif !isnothing(access_key)
access_key, secret_key, token = _aws_get_credential_details(p, ini)
return AWSCredentials(access_key, secret_key, token)
elseif !isnothing(sso_start_url)
access_key, secret_key, token, expiry = _aws_get_sso_credential_details(p, ini)
return AWSCredentials(access_key, secret_key, token; expiry=expiry)
else
return _aws_get_role(p, ini)
end
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/credentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function _aws_get_role(role::AbstractString, ini::Inifile)
duration_seconds = get(settings, "duration_seconds", nothing)

credentials = nothing
for f in (dot_aws_credentials, dot_aws_config)
for f in (sso_credentials, dot_aws_credentials, dot_aws_config)
credentials = f(source_profile)
credentials === nothing || break
end
Expand Down
Loading

0 comments on commit 8b0f1e8

Please sign in to comment.