Skip to content

Migration story for stored cleartext datasource credentials: operator-initiated re-homing into sys_secret (blocked by the managed-schemaMode refusal) #8155

Description

@huangyiirene

Split out of #8081 scope item 3 by the domain:services PM seat. The maintainer's Option-A ruling on #7990 put this in scope of the programme — "The existing-rows migration is in scope of the programme, not optional" — and #8081's dispatch order asked for the story, not its execution. This card carries the proposal the dev produced. ⛔ Not graded by me; no domain:* label.

Blocked-by:#8153

An inventory already exists, and it is free

/meta re-parses every stored row and badges it _diagnostics: {valid:false, errors:[…]} carrying the full refusal message. Operators can already enumerate the affected rows — the migration needs no discovery phase, which removes the usual first half of a migration card.

⚠️ That also creates a coupling worth stating: #8154 (redacting the /meta read path) must not strip or break _diagnostics, or this inventory disappears.

Recommended shape — (b) admin tooling, per-datasource, operator-initiated

A Setup action — "Move credential to the secret store" — that reads the stored cleartext, binds it through the existingSecretBinder.bind(), writes external.credentialsRef, and removes the inline key only after the ref is durably written.

Is it destructive? No, and deliberately so. No credential value is discarded — it is re-homed from cleartext into sys_secret. The inline key is deleted only once the encrypted row exists. It is per-datasource and operator-initiated, so there is no sweep over a table. That matters: the ruling's "escalate if destructive" clause is what this shape is designed to stay clear of.

Rejected, with reasons

⚠️ Sequencing — this is blocked, and running it early makes things worse

The migration's entire output is external.credentialsRef on an existing row. Per #8153, writing that onto a row whose schemaMode defaults to 'managed' is exactly the shape that fails re-parse.

⇒ Running this before #8153 is settled would convert every affected managed datasource from "invalid because it holds cleartext" to "invalid because it holds a credentialsRef" — a migration that moves rows from one invalid state to another while appearing to succeed. #8153 first.

Constraints

Provenance: #8081 dev report (comment 5269923121, §③), #7990 maintainer ruling (comment 5266068845), my ACCEPT receipt (#8081 comment 5270102954). Related: #8103 (the same destructive-sweep boundary, for sys_secret orphans), #8154, #8152.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions