Skip to content

aggregate() does not mask secret/password fields (bypasses read-path masking) #3171

Description

@os-zhuang

Summary

ObjectQL.aggregate() does not apply credential-field masking, unlike find() / findOne(). A query that selects, groups by, or otherwise surfaces a secret or password field through aggregate() can leak the stored value (an opaque secret:<id> ref for secret; plaintext for password) that the normal read path masks to SECRET_MASK.

This is a pre-existing gap for secret, surfaced while implementing read-path masking for password in #2036 / ADR-0100 (PR #3170). It was deliberately left out of that change to keep it focused on the read-contract decision.

Detail

  • find()maskSecretFields (engine.ts) and findOne()maskSecretFields both mask via collectMaskedReadFields.
  • aggregate() returns driver rows (or in-memory aggregation output) with no masking call.
  • count() is unaffected (returns only counts).

Why post-hoc masking is the wrong fix

Blindly masking aggregate output would corrupt group keys / aggregate values (e.g. GROUP BY on a credential field, or MIN/MAX over one), producing rows keyed on ••••••••. The value semantics of an aggregation over a credential field are meaningless anyway.

Proposed fix

Reject aggregations that reference a secret or password field (in select/aggregate expressions, groupBy, or having) with a clear error, rather than silently masking or leaking. Applies symmetrically to both credential types (reuse collectMaskedReadFields). Add unit coverage under packages/objectql.

Acceptance

  • aggregate() referencing a secret or password field fails fast with a descriptive error (or is otherwise provably non-leaking).
  • Unit test pins the behavior for both types.

Ref: ADR-0100, #2036, PR #3170.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions