Skip to content
Open
11 changes: 11 additions & 0 deletions .changeset/integration-removal-credential-gc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"executor": patch
---

**Removing an integration now removes the credentials its connections minted**

`integrations.remove` deletes every connection row belonging to the integration. It left the credentials those connections had minted in the store — the same orphan `connections.remove` was fixed to prevent, reachable through a different path and stranding many secrets at once rather than one.

An orphaned refresh token is the worst case: long-lived by design, no longer referenced by anything, and invisible in the product, so nobody can see it to revoke it.

The rows are read before they are deleted, because once they are gone nothing names the items they minted. Only minted ids are removed — an item the connection merely referenced is left alone, exactly as on the single-connection path. The deletion is deferred until the removal commits, so a rolled-back removal leaves the credentials intact rather than restoring connections that point at secrets which no longer exist.
9 changes: 9 additions & 0 deletions .changeset/orphaned-credential-on-connection-remove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"executor": patch
---

**Removing a connection now deletes the credential it minted**

`connections.remove` deleted the connection row and left the credential it had minted in the store. The secret outlived the only thing that referenced it, with no surface left in the product to see or remove it — so a user who disconnected an account still had that account's tokens held on their behalf.

Removal now also deletes the items the connection minted, identified by rebuilding their deterministic ids from the connection row rather than by scanning for anything that looks related. A minted credential that another connection still points at is kept. The alias scan is scoped to the provider that owns the connection, and both the OAuth and the static halves of the deletion are covered.
Loading