skip to content

In EAS Build, how do remote (managed) credentials and local credentials from credentials.json differ, and when would you choose local?

level: middleimportance: should knowfreq 35%

answer

  1. credentialsSource: remote or local
  2. remote: stored encrypted on EAS
  3. local: credentials.json paths plus passwords
  4. uploaded per job, then discarded
  5. eas credentials syncs both ways

basics

~20 s

Remote credentials are generated or uploaded once and stored encrypted on EAS servers; local credentials are read from a git-ignored credentials.json on every build, uploaded with the job and discarded afterwards. A profile picks with credentialsSource.

solid answer

~50 s

A build profile's `credentialsSource` chooses. With `"remote"`, the default, the keystore or the iOS certificate and profile live on EAS servers, encrypted, and every build and every authorized teammate uses them; EAS can generate them and keep ad hoc profiles current. With `"local"`, EAS CLI reads `credentials.json` at the project root: for Android `keystore.keystorePath`, `keystorePassword`, `keyAlias` and `keyPassword`; for iOS `provisioningProfilePath` and `distributionCertificate.path` and `password`, or one such object per Xcode target. Those files are uploaded with each build job and discarded when it finishes, so EAS never keeps them. I would choose local when policy says signing keys must stay in the company's own secret store, or for a store EAS should not manage, such as a separate Amazon Appstore profile. Local means you own git-ignoring, distributing and rotating the files. `eas credentials` moves credentials between the two, in both directions.

code

json · 11 lines
json
{
  "build": {
    "production": {
      "android": { "credentialsSource": "remote" }
    },
    "amazon-production": {
      "extends": "production",
      "android": { "credentialsSource": "local" }
    }
  }
}

go deeper

for a junior

Recall that credentialsSource is remote by default, and that local means a git-ignored credentials.json with paths and passwords.

for a middle

Explain the credentials.json fields, multi-target iOS, what EAS keeps in each mode, and how eas credentials downloads or uploads between them.

for a senior

Show when local is justified, key custody policy or a separate store, and what it costs: distributing files to CI, rotation and backups become yours.

for a principal

Frame the choice as custody: decide whether a vendor may hold your release keys, and make that an explicit policy with an owner rather than a per-profile accident.

## One switch, two custody models Every EAS build profile has a `credentialsSource` key with two values: - **`"remote"`** (the default): credentials are stored on EAS servers and resolved there for every build. - **`"local"`**: credentials are read from a `credentials.json` file in the project for every build. The choice is per profile, so one project can mix them, for example a `google-production` profile with remote credentials and an `amazon-production` profile with local ones. ## Remote (managed) credentials - EAS CLI can **generate** them on the first `eas build`: a new Android keystore, or an iOS distribution certificate and provisioning profile after you sign in to Apple. - You can also **provide** existing files when prompted, or upload them from `credentials.json` later. - They are **encrypted at rest** and with a key management service, and decrypted only in memory on the build worker. - Teammates with sufficient project permissions can build without holding any key files or Apple team access. - EAS can keep derived artifacts current, such as regenerating an ad hoc provisioning profile when devices are added. - Android supports several named keystores per app; the default one is used unless a profile sets `keystoreName`, which is only allowed with remote credentials. ## Local credentials: credentials.json `credentials.json` sits at the project root and holds **paths and passwords**: ```json { "android": { "keystore": { "keystorePath": "android/keystores/release.keystore", "keystorePassword": "KEYSTORE_PASSWORD", "keyAlias": "KEY_ALIAS", "keyPassword": "KEY_PASSWORD" } }, "ios": { "provisioningProfilePath": "ios/certs/profile.mobileprovision", "distributionCertificate": { "path": "ios/certs/dist.p12", "password": "DISTRIBUTION_CERTIFICATE_PASSWORD" } } } ``` - Paths may be relative to the project root or absolute. - `keyPassword` may be omitted; the other Android fields are required. - For a **multi-target** iOS app (a widget, a share extension), `ios` becomes an object keyed by **Xcode target name**, each with its own profile and certificate, because every target has its own bundle identifier. - At build time the files are **uploaded with the job and disposed of** when it completes; EAS does not keep them. - `credentials.json` and every file it points to must be **git-ignored**; the file contains passwords in plain text. ## Side by side | | `remote` | `local` | |---|---|---| | Where keys live between builds | EAS servers, encrypted | Your machines and secret stores | | Can EAS generate them | Yes | No, you create them | | Teammates and CI need the files | No | Yes, at the same paths | | Ad hoc profile refresh by EAS | Yes | No | | Named Android keystores (`keystoreName`) | Yes | Not allowed | | Rotation and backup | EAS stores them; you keep a backup | Entirely yours | ## Moving between them `eas credentials` (or `eas credentials -p android`) has a **credentials.json** menu: 1. **Download credentials from EAS to credentials.json** writes the managed files and passwords locally, for a local build or a backup. Android credentials are usable immediately; iOS ones must also be installed into the keychain and Xcode for a local Xcode build. 2. **Upload credentials from credentials.json to EAS** turns local files into managed ones, the usual first step when bringing existing keys to EAS. Upload is interactive, and if a keystore is already configured EAS CLI asks before overwriting it and saves a backup of the old one first. ## When local is the right call - A security policy requires signing keys to stay in the organization's own vault or hardware, with EAS never storing them. - A separate distribution channel, such as another app store, uses a key that should not live alongside the Play key. - A transition period, while a team verifies that its existing key works on EAS before uploading it. In every other case remote is less work and less risk: fewer copies of the key exist, and nobody has to pass passwords around. Choosing local means owning the distribution of those files to every machine and CI job, which is a secret-management problem in its own right. ## Mistakes to avoid - Committing `credentials.json` or a `.jks` because it was not in `.gitignore`. - Setting `credentialsSource: "local"` on one profile and forgetting that CI must now have the files at identical paths. - Assuming deleting credentials with `eas credentials` revokes them at Apple; it only removes EAS's copy.

  • What does EAS do with the files referenced by credentials.json when a build uses local credentials?
    EAS CLI reads the paths and passwords, uploads the files with the build job so the worker can sign, and the credentials are disposed of when the job completes. EAS keeps no copy, which is the point of local credentials, and also why every machine that starts builds must have the files.
  • How is credentials.json structured for an EAS iOS app with a widget extension?
    The `ios` value becomes an object keyed by Xcode target name, for example the app target and the widget target, each holding its own `provisioningProfilePath` and `distributionCertificate` with `path` and `password`. Each target has its own bundle identifier, so each needs its own profile; the certificate may be shared.

saying these in an interview costs you the question

  • With local credentials, EAS stores the uploaded keystore for later builds.
  • credentials.json is safe to commit because EAS encrypts it.
  • keystoreName can select a keystore from credentials.json.
  • Remote credentials require every teammate to hold the Apple team login.
  • Deleting credentials in eas credentials revokes them at Apple too.