Proper place to set "secret" environment variables


Am a little confused about where I should set private environment variables, such as our Facebook App ID/secret or Heroku server endpoints, which we want to vary by workflow.

My current setup is I have a workflow that runs when I push to our development branch and a different workflow that runs when I push to our production branch. I’ve defined keys for Facebook ID/secret and Heroku endpoints, and whose values vary based upon the workflow.

My question is - is this the proper place to define these variables? If so, then what types of variables would be defined in the Secret tab? If I should be defining the above variables in the Secret tab, then how can I define them so that they vary based upon which workflow is running?

Thanks for the help!


Hi @clee46,
thanks for the question!

You should define your secret variables on Secrets tab (in Workflow Editor).
These variables are not part of your bitrise config (bitrise.yml), instead they are stored separately.
For security reasons these variables are not applied in case of pull request, to avoid malicious access to secret infos.

The secrets env vars are config level variables, so you can not define it per workflow. Possible workaround is to prefix/suffix the variable names based on in which workflow you want to use them.

Read more in devcenter:


Thanks for your reply!

A little confused about workflow env vars. Can the client access these?

Below is my current idea, but it all depends on whether the client can access the workflow env vars. If it cannot, is there no way that a client can “know” which environment variables to use based upon which branch it was built from?

  1. Set all the secret env vars for all environments in the Secrets tab, using prefixes to distinguish which environment. (i.e. DEV_FACEBOOK_ID, PROD_FACEBOOK_ID, etc.).
  2. We define a workflow env var “CLIENT_ENV” whose value is “development” for the development workflow and “production” for the production workflow, etc…
  3. If I push to the development branch, Bitrise triggers a build using our development workflow.
  4. Based upon the value of “CLIENT_ENV”, the client then programmatically determines which secret env vars to use. For example, if the environment is development, it knows to use DEV_FACEBOOK_ID, DEV_FACEBOOK_SECRET, etc.


Hi @clee46,

That should work, if you don’t need those secrets in pull request builds. If you do need those in PR builds too, then right now the best solution is to use Generic File Storage, as those are available for PR builds too.

There’s a related feature request to let you control which secret env vars and files can be accessed in PR builds and which aren’t, if you want to feel free to vote & comment here:

Can you please clarify this a bit? What do you mean by Client?
In short, on all the admins but only the admins of the app can access and modify Secrets. In the build the secrets are available (except in PR builds), regardless of who started the build.

Last but not least, I think we don’t have a #feature-request for per-workflow secrets but I think that would be quite useful too, so feel free to create one at :wink:


Sorry, by client, I meant the app itself. So, let me step back and outline the entire deployment strategy we hope to achieve:

  1. We have a single repository containing a Xamarin project with both iOS and Android apps.
  2. The repository has a development branch, a QA branch and a production branch.
  3. Each of these client branches is linked to a different server/DB, Facebook app, etc. so that when a change to one of these branches triggers a new build, the resulting app “knows” to connect to its respective server/DB or Facebook app.

The proposal in my last post should be able to achieve this, but it all hinges on whether the app can access Workflow Environment Variables. Can you confirm that this is the case?

I read through your docs on Generic File Storage, but it seems overly complex way to store a Facebook APP ID/secret or a Heroku server endpoint. Is this the recommended method? If so, can you point me towards a tutorial or propose how I would use Generic File Storage in this use case?


Well, sure it (build steps and tools) can during the build. If you want to include a secret in a deployable app (ipa / apk) then you’ll have to include that secret in the app, e.g. by writing it into a file which is compiled into the app - that’s why I suggested Generic File Storage. With that you can define these values in e.g. a JSON file which you embed / compile into the app, and so the deployed app can read those.


I’d also suggest you to ask this another way: if you have to do this locally on your Mac, how do you handle it there?

That’s (usually) exactly how you can on too, just in an automated way :slight_smile:


OK, I think I get it!

So, if I understand correctly, I would need to create and upload a separate JSON file for each set of env variables. For example, a dev_vars.json, qa_vars.json, prod_vars.json each with their respective secrets.

Each json has its own unique download URL, so I can then use each download URL in its respective workflows. For example, development workflow would be configured to download dev_vars.json.

So end-to-end: a change to development branch triggers development workflow which downloads development json with all the secrets needed to connect to development server/DB/facebook app, etc.

I guess the last piece of the puzzle - can you point me to where in the workflow should the JSON be downloaded and what step allows me to do that?

Thanks for all your help and for the quick replies! :slightly_smiling_face:


There are quite a few possibilities, you can find a couple of examples here:

About where: most likely after the Git Clone step, as that’s the point where your source code is retrieved, and before the build step you use as that’s where you’ll want to use/have that file available :wink:

Any time :wink:


I’m looking at using the Secret Vars, but I was very surprised to see that they are not masked and any user with Workflow edit access can see the secret value. I expected these to be more like Octopus where once the value is entered, you cannot see it again. Can this please be tightened up by masking the value so it is not readable once entered?
Currently I believe this violates our security policy so I’m not able to use a few steps that I’d really like to use.



The thing about this is that those values will be available in the build anyway, so if someone has access to the editor they can easily print that by modifying the workflow and starting a build which either prints the value or just sends it to somewhere.

That said, for the web UI there’s a related #feature-request if you’re interested @benrnz-sv :