Skip to content

spec+service-settings: build ADR-0128 D1–D3, a producer-discriminated, delimiter-safe AAD on CryptoContext, with a versioned handle and an at-rest rewrap #21326

Description

@objectstack-fleet

Filed by the domain:spec seat 1 (session_01UtnxvdiN376GF3sgXwAw4d, seat post #6017) as an execution parameter of the maintainer's ruling A on #21263 (5945612493, batch #267 item 1, 「其他同意」). The ruling reads: "D1: the claiming seat files one card for ADR-0128 D1, scoped as ADR-0128 §2 and §4 state it (priority from triage). It is not this PR." ⛔ Not a claim. ⛔ Not graded here: priority and lane are triage's.

⚠️ Security family: this card names classes and positions only.

Why now

ADR-0128 (Accepted 2026-09-07) recorded D1–D3 as a direction and deferred the work (§4), naming four triggers that fund it. One of them is met: "ICryptoProvider is opened for another breaking change". PR #21292 (#21263) adds the required keyedDigest member. The ruling lands that break alone, because the organisation's repositories hold zero out-of-repo implementers (census 5945420994), so bundling would save a second break for no measured population. The deferral is therefore over, and this card schedules the work. A separate Tier H card carries ADR-0128's dated note.

Scope (ADR-0128 §2 and §4, as written)

  • D1: CryptoContext (packages/spec/src/contracts/crypto-provider.ts) carries a required scope discriminant from a closed set, with one member per producer: settings, object secret field and datasource credential. Every provider that binds AAD folds it in.
  • D2: the AAD encoding is delimiter-safe: length-prefixed, escaped or canonical structured. ⛔ No unescaped join.
  • D3: the fix is at the producer of the AAD (ICryptoProvider and LocalCryptoProvider in packages/services/service-settings). ⛔ No consumer-side fallback that tries another vocabulary's AAD.
  • §4.2, the expensive half: an at-rest rewrap of every existing ciphertext. It reads under the old AAD and writes under the new one, so the handle needs a version that says which derivation sealed it. The rewrap must be resumable, safe against a live deployment, and fail closed on any row it cannot read. rotateKey is the seam §4 names.
  • The producers to thread the discriminant through (ADR-0128's Consumers line): the settings service, the engine's secret-field path (@objectstack/objectql) and the datasource secret binder (@objectstack/service-datasource). Out-of-repo, every cloud host constructs LocalCryptoProvider through a link: dependency (census 5945420994), so a framework change reaches them with the implementation.

What triage decides

  • Priority, and whether this splits into stages, for example contract + provider + versioned handle first and the rewrap second. ADR-0128 §4's ordering note says both derivations must coexist during the migration.
  • Lanes: the work spans domain:spec (the contract) and domain:services (the provider and the producers).
  • ⛔ This card does not reopen the direction (ADR-0128 D1–D4 stand). It only schedules them.

Dedupe

The 100 most recently updated open issues and PRs were listed over REST (repo-scoped) and grepped for ADR-0128, producer-discriminated and rewrap. The hits are seat post #6017 and PR #21292, the ruling's PR, and neither schedules D1. #12599 is the closed source card. #21263 is the ruling's anchor.

Dedupe words: ADR-0128 D1 producer-discriminated AAD · CryptoContext scope discriminant · sys_secret rewrap versioned handle

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions