Create a dedicated service account for the pipeline, invite it to Play Console with only the release permissions your lanes need, and leave out the right to release to production unless a protected job needs it. Store its JSON key in a secret manager and test it before the first real upload.
What the platform says
Google's Play Developer API guide says that in most cases you should use a service account, and that service accounts must be used in a secure environment such as your server. It adds that the credentials must be securely managed so they are not revealed to anyone not authorized to use the API. OAuth clients are for acting on behalf of an individual user, which is not what unattended CI needs.
Google also notes you no longer need to link your developer account to a Cloud project to use the API.
Permissions worth knowing
Play Console permissions are granular. Two of the release permissions matter most:
| Permission | What it allows |
|---|---|
| Release to production, exclude devices, and use Play App Signing | Create, edit and roll out production releases, unpublish and republish apps |
| Release apps to testing tracks | Upload drafts, create and roll out releases to testing tracks, but it does not allow publishing to production |
That second line is the useful one for CI. A pipeline that only needs to push a build to internal testing does not need production rights.
The fastlane supply documentation recommends granting Admin for convenience, but says you may select permissions manually and leave out some release permissions such as release to production. Treat that as a hint that the broad grant is a convenience choice, not a requirement.
Setup steps
- Create or choose a Google Cloud project and enable the Google Play Developer API.
- Create a service account in the Cloud console and generate a JSON key.
- In Play Console, invite the service account email as a user and select only the permissions needed for the lane.
- Put the JSON key in your secret manager. Do not commit it.
- Validate it with the fastlane check action, which tests the connection with the downloaded key, before wiring it into a release lane.
- Upload to an internal or closed testing track first and promote by a separate, approved step.
Why a separate production path helps
If one service account can do everything, any job that can read its key can ship to every user. Splitting the roles, a testing-track account for every branch build and a more privileged one reachable only from a protected release job, means a compromised pull request build can at worst reach testers. Our post on whether CI should release to production expands on that split.
Protect the key file
A JSON service account key is a long-lived credential. Rotate it on a schedule, delete unused keys in the Cloud console, and keep it out of caches and artifacts. Also be careful with logs: masking tools match exact strings, and a whole JSON blob is a poor fit, as we explain in why masking misses JSON keys.
Where Safeguard fits
Safeguard does not manage Play credentials. It scans dependencies, supports reachability analysis, and enforces policy gates on releases. Run a free scan.
Quick check
Does the service account need Admin rights?
Not necessarily. Select only the permissions the lane needs, and leave out production release rights unless a protected job requires them.
Why not use an OAuth client?
OAuth clients act on behalf of a person. Google recommends service accounts for secure server access, which is what CI is.
Sources
- Google Play Developer API: getting started
- Play Console permissions help
- fastlane docs: upload_to_play_store
Last reviewed: 19 October 2026.