Account Linking should include userId in auth url request
When using Account Linking, the authorization url gets passed a state, client_id, and scope. I think it should also receive the userId of the Alexa user making the request. When my user logs in, I would like to store their user/password in my database (the linking credentials will actually be used to login to a 3rd-party site on their behalf). I want to store the user/pass encrypted, but I need to have an encryption key. Since I can't ask the user for their password or anything when using the skill and use that to decrypt, I would like to use the userId passed in the skill request to decrypt the stored data. That way, I can look up their record using the token, and decrypt the stored user/pass using the userId also included in the request. Am I missing something, or is there a better way to do this?
Hi Matt, yes, you are missing something. Your app is responsible for generating the userId and sending it to Alexa service during account linking, not the other way around. It's counterintuitive and it may help you understand better if you realize that during account linking your app acts as the OAuth provider/server and the Alexa service as the OAuth client. Stefan
Yes, I understand how this works. I think you are misunderstanding my request. You see, I do not want the user to login to my system, where they already have a user account. Instead, I want to prompt them for username/password to some OTHER site, which my skill will access. So I need to store their user ID and password in my database. I want to encrypt the stored username/password in my database, in case somehow it is accessed. These private login credentials should not be visible to anyone else, ever. So I need to encrypt them some kind of unique key which can be used to decrypt them. And this unique key must be sent with every request to my skill, along with the token, so I can look up the user's record with the unencrypted token, then decrypt the values using the key. I don't see any other way to have a unique key sent, other than the userId of the user. This is the key I want to use to "unlock" the user record. Anyone gaining access to my database would find randomly-generated tokens and encrypted username/passwords. They would not be able to make any sense of it without the Amazon-supplied userId to decrypt it. I hope that clarifies what I am trying to do. Again, I understand that I generate the token and send it back. My main goal is to encrypt and store information entered by the user during this stage, and it have it be retrievable and unencryptable during subsequent skill requests.
Got it. What you're trying to do is orthogonal to the Alexa account linking and is similar to what we're doing for the FreeBusy Scheduling Buddy skill so enable it for your account to see how we're doing account linking. This is the part I disagree with from your analysis: [i]"And this unique key must be sent with every request to my skill, along with the token"[/i]. The token is your unique identifier. You store the encryption key in your own db and you use the token as a unique identifier to get to the key. The token doesn't have to be predictable or related to identifible user informatio. You can generate GUIDs for tokens so if someone gets a hold of your db it's not obvious which key belongs to which identifiable user (presuming here that there's no other table that maps these GUIDs to user identifiable information in your db). Might be helpful to read our credential encryption solution https://freebusy.io/how-it-works#technical Cheers, Stefan
Okay, that link helped. I see that you are generating a secure key and storing it on your server itself. In my case, I want to use AWS Lambda, so I don't have the option of storing a secure key. I have considered generating a random key and storing it in the Lambda code itself and in my personal vault, but that is really not much more secure anyway. My hope was that token+userId was a sufficiently "random" key. That way, each user record would be stored with the unencrypted Alexa userId. When the skill request came into Lambda, I would lookup the user record by userId, then combine token+userId to decrypt the stored username/pass. Unfortunately, I need the userId in the initial authorization stage to store the record in the DB, and it's not supplied in the request. All I have is the token which I generate. Any other thoughts on how to securely store user credentials in an AWS+Lambda+DynamoDB environment?