# Data storage, isolation and controls
> Source: /guides/data-storage-and-controls
> Where partner data lives, how it is encrypted, and how access is bounded to your organization.

What a security reviewer usually wants to know before a partner integration is
signed off.

## Where it runs [#where-it-runs]

Journey's API, its operational database, database backups and the analytics
datasets behind them all run in Google Cloud's **`us-east1`** region.

The API itself runs on Cloud Run behind Cloudflare, with a dedicated service
account and all egress routed through a VPC.

## Where data sits [#where-data-sits]

<Steps>
  <Step title="Raw PMS extracts">
    Newline-delimited JSON in Google Cloud Storage, partitioned by chain, date
    and time.
  </Step>
  <Step title="Analytics">
    BigQuery datasets — raw per-PMS datasets, and the modelled marts that dbt
    builds from them.
  </Step>
  <Step title="Operational store">
    AlloyDB for PostgreSQL 16, which is what the Partner API reads and writes.
    It runs as a primary with a read replica.
  </Step>
</Steps>

## Encryption and access [#encryption-and-access]

| Control | How it works |
|---|---|
| **In transit (API)** | HTTPS to the API, terminated at the edge. |
| **In transit (database)** | AlloyDB is configured for encrypted connections only, on both the primary and the replica. |
| **At rest** | Google-managed encryption, applied by default across storage, BigQuery and the database. Journey does not currently configure customer-managed keys. |
| **Network** | The database has **no public IP** — private networking only. |
| **Database authentication** | IAM database authentication is enabled, so access is granted to identities rather than shared passwords. |
| **Object storage** | Uniform bucket-level access, public access prevention enforced, and create-only writes so an extract cannot overwrite history. |
| **Backups** | Continuous backup with point-in-time recovery, plus automated backups, held in the same region. |

## How your data is isolated from other partners' [#how-your-data-is-isolated-from-other-partners]

This is enforced in the API, on every request, rather than relying on callers
to filter correctly.

<Steps>
  <Step title="Your organization comes from your credential">
    Not from a parameter. A partner caller cannot pass `?organizationId` — it
    is ignored. A credential with no organization is rejected outright.
  </Step>
  <Step title="Venue reach narrows it further">
    Role restrictions on your credential can limit it to particular properties
    or brands within your organization. Reads are filtered to that allowlist.
  </Step>
  <Step title="Out of scope looks like not found">
    Anything outside your organization and venue reach returns **404, not
    403**, so the response cannot be used to probe for what exists elsewhere.
  </Step>
</Steps>

## Personal data [#personal-data]

- **Guest contact details are masked by default.** Guest name, email and phone
  are only returned if your credential carries the guest PII read permission.
  Without it the fields are present but masked, which is a scope question
  rather than a data-availability one.
- **PII is labelled internally.** The reservations mart is tagged as
  containing personal data so that downstream tooling can treat it
  accordingly.
- **Invite sending is the narrow exception.** Guest invites deliberately touch
  contact details, and require the PII permission in addition to the general
  guest read permission.

## Credential handling [#credential-handling]

- `X-API-Key` is **not** in the API's CORS allow-list. This is deliberate:
  partner keys are for server-to-server use and must never be exposed to a
  browser.
- Only partner-level and admin-level keys are accepted on the partner surface.
  A service-level key is rejected.
- Revoked and expired keys stop working immediately, returning `401`.

<Warning>
  A partner key carries access to guest data across your whole organization.
  Keep it server-side, in a secret manager, and rotate by issuing a
  replacement before revoking the old one.
</Warning>

## What is not covered here [#what-is-not-covered-here]

Data retention schedules for raw extracts and analytics tables, and the
specifics of Journey's internal access reviews, are governed by Journey's
security policies rather than by the API. Ask your Journey contact if you need
them for a security review.
