Skip to content

Documents GCP refusals and outage cost - #119

Merged
johnnyt merged 1 commit into
mainfrom
ece-0f6-gcp-permanent-failure-and-outage-docs
Sep 30, 2026
Merged

johnnyt merged 1 commit into
mainfrom
ece-0f6-gcp-permanent-failure-and-outage-docs

Conversation

@johnnyt

@johnnyt johnnyt commented Sep 30, 2026

Copy link
Copy Markdown
Member

Documents two behaviours of a GCP row in Encryptor.Ecto.KeyStore that were true and unwritten. Documentation only: no code, no changelog fragment (the fragment rules exclude documentation).

What changes

docs/guides/gcp-kms-key-store.md gains a section, "When Cloud KMS refuses, or does not answer", with two parts:

  • A permanent refusal answers {:key_unavailable, selector}. A destroyed key version, a row whose binding no longer matches its wrapping, and a missing or revoked decrypt grant all answer the retryable term, as an outage does. The section says what encryption_key/2 and decryption_keys/2 do when the newest row refuses and when an older row does, and what a retrying caller should check.
  • An outage costs one request timeout per GCP row. Each GCP row is its own Decrypt request bounded by the provider's :timeout (default 5,000 ms), and the store tries every row in turn, so decryption_keys/2 waits about N timeouts for N GCP rows and encryption_key/2 about one.

The text is worded for encryptor 0.5.0, the version this package pins, and names no future term.

Provenance

  • The shred section said ADR-0005 Amendment A5 is "proposed, not accepted". ADR-0005's Note of 2026-09-24, "the operator accepted Amendment A, with its A5", accepted it. That sentence now says so. It sits in the same passage this change extends, so it is corrected here rather than left beside the new section.
  • Guide rather than moduledoc: the acceptance allows either. The guide already carried the shred-time half of the first behaviour, so both behaviours now sit in one place.

Review (in-turn)

I re-read the diff against the bead and checked each claim against the code. The KeyStore claims were read at 4722b05 and the provider claims in encryptor 0.5.0. Every failed Decrypt becomes {:key_unavailable, selector}: see the {:error, _failure} arm of Encryptor.Provider.GcpKms.unwrap/3, and handle/2 in Encryptor.Provider.GcpKms.Api, which maps any non-2xx status to {:http_status, status} and a transport failure to {:transport, :request_failed}. The store returns that term unrelabelled (Encryptor.Ecto.KeyStore.unwrap_row/4, the delegating clause). Rows are unwrapped one after another and every row is tried (Encryptor.Ecto.KeyStore.unwrap_all/3, an Enum.map over all rows). encryption_key/2 unwraps the newest row only (Encryptor.Ecto.KeyStore.encryption_key/2). The default timeout is 5,000 ms and is handed to the host's HTTP client as timeout: (@default_timeout in Encryptor.Provider.GcpKms, and request/5 in its Api). The cited moduledoc heading ## Configuration exists in Encryptor.Provider.GcpKms. Gate: the change touches no Elixir code, so under this repo's rule it has no gate to run and commits on review of the diff alone.

Refs: ece-0f6

The GCP key store guide gains a section on what a GCP row answers
when Cloud KMS refuses or does not answer. A permanent Decrypt
refusal (a destroyed version, a binding mismatch, a missing grant)
answers the retryable {:key_unavailable, selector}, as an outage
does, and the section says what each callback does when the newest
or an older row refuses. During an outage each GCP row waits out the
provider's request timeout, one row after another, so
decryption_keys/2 waits about N timeouts for N GCP rows.

The shred section no longer calls ADR-0005 Amendment A5 proposed:
that record's Note of 2026-09-24 accepted it.

Refs: ece-0f6
@johnnyt
johnnyt force-pushed the ece-0f6-gcp-permanent-failure-and-outage-docs branch from 3149456 to 89e498c Compare September 30, 2026 05:56
@johnnyt
johnnyt merged commit f97af6d into main Sep 30, 2026
1 check passed
@johnnyt
johnnyt deleted the ece-0f6-gcp-permanent-failure-and-outage-docs branch September 30, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant