Skip to content

orb(installations): the backfill unconditionally clears suspended_at — an owner's App suspension is erased and the broker's eligibility gate becomes always-passing #9151

Description

@JSONbored

Problem

backfillOrbInstallations (src/orb/installations.ts:50-65) unconditionally clears the suspension flag
on every install GitHub returns:

ON CONFLICT(installation_id) DO UPDATE SET
  account_login = excluded.account_login, …, suspended_at = NULL, removed_at = NULL,
  last_event_at = CURRENT_TIMESTAMP

listOrbAppInstallations never parses the installation's suspended_at — it reads only id, account,
and repository_selection — so there is no value to write through even if the upsert wanted one.
GET /app/installations does return suspended installations, carrying suspended_at/suspended_by.

A suspension recorded by the installation.suspend webhook (installations.ts:33-35) is therefore
erased by the next backfill, with no unsuspend event ever having arrived.

Trigger

An account owner suspends the ORB App (GitHub's native "pause this app"). An operator later runs
POST /v1/internal/orb/installations/backfill to recover missed installs. The suspension silently
disappears from the registry.

Impact

brokerOrbToken's eligibility check install.suspended_at !== null (src/orb/broker.ts:167-171) — the
only registry-side representation of "the account owner revoked consent" — becomes structurally
always-passing. Concretely this converts a clean 403 installation_not_eligible into a 503 broker_error (GitHub itself rejects the mint), so the container retries and DLQs instead of stopping,
and every operator-facing view reports the install as active. src/orb/oauth.ts:105's "Installation not
active" check is defeated the same way, re-opening self-enrollment on a suspended install.

Consent withdrawal is the one signal that should never be silently discarded.

Requirements

  • Parse suspended_at in listOrbAppInstallations and write it through in the backfill upsert instead
    of hardcoding NULL.
  • Apply the same reasoning to removed_at — confirm the backfill should be resurrecting removed installs
    at all, or scope the clear to installs GitHub actually reports as active.
  • Add a test that a suspended install survives a backfill.

Test Coverage Requirements

99%+ patch coverage, branch-counted; both arms (suspended / active) through the backfill.

Links & Resources

maintainer-only — consent and eligibility state.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions