5.2 KiB
Google access through a credential broker
A credential broker is a server of yours that holds the Google service-account keys, the Cloud project facts and the
Play permission grants. With one configured, storebound keeps no Google key on the machine: it asks the broker for a
short-lived access token for each Google API call and reads the package's Play permissions from it before a command
writes anything. The local key (PLAY_SERVICE_ACCOUNT) keeps working and is the fallback.
Setup
~/.storebound/broker.json:
{
"url": "https://broker.example.com",
"apiKeyFile": "~/.storebound/broker.key",
"account": "play-publisher@example.com"
}
url: the broker's base URL. Onlyhttps://(plainhttp://only forlocalhost, a local test broker).apiKeyFile: a file with one scoped API key on one line, with the scopesgoogle:readandgoogle:token. On macOS and Linux it must bechmod 600: storebound refuses a key file that the group or others can read. Default:broker.keynext tobroker.json. The key is never printed, never written into a config or a log.account(optional): the service account e-mail the broker mints tokens for. A credential profile or the project can name its own withPLAY_SERVICE_ACCOUNT_EMAIL(env,~/.storebound/credentials/<profile>.json,.storebound/credentials.json); without either, theclient_emailof a local key is used, and for Play commands the account the broker names for the package.
Overrides: STOREBOUND_BROKER_URL, STOREBOUND_BROKER_KEY_FILE (env wins over the file), STOREBOUND_BROKER_CONFIG
(another broker.json). Off: STOREBOUND_BROKER=off for one run, "broker": false in a credential profile (that profile
keeps its key file), or env STOREBOUND_PROFILE_<NAME>_BROKER=off.
What storebound calls
| call | when |
|---|---|
POST /api/google/token { "account", "scopes": ["androidpublisher"] } -> { "accessToken", "expiresAt" } |
before Google calls. Kept in memory until 5 minutes before expiresAt; parallel calls share one request |
GET /api/google/play/<package>/storebound |
storebound validate, the preflight of Play write commands, apps check and the desktop's Accounts view |
Scopes: androidpublisher for the Play Developer API, cloud-platform.read-only for Play statistics exports and Play
Games configuration reads. The broker hands out no scope for the Play Developer Reporting API (vitals, the app list of
apps list) or for Play Games configuration writes: those use the local key, and say so when there is none.
Fallback and failures
- Broker not configured: the local key, as before.
- Broker not answering (network error, timeout, 5xx) or not knowing the account (400 / 404 on a token): the local key, with one warning per run. No local key: the error names the broker.
- Broker refusing the API key (401 / 403): storebound stops with "the key lacks google:token" and does not retry or fall back. Give the key its scopes on the broker.
- A package the broker does not know (404 on
/storebound): a warning to register it there. It is not a missing Play access; the command still runs and Google answers for itself.
Permission checks
The broker's answer lists the service account's Play permissions for the package and the APIs enabled in its Cloud projects. Before a Play command writes, storebound compares them with what the command needs and stops before any Play call, naming the exact permission or API and the link to fix it:
| work | Play permission | commands |
|---|---|---|
| uploads, releases, rollouts | CAN_MANAGE_TRACK_APKS |
play upload, play release, play rollout, play share |
| store listing and images | CAN_MANAGE_PUBLIC_LISTING |
play listing, play images |
| products and subscriptions | CAN_MANAGE_ORDERS |
play products, play subscriptions |
| Data safety, app content | CAN_MANAGE_APP_CONTENT |
play data-safety |
| review replies | CAN_REPLY_TO_REVIEWS |
(listed in the checks) |
| Play Games Services | API gamesconfiguration.googleapis.com |
play games |
Every Play call also needs androidpublisher.googleapis.com enabled. A dry run (--dry) and reads only warn.
storebound validate reports the same gaps as blockers, the permissions and APIs the broker lists, and SDK config
files (google-services.json, GoogleService-Info.plist) the broker reports as drifted or whose sha256 differs from
the repo's copy.
When Google itself answers 403 SERVICE_DISABLED or PERMISSION_DENIED, the error names the API (with its enable
link) or the missing app access (with the Users and permissions link), adds what the broker lists for the package, and
is never retried.
Where it shows
storebound doctor:Play: tokens from the credential broker <url> for p***@...(or the local key, and why the broker is not usable).--json:play.sourceis"broker"or"file".storebound accounts: a "Play via" column (credential broker / key file) per profile.storebound validate --json(and MCPvalidate):credentials.play.source.storebound apps check --store play --jsonand the desktop's Accounts view:sourceand, per Play app of the machine, the permissions and APIs the broker lists and what is missing.