---
title: Credential custody
nav: Credential custody
description: Where store credentials live, what the application database holds, and why authenticated calls execute outside it.
group: trust
order: 1
status: shipped
updated: 2026-09-21
---

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](/guidelines/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.
