Trust and operations
Credential custody
Where store credentials live, what the application database holds, and why authenticated calls execute outside it.
A Google Play service-account key can read your monetization catalogue and, with the right grants, change your prices. It is treated accordingly.
The application never holds the key
Credentials live in a separate credential vault running as its own isolated worker with its own storage and its own authorization.
The application database holds an opaque random handle and a key version. Not the key. Not an encrypted copy of the key. Not a deterministic reference that could be recomputed from workspace or connection identifiers.
The service-account email is transient — used at the moment it is needed, not retained.
Authenticated calls execute inside the vault
The application does not fetch a credential and then call Google. It asks the vault to perform a specific, named operation, and the vault mints the token and makes the call.
A compromise of the application runtime therefore yields no store credential. It yields the ability to request operations the vault already allows — which is why the allowlist is narrow.
The operation allowlist
The vault accepts only the exact request shapes listed in Google Play. Anything else is refused at the boundary with "Google operation is not allowed."
The allowlist checks the origin, the path prefix, the segment structure, the HTTP method, the package-name format, identifier safety, and the body size. Query parameters are restricted to pageSize and pageToken. A GET carrying a body is rejected.
Encryption
Credentials are encrypted with AES-GCM using additional authenticated data bound to the tenant and connection. A ciphertext lifted from one connection cannot be decrypted in the context of another — the binding is part of what is authenticated, not metadata beside it.
Each credential records the wrapping-key version it was sealed with, and the version is written back after a re-wrap so rotation state is never inferred.
Maintenance is authorized separately
Seeding, verification, re-wrapping, and cleanup require a maintenance bearer token distinct from ordinary credential use, compared in constant time.
Bulk re-wrap isolates and reports objects it cannot handle rather than aborting. One legacy envelope must not block rotation of every other healthy credential.
Repair and deletion
A connection whose vault entry is missing or unreadable can be repaired in place by re-submitting the key, without re-importing the catalogue.
Deleting a connection discards the local mirror and everything derived from it. Nothing is written to the store.
Workspace isolation
Every query is scoped by workspace in the same statement as the record identifier. A record belonging to another workspace is a miss, not a permission error — so a probe cannot distinguish "does not exist" from "exists and is not yours".
Operational state
Some rollout steps are environment work rather than code, and a deployment is not complete until they are done: applying the vault migration, configuring the maintenance bearer as an encrypted secret on both workers, deploying the credential worker before the application worker, and re-running the seed, verify, re-wrap, verify, and cleanup drill.
Branch previews share no isolated bindings yet and are not safe for real credentials. Only the main branch deploys against shared infrastructure.