Skip to content

docs(config): add ADR 0019 for raw API-response passthrough guardrails - #6310

Merged
Coly010 merged 6 commits into
developfrom
docs/config-adr-0019-api-response-passthrough
Aug 25, 2026
Merged

docs(config): add ADR 0019 for raw API-response passthrough guardrails#6310
Coly010 merged 6 commits into
developfrom
docs/config-adr-0019-api-response-passthrough

Conversation

@Coly010

Copy link
Copy Markdown
Contributor

What changed

Adds ADR 0019, recording the design guardrails for the _apiResponse escape hatch on API-sourced config values in @supabase/config — the raw /v2/projects/{ref}/configdata.attributes object carried alongside the typed mapping so package consumers can read API fields added faster than the package publishes.

The five rules it records:

  1. _apiResponse?: Record<string, unknown> — optional, present only on API-sourced values; absence does not mean "fully mapped".
  2. Lenient decode of the v2 attributes — unknown keys never fail; this is the primary protection, _apiResponse is the access mechanism.
  3. One metadata-key rule: $/_-prefixed keys are excluded from all structural walks and encodes (extends the existing $schema precedent, implemented once in the shared walk core from ADR 0018).
  4. Never persisted — the raw response carries HMAC'd secret digests and must not land in config files.
  5. Fallback, not contract — typed fields win once a raw key graduates into the mapping; unmapped-field discovery is a registry-derived helper, not a second stored field.

Why

Discussed 2026-08-24 in the context of publishing @supabase/config for multiple consumers (CLI config diff/pull, Studio's config-drift work in supabase/supabase#48906, which vendors a temporary schema mirror explicitly awaiting this package). The Management API moves faster than deliberate package releases; without a designed escape hatch the package's cadence bottlenecks every service team's API velocity, and without the guardrails a naive passthrough causes phantom drift in the ADR 0018 subtraction walks and risks persisting secret digests.

Note: numbered 0019 because 0018 is taken by #6205 (currently in the merge queue); the README index row may need a trivial rebase once #6205's 0018 row lands.

🤖 Generated with Claude Code

@Coly010
Coly010 requested a review from a team as a code ownerAugust 24, 2026 14:09
@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@f03dd0cec4c8520320ec09eac570bb7f04b14a23

Preview package for commit f03dd0c.

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:0887cff201

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
@Coly010Coly010 self-assigned this Aug 24, 2026
…19-api-response-passthrough
# Conflicts:
#	docs/adr/README.md
Scope the metadata-key rule to reserved struct positions instead of a
$/_ prefix match, since dynamic Schema.Record keys (function slugs,
edge runtime secret names) legitimately start with either character.
Require executeRaw for the v2 config fetch so the generated client's
strict schema doesn't strip unknown fields before the lenient decode
runs. Require non-enumerable/out-of-band storage for _apiResponse so
generic serialization can't observe it. Carve secrets out of typed
graduation so an HMAC digest can't reach the encoder through the
typed field.

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:bf7a489fb0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Reframe rule 3 around exclusion-by-construction: sparse.ts's
subtractValue iterates Object.entries, so a non-enumerable
_apiResponse is invisible to every walk with zero key checks and no
schema/path plumbing, and $schema never exists on decoded values at
all (io.ts extracts it pre-decode and re-attaches on write). Split
the persistence policies accordingly: $schema must be written,
_apiResponse never can be. State that _apiResponse is not a decode
schema field (file input can never produce it), that generic copies
drop it by design with an explicit accessor/attach path for consumers
that need it, that the executeRaw caller status-checks before
decoding, and that pull-style rewrites must source x-secret fields
from the local document with drift skipping them.

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:4c98523be3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment threaddocs/adr/0019-config-api-response-passthrough.md

@avalleteavallete left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve. The five rules match the current tree (executeRaw, Object.entries walks, $schema at the io boundary, x-secret). Left a few implementer-facing clarifications — the important one is reconciling mapping ownership with ADR 0018 so CLI-2156 and Studio don't grow two mappers.

Comment threaddocs/adr/0019-config-api-response-passthrough.md
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Comment threaddocs/adr/0019-config-api-response-passthrough.md
Comment threaddocs/adr/0019-config-api-response-passthrough.md Outdated
Reconcile mapping ownership with ADR 0018: the API-to-ProjectConfig
translation originally assigned to the diff core (CLI-2156) now lives
in @supabase/config so the CLI and Studio share one mapper; 0018's two
ownership sentences are amended and both ADRs cross-reference the
supersession. Clarify rule 2 that lenient decode tolerates unknown
keys without inlining them onto ProjectConfig (Alternative 4 stays
rejected). Swap the rule 5 carve-out example from the local-only
edge_runtime.secrets.* to Auth x-secret fields that actually map from
the v2 auth attribute record. Specify unmappedApiFields() as a deep
path subtraction against the registry of mapped API paths, not a
top-level key subtract.
@Coly010
Coly010 enabled auto-merge August 25, 2026 08:57

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:57df21cd2c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment threaddocs/adr/0019-config-api-response-passthrough.md
Comment threaddocs/adr/0019-config-api-response-passthrough.md
@Coly010
Coly010 added this pull request to the merge queueAug 25, 2026
Merged via the queue into develop with commit 643b182Aug 25, 2026
16 checks passed
@Coly010
Coly010 deleted the docs/config-adr-0019-api-response-passthrough branch August 25, 2026 09:23
Sign up for freeto 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.

2 participants

@Coly010@avallete