nervous-systems / eulalie

Asynchronous AWS client for Clojure & Clojurescript/Node
The Unlicense
86 stars 10 forks source link

Using IAM credentials causes :invalid-client-token-id error #14

Closed joelittlejohn closed 9 years ago

joelittlejohn commented 9 years ago

Hi @moea I see that things have changed quite a bit in eulalie regarding expiring credentials. Originally we referred to nervous-systems/fink-nottle#4 and used the function suggested there, but we were finding that that our service was becoming broken after a few hours when credentials expired. It now looks like eulalie.creds/iam is the correct way to build expiring credentials, however on switching to this method we've found that we can no longer make successful requests.

Using fink-nottle 0.4.2 we're declaring our creds like this:

(def creds (-> (eulalie.creds/iam) (assoc :endpoint endpoint)))

However any attempt to receive a message from SQS results in the following exception:

Exception in thread "main" clojure.lang.ExceptionInfo: invalid-client-token-id: The security token included in the request is invalid. {:type :invalid-client-token-id, :message "The security token included in the request is invalid."}
    at clojure.core$ex_info.invoke(core.clj:4593)
    at eulalie.support$error__GT_throwable.invoke(support.cljc:17)
    at eulalie.support$issue_request_BANG_$fn__15759$state_machine__9420__auto____15760$fn__15762.invoke(support.cljc:29)
    at eulalie.support$issue_request_BANG_$fn__15759$state_machine__9420__auto____15760.invoke(support.cljc:22)

Using a repl running on this instance I've tried to replicate what eulalie will be doing by running the following:

(<!! (eulalie.creds/creds->credentials (iam)))

when I do this I see what looks like a valid set of credentials (I've truncated the sensitive values):

{:eulalie/type :expiring,
 :current
 #<Atom@4ffe91e4:
   {:code "Success",
    :last-updated "2015-08-14T08:53:32Z",
    :type "AWS-HMAC",
    :token
    "AQoDYXdzEOr//////////wEa0AM58//iKa1kwziRDN...",
    :expiration 1439564263000,
    :access-key "AS...",
    :secret-key "lE..."}>,
 :refresh
 #object[eulalie.instance_data$default_iam_credentials_BANG_ 0x70d2bad7 "eulalie.instance_data$default_iam_credentials_BANG_@70d2bad7"],
 :threshold 300000}

So I'm wondering if there is something wrong with the way that eulalie is attempting to sign requests.

moea commented 9 years ago

Thanks for the detailed report. There was previously an undocumented mechanism for refreshing IAM credentials, but it was brittle. I had another go at it for 0.6.0.

As you pointed it, It looks like credentials are incorrectly resolved in 0.6.0, leading to requests being signed with empty credentials. creds->credentials was intended to dereference :current.

I just pushed 0.6.1-SNAPSHOT, which ought to fix this - and seems to, in testing. Please let me know if this resolves your issue, and I'll promote the snapshot.

joelittlejohn commented 9 years ago

Thanks for looking at this so quickly. Apologies for the slow response, I've been busy with other things this afternoon but I'm deploying the new eulalie snapshot now. Will update you with the results :)

joelittlejohn commented 9 years ago

Fix appears to be working well here :+1: