cognitect-labs / aws-api

AWS, data driven
Apache License 2.0
730 stars 100 forks source link

Support AWS SSO Credentials Provider #182

Open Chouffe opened 3 years ago

Chouffe commented 3 years ago

Dependencies

{:deps {com.cognitect.aws/api       {:mvn/version "0.8.505"}}

Description

AWS SSO sessions are not supported currently by the library. An implementation of the CredentialsProvider for AWS SSO would solve this issue.

One of the current workarounds is to leverage a library like yawsso which syncs the temporary session credentials to the ~/.aws/credentials file.

References

The aws-sdk-java added support for SSO credentials provider via this PR. Here is also a GH issue reporting the issue.

jeroenvandijk commented 3 years ago

@Chouffe Another possible workaround is implementing credential_process yourself (see #73) in combination with a script like this

lukaszkorecki commented 3 years ago

@Chouffe here's the credential provider we're using for SSO profiles: https://gist.github.com/lukaszkorecki/120008f7832e23702e94f4205b8e3df5#file-sso-profile-clj

kirked commented 2 years ago

We use https://github.com/synfinatic/aws-sso-cli to do the actual credentialing.

Currently, to fetch jars from our S3-private repo, we have to issue something like this:

aws-sso exec -p <PROFILE_NAME> -- clj -T:build uber

and our ~/.aws/config has profile entries that look like this:

[profile <PROFILE_NAME>]
credential_process = /Users/me/bin/aws-sso --url-action=open --sso=<SSO_INSTANCE> process --arn <ROLE_ARN>

It then does the credentialing necessary (which is cached by aws cli) and sets the environment variables and runs your command for you.

It'd be nice to have an SSO credentials provider that was aware of this mechanism and made use of it automatically.

metasoarous commented 11 months ago

Hi there. Just wanted to flag that since AWS renamed SSO to IAM Identity Center last year, they seem to be steering users towards authenticating humans via this system versus ye old IAM users, which are recommended primarily for non-human programmatic access (servers, github actions, etc). Given that, turn key support for SSO would seem to be increasingly valuable for this API, since it typically makes more sense to use the Identity Center users for auth when (e.g.) running scripts on dev machines.

Thanks for all your work!

ferdinand-beyer commented 2 months ago

We use version 2 of the AWS SDK and small wrapper around the ProfileCredentialsProvider:

deps.edn

        software.amazon.awssdk/sso          {:mvn/version "2.27.7"}
        software.amazon.awssdk/ssooidc      {:mvn/version "2.27.7"}

provider:

(ns example
  (:require [cognitect.aws.client.api :as aws]
            [cognitect.aws.credentials :as credentials]
            [cognitect.aws.util :as util])
  (:import [java.time Instant]
           [software.amazon.awssdk.auth.credentials AwsSessionCredentials ProfileCredentialsProvider]))

(defn default-profile-name []
  (or (util/getenv "AWS_PROFILE")
      (util/getProperty "aws.profile")
      "default"))

(defn- aws-session-credentials [^AwsSessionCredentials credentials]
  (let [^Instant expiry (.. credentials (expirationTime) (orElse nil))]
    (cond-> {:aws/access-key-id (.accessKeyId credentials)
             :aws/secret-access-key (.secretAccessKey credentials)
             :aws/session-token (.sessionToken credentials)}
      (some? expiry) (assoc ::credentials/ttl (- (.getEpochSecond expiry)
                                                 (.. (Instant/now) (getEpochSecond)))))))

(defn sso-profile-credentials-provider
  "A version of `profile-credentials-provider` that supports SSO."
  ([]
   (sso-profile-credentials-provider (default-profile-name)))
  ([profile-name]
   (credentials/cached-credentials-with-auto-refresh
    (let [pcp (ProfileCredentialsProvider/create profile-name)]
      (reify credentials/CredentialsProvider
        (fetch [_]
          (let [credentials (.resolveCredentials pcp)]
            (when (instance? AwsSessionCredentials credentials)
              (aws-session-credentials credentials)))))))))