Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Observations on the Fastlane/Spaceship session length #14301

Closed
janpio opened this issue Feb 22, 2019 · 24 comments · Fixed by #14525
Closed

Observations on the Fastlane/Spaceship session length #14301

janpio opened this issue Feb 22, 2019 · 24 comments · Fixed by #14525

Comments

@janpio
Copy link
Member

janpio commented Feb 22, 2019

After the topic how long the FASTLANE_SESSION is valid came up in #14239, @ZonD80 asked:

What if just ping apple after entering 2FA code every N hours to keep session alive? is it an option?

This led to me answering:

@ZonD80 That depends on if they actually extend the session length, and if spaceship correctly handles updating the session cookie. Some testing there would be greatly appreciated!

Fortunately he took the "bait" and replied:

@janpio okay, i'm on it. We will test it on Friday.

and later

@janpio here are some tests:
Spaceship::Portal.login(email, password) - acquires 2FA session cookie and with second login it remains the same - so no cookie is updated after login. However, via browser, apple sends the same cookies, but with another expiration date (+year). I guess we need to change behavior to updating of local session cookies with every login/request.

Upon cookie deletion (removal of file) - it requires new 2FA PIN code, so i guess their "Trust" button is only cookie life extension, because it is not working if i using incognito mode.

I've placed a worker in our system to auth on dev portal every 600 seconds, let's take a look, will it survive till Monday or not.

As this discussion and further observations might not be of interest for all the people in that issue, I created this one where we can continue.

@janpio janpio changed the title Observations on the Fastlane/Spaceship session Observations on the Fastlane/Spaceship session length Feb 22, 2019
@janpio
Copy link
Member Author

janpio commented Feb 22, 2019

Some official information from Apple on how long logins with 2FA should be valid:

Will I need to enter a verification code every time I sign in to my Apple Developer account?

Once two-factor authentication is enabled, you’ll need to enter a verification code every time you sign in, unless you choose to trust the browser, in which case you won’t be asked for a verification code again from that computer for 30 days. You may be asked to re-verify if you reset or change browsers.

via https://developer.apple.com/support/account/authentication/

@zargox

This comment has been minimized.

@fastlane fastlane deleted a comment from LanceMcCarthy Feb 23, 2019
@ZonD80
Copy link

ZonD80 commented Feb 25, 2019

2FA session is still alive after launch on Friday with login every 600 seconds

@janpio
Copy link
Member Author

janpio commented Feb 25, 2019

Awesome, so updating the session cookie might be something to look into. Can you share your setup so we can reproduce this?

@ZonD80
Copy link

ZonD80 commented Feb 25, 2019

How can i share it, what exactly do you need?

@janpio
Copy link
Member Author

janpio commented Feb 25, 2019

I was referring to:

I've placed a worker in our system to auth on dev portal every 600 seconds, let's take a look, will it survive till Monday or not.

What exactly does this do and how?

@ZonD80
Copy link

ZonD80 commented Feb 25, 2019

#!/usr/bin/env ruby

email = "EMAIL"
password = "PASS"

require "spaceship"
require "net/http"

puts "Logging into account #{email} with #{password}"


puts "logging to dev portal"

Spaceship::Portal.login(email, password)


puts "OK"

exit 0

We just set this script to run every 600 seconds in a loop - that's it, it always gave us "OK" after first entering of 2FA code on Friday.

@janpio
Copy link
Member Author

janpio commented Feb 25, 2019

Thanks.

That leaves the question: How is fastlane's session/cookie system different than the website, where you do not need to re-login after x hours/days and not have to keep polling the login method to keep it alive?

(Although this seems to work, it shouldn't be our plan to tell everyone to start pestering Apple with login requests every 600 seconds 🙊 )

@ZonD80
Copy link

ZonD80 commented Feb 25, 2019

OK i have an answer:)

I've tested if further - in fact you only need cookie with name "myacinfo", it can be grabbed from browser session and placed into fastlane cookie file (or otherwise, from fastlane to browser), (ofc if you have same country/IP/subnet) as your CI system (i've tested with ssh -D and proxy in browser).
Apple sends the same cookie with another expiration date.

Technically they should update last access time of this session and keep it valid after 30 days of last access time, otherwise workflow may be broken when session becomes invalid. But, we need to wait for 30 days with active usage of this session to check it out.
So just pinging with this session may be an option...

@ZonD80
Copy link

ZonD80 commented Feb 25, 2019

LOL and you can just keep your myacinfo, change IP to another country - and still be authorised. It's... okay.

@janpio
Copy link
Member Author

janpio commented Feb 25, 2019

I will have to go deep into the code again to be able to verify this, but I thought this was already how it worked. (But maybe not if FASTLANE_SESSION is set - maybe we have to change that behavior to only use the ENV provided session on first usage, then the local file (but I also think this should be how it works already))

@LanceMcCarthy
Copy link

LanceMcCarthy commented Feb 25, 2019

Has anyone just tried to increase the max_age value in the cookie? Right now it looks like it's only set to 1800 seconds, can we spoof this and increase the value to match the value the browsers use?

image

@RacingWang

This comment has been minimized.

@LanceMcCarthy

This comment has been minimized.

@RacingWang

This comment has been minimized.

@mgrebenets
Copy link
Collaborator

mgrebenets commented Apr 3, 2019

I've ran into similar issues recently.

I've noticed that spaceauth outputs 2 cookie objects in the FASTLANE_SESSION variable:
one for apple.com domain with max_age empty and another one for olympus.itunes.apple.com domain with max_age: 1800 (30 min).

If I use this FASTLANE_SESSION value on CI box, then I have to do 2FA every 30 minutes, which is not ideal and spaceship documentation says it should be around 30 days.

Then I looked into ${HOME}/.fastlane/spaceship/<apple-id>/cookie and I can see that is has much more cookie objects in there, actually 4.
The cookie that seems to make all the difference is for domain: idmsa.apple.com and has max_age: 2592000 (30 days).

So what I tried is take contents of ${HOME}/.fastlane/spaceship/<apple-id>/cookie and put it all into FASTLANE_SESSION on CI box.
I can confirm that after 30 minutes since last use the session did not expire and I was able to use pilot command without the need to generate new FASTLANE_SESSION.

The question is why does spaceauth output short version of the cookies that lasts for 30 minutes only?
The cookies created on my dev laptop work on CI box all the same, so is it OK to use it in my CI setup?

@janpio

@janpio
Copy link
Member Author

janpio commented Apr 3, 2019

Nice observation @mgrebenets.

I actually don't really understand what is happening with the cookies, I can just link you to the code that select/keeps them:

itc_cookie_content = Spaceship::Tunes.client.store_cookie
# The only value we actually need is the "DES5c148586daa451e55afb017aa62418f91" cookie
# We're not sure if the key changes
#
# Example:
# name: DES5c148586daa451e55afb017aa62418f91
# value: HSARMTKNSRVTWFlaF/ek8asaa9lymMA0dN8JQ6pY7B3F5kdqTxJvMT19EVEFX8EQudB/uNwBHOHzaa30KYTU/eCP/UF7vGTgxs6PAnlVWKscWssOVHfP2IKWUPaa4Dn+I6ilA7eAFQsiaaVT
cookies = YAML.safe_load(
itc_cookie_content,
[HTTP::Cookie, Time], # classes whitelist
[], # symbols whitelist
true # allow YAML aliases
)
# We remove all the un-needed cookies
cookies.select! do |cookie|
cookie.name.start_with?("myacinfo") || cookie.name == 'dqsid'
end
or the "blame" version of that: https://github.com/fastlane/fastlane/blame/2d8124410943c0c1fdbf7729b339006cb95d343b/spaceship/lib/spaceship/spaceauth_runner.rb#L30-L48 Maybe the PRs behind those changes tell you a bit what was the thinking there.

If including the idmsa.apple.com cookie helps, we can of course adapt that code.

@LanceMcCarthy
Copy link

The idmsa.apple.com cookie for spaceship would be fantastic, it would keep the CI/CD builds that rely on the FASTLANE_SESSION variable (i.e. Azure DevOps) at the same valid timeframe to the 30 day expectation.

Nice catch @mgrebenets

@janpio
Copy link
Member Author

janpio commented Apr 4, 2019

If that is the case, a PR for spaceauth would be very welcome - which then could also be tested by more people before rolling this out to all users.

@mgrebenets
Copy link
Collaborator

mgrebenets commented Apr 4, 2019

So I'd just have to figure out what's the "needed" cookie.

The code is this:

      # We remove all the un-needed cookies
      cookies.select! do |cookie|
        cookie.name.start_with?("myacinfo") || cookie.name == 'dqsid'
      end

The cookie that has 30 days expiration day doesn't have a clean name:

name: DES5d9905bb34aa91d4867f38ebd3b2664d1

It starts with "DES" so it probably has something to do with [DES] (https://en.wikipedia.org/wiki/Data_Encryption_Standard) 🤷‍♂️ .
If this cookie always starts with "DES", it wouldn't be difficult change to do.

Could anyone else confirm that they also have a cookie names like "DES...." in their ~/.fastlane/spaceship/<apple-id>/cookie after running fastlane spaceauth -u <apple-id>?
Max age of that cookie should be 30 days (max_age: 2592000)

@mgrebenets
Copy link
Collaborator

I can confirm that adding just that one extra "DES" cookie for idmsa.apple.com domain works fine with FASTLANE_SESSION my setup.

The question I still got is how to pick that one cookie from all cookies.
If DES prefix is something that identifies the cookie in all cases, then that could be the fix.
Unless Apple later changes that prefix.
Another option is to look for cookie by "idmsa.apple.com" domain parameter and pick the one that has non-empty (and largest) max_age value...

Of course, there's always of option of just using all cookies, which increases the size of env variable but is more future proof.

@mgrebenets
Copy link
Collaborator

Oh, and the comment in the same file:

      # The only value we actually need is the "DES5c148586daa451e55afb017aa62418f91" cookie
      # We're not sure if the key changes

so we do need that one and it gets filtered out :)

@janpio
Copy link
Member Author

janpio commented Apr 5, 2019

Yeah, that comment confused me as well - but the blame/history of the file might tell you a bit if that was just forgotten when something else was changed or if it is something else. Pretty confusing.

@ZonD80
Copy link

ZonD80 commented Apr 12, 2019

Looks like they have limited session to one day.
But, here is solution (thanks to stackoverflow):

https://apple.stackexchange.com/questions/336842/get-two-factor-authentication-code-from-terminal

#! /usr/bin/env osascript
tell application "System Events"
    if name of every process contains "FollowUpUI" then
        tell window 1 of process "FollowUpUI"
            click button "Allow"
            delay 2
            set code to value of static text 1 of group 1
            log (code)
            click button "Done"
        end tell
    else
        log ("Couldn't find 2FA window")
    end if
end tell
return

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants