Two-factor authentication for Apple ID / iTunes Connect TestFlight deploy

Hi,

my Apple account has Two-factor authentication enabled and, I have some issues setting up the fastlane with bitrise.io.

On my local environment everything works fine because I was able to type the apple code received on my phone.

I followed the instruction from here fastlane/spaceship at master · fastlane/fastlane · GitHub but I didn’t had any success.

The error is:

I set the FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD and FASTLANE_SESSION in the Secret Environment Variables section but seams it doesn’t work.

Any suggestions?

1 Like

Hi,

In general you have two solutions for 2FA with iTunes Connect TestFlight:

  1. Create a CI/bot/“machine” user on iTunes Connect which does not have 2FA enabled, and will only be used for automations, e.g. to use it on bitrise.io. This is probably the easiest solution, as once you create the user it’ll just work, no future changes are required. Simply just register a new iTunes Connect account, just like a regular account, the way you registered your own iTC account, and simply never use it for development / login, only for integrations.
  2. Follow the official instructions (if any) of the tool you use to do the deploy.

In this case specifically / what the reported issue might be

In this case you can see the fastlane / spaceship guide link in the log: https://github.com/fastlane/fastlane/tree/master/spaceship#2-step-verification

Now, the guide here states that you can run a command locally, and you should provide the output of the command as an environment variable. For environment variables you can use App Env Vars and Secret Env Vars - from the screenshot it seems you used Secret Env Vars. That’s OK, but as you can see in the orange notice Secret Env Vars are not available in pull request builds. This is one thing what might cause the issue for you.

Another thing is, on the screenshot you did set FASTLANE_SESSION as mentioned in the guide, but you should also make sure to turn off the Replace variables in input? option of that env var, so that Bitrise (CLI) won’t treat the $ characters in the value as env var references.

Last but not least, and I’d say in your case this is the most likely cause, you should replace the \n characters in the value printed by fastlane spaceauth, because if you do provide \n there, it will be encoded properly to represent the \ and the n characters, while what you can see in the fastlane docs is for bash, where \n means newline. To do this simply replace all the \n with an actual newline (hit enter/return) in the env var value on bitrise.io. That will be the same as if you’d print \n in bash / the way the fastlane docs expose the env var.

1 Like

Ohh and of course, let us know how it goes, and feel free to ask if you’d have any questions!

Hello, this is the same problem that i’ve.

yet if i do as you wrote over here (i replace the \n with enters etc)

Error loading session from environment
Make sure to pass the session in a valid format

is there some additional trick for that?
I do it as following

- !ruby/object:HTTP::Cookie
  name: DExxxxx
  xxxx
  xxxx xx
  xxxxx xxx

Can you please copy paste the related parts of the bitrise.yml? Where you specify this value. Or do you use secret env vars for it?

Feel free to remove sensitive infos, but the actual env def syntax would help a lot.

    FASTLANE_SESSION: "- !ruby/object:HTTP::Cookie\n  name: COOKIENAME\n
  \ value: A/VALUE/IS/HERE\n
  \ domain: idmsa.apple.com\n  for_domain: true\n  path: \"/\"\n  secure: true\n
  \ httponly: true\n  expires: \n  max_age: 25920\n00\n  created_at: 2017-05-02
  18:01:03.754319000 +02:00\n  accessed_at: 2017-05-02 19:42:09.357338000 +02:00"

I’m running in circles and can’t quite figure out the reason. I read like half a github about it, and in the end i figured out that it is somehow related to the Bitrise and how it interprets the cookie itself rather than a problem with Fastlane

Bitrise does not interpret anything in the env vars, except the $ANOTHER_ENV_VAR references if there’s any and the “expand” option is enabled. Other than that it’s just an env var, like any other.

It’s the same as if you’d run

export MY_KEY="the value here"

in your Terminal / in Bash.

Sorry, I wasn’t precise enough - could you please share the “layout” like this:

app:
  envs:
  - MY_KEY: "the value"

So that we can see the whole “definition” / “layout” of the env config.

---
format_version: 1.3.1
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
app:
  envs:
  - opts:
      is_expand: false
    FASTLANE_WORK_DIR: "."
  - opts:
      is_expand: false
    FASTLANE_LANE: beta
  - opts:
      is_expand: false
    FASTLANE_PLATFORM_IOS: ios
  - opts:
      is_expand: false
    FASTLANE_PLATFORM_ANDROID: android
  - opts:
      is_expand: false
    FASTLANE_SESSION: "---\n- !ruby/object:HTTP::Cookie\n name: COOKIENAME\n
      value: COOKIE/2VALUE\n
      domain: idmsa.apple.com\n for_domain: true\n path: \"/\"\n secure: true\n httponly:
      true\n expires: \n max_age: 2592000\n created_at: 2017-05-02 18:01:03.754319000
      +02:00\n  accessed_at: 2017-05-02 19:42:09.357338000 +02:00"
trigger_map:
- push_branch: master
  workflow: primary
- pull_request_source_branch: "*"
  workflow: primary
  pull_request_target_branch: master
workflows:
  primary:
    steps:
    - activate-ssh-key:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone: {}
    - fastlane:
        title: iOS Fastlane
        inputs:
        - lane: "$FASTLANE_PLATFORM_IOS $FASTLANE_LANE"
        - work_dir: "$FASTLANE_WORK_DIR"
    - npm:
        title: npm install
        inputs:
        - command: install
    - install-react-native:
        inputs:
        - version: ''
        - npm_options: ''
    - react-native-bundle:
        title: iOS RN
        inputs:
        - assetRoots: ''
        - options: ''
        - url: ''
        - root: ''
    - npm:
        title: npm test
        inputs:
        - command: run test
    - react-native-bundle:
        title: Android RN
        inputs:
        - platform: android
        - assetRoots: ''
        - options: ''
        - url: ''
        - root: ''
    - npm@0.9.0:
        title: npm increment_build
        inputs:
        - command: run increment_version
    - fastlane:
        title: Android Fastlane
        inputs:
        - lane: "$FASTLANE_PLATFORM_ANDROID $FASTLANE_LANE"
        - work_dir: "$FASTLANE_WORK_DIR"
    - deploy-to-bitrise-io@1.2.9: {}

I think you should report this on the fastlane issue tracker, as the definition seems to be good.

The FASTLANE_SESSION: is essentially the same as

export FASTLANE_SESSION="---\n- !ruby/object:HTTP::Cookie\n name: COOKIENAME\nvalue: COOKIE/2VALUE\ndomain: idmsa.apple.com\n for_domain: true\n path: \"/\"\n secure: true\n httponly: true\n expires: \n max_age: 2592000\n created_at: 2017-05-02 18:01:03.754319000 +02:00\n  accessed_at: 2017-05-02 19:42:09.357338000 +02:00"

This might also help: you can use the Bitrise CLI to run debug builds locally - https://www.bitrise.io/cli

Might make things easier/faster to debug.

ok, well thanks for help anyway. this Bitrise CLI will be a big help for me for future anyway (cause pushing always to git repo is quite a pain if i do some changes locally to the pipeline or code).
If i won’t figure out the problem (maybe i screwed up the logging in in spaceauth) then I will ask guys on fastlane what might be the reason.

1 Like

Sure, and if we can help with anything please let us know!

I’d also advise you to try to generate & set the value again - a quick tip: if you set the value directly in bitrise.yml mode then you don’t have to modify it, \n should remain \n, you only have to replace \n if you input the value on the Web UI / in the Editor. Simply just generate a new value and replace the value in bitrise.yml with the new one basically:

  - opts:
      is_expand: false
    FASTLANE_SESSION: "PASTE THE VALUE HERE"

Setting it through the web ui should work as well of course, but in that case you’ll have to replace the \n chars with actual newlines, which will be serialized as \n when written into YML.

I tried to generate new one and right now I get the message
"Two Factor Authentication for account ‘xxx@xxx.com’ is enabled
Your session cookie has been expired.
Please enter the 6 digit code: "

Which is 100% fastlane related. Though sadly no idea how to solve that one, but now I’m a one step closer.

CLI is quite a good feature

It seems signing in on appleid.apple.com might help - sigh: authentication.failed / Your session has expired. Please log in. ¡ Issue #4157 ¡ fastlane/fastlane ¡ GitHub

I saw this previously. but sadly nothing happens after that.

We just discovered one more edge case when 2FA / the Fastlane Session won’t work: our servers are running in US and it seems that the (fastlane / apple) session is location aware. This means that it might not work if you’re not in the same “region” as where it’s used. It should work if you’re in the US where our runners are, but otherwise if you generate a session on your Mac it might not work on our US build machines.

Related fastlane issue & discussion:

https://github.com/fastlane/fastlane/issues/9518

1 Like

I am getting
there is no web session to update
I ran 36 builds with trial and errors… please someone help me!

Hi @fabrygio,

Did you try the things mentioned before in this thread?
If you did, I’d suggest you to contact the fastlane guys as our step just runs the relevant fastlane tool - you can see the exact command the step runs in the step’s log.