Skip to content

[Connector integrity] Do not expose a mutable live target-registry collection #231

Description

@seonghobae

Product/integrity gap

Protected develop@622e5e6c3d534f230c390f10e3832efadfc01825 exposes the backing TargetConnectorRegistry through:

public Collection<TargetConnector> all() {
    return byId.values();
}

Map.values() is a live mutable collection view. A caller that obtains all() can invoke remove(...), removeIf(...), clear(), or iterator removal and thereby mutate registry/discovery authority without passing through register(...) or any future identity validation. This is a separate invariant from duplicate-ID rejection in #203.

Current sequencing / writer lease

Status: known_gap, source mutation defer_until_trigger. Active PR #156 currently owns TargetConnectorRegistry for Qlik scaffold retirement and must not be raced. After #156 stabilizes/integrates or the target-registry writer lease otherwise clears, re-read the exact registry surface before implementing this issue. Coordinate with #203 so the two integrity fixes do not create competing branches over the same file.

RCA

  • Immediate cause: returning byId.values() directly.
  • Technical root cause: read-only discovery semantics and mutable registry storage share the same collection object.
  • Control failure: existing connector catalog/registry tests do not assert that enumeration cannot mutate registry state.
  • Impact: in-process callers/plugins can silently remove connector authority, change later discovery results, and make behavior depend on who retained a collection view.

Test-first acceptance after the writer lane clears

  1. Add a failing test against the real TargetConnectorRegistry before production changes.
  2. Prove mutation attempts through the all() result cannot change registry contents or order. Cover at least direct clear/remove or iterator removal.
  3. Return an immutable snapshot or equivalent read-only collection with deterministic iteration order. Prefer a snapshot over a live view so later legitimate registry changes cannot retroactively change an already-returned enumeration unless the API explicitly documents that behavior.
  4. Preserve existing connector object identity and lookup/catalog ordering; do not clone connector instances.
  5. Coordinate with [Connector integrity] Reject duplicate ETL target connector IDs after scaffold-retirement lane stabilizes #203 duplicate/null/blank-ID fail-closed work and [Product gap] Eliminate production scaffold-only connector implementations #153/fix(connectors): remove Qlik scaffold from production registry #156 scaffold truth; do not resurrect retired Qlik or otherwise alter supported connector claims.
  6. Add beginner-readable public Javadoc for the enumeration semantics if not already supplied by the accepted registry repair.
  7. Run focused/full ETL tests plus current dependency/SBOM/SAST/security evidence and require non-vacuous owned-production coverage before protected integration.

Non-goals

No new plugin lifecycle, priority system, concurrent dynamic registration contract, provider implementation, credential change, or cross-repository mutation.

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

    Labels

    area: authAuthentication, authorization, identity, or tenant isolationarea: ci-cdCI, GitHub Actions, checks, release, or supply chainarea: dependenciesDependency or lockfile maintenancearea: securitySecurity boundary, hardening, or vulnerability preventionmaintenancepriority: mediumNormal-priority or P2 workstatus: triagedOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions