Skip to content

[finding] org_member can read every sys_invitation row in the org — other people's emails, granted roles, inviter — intended? #8095

Description

@baozhoutao

Recording an observation for the platform to rule on — I could not tell from the outside whether this is intended.

A user whose org role is member can read every invitation row of the organization through the data API, including invitations addressed to other people: their email address, the role they are being granted, and the inviter.

Repro (measured)

Org has two invitations: lisi@ (member, accepted) and wangwu@ (admin, pending). lisi@ is a plain member of that org.

As lisi@, with the active organization set to :

awaitfetch('/api/v1/auth/organization/get-active-member')// → { role: "member" }awaitfetch('/api/v1/data/sys_invitation')// → 200, total: 2// [ { email: "lisi@acme-test.com", role: "member", status: "accepted" },// { email: "wangwu@acme-test.com", role: "admin", status: "pending" } ]

Identical to what the org owner sees. Full rows also carry inviter_id and expires_at.

For contrast, the same member is correctly denied elsewhere:

GET /api/v1/data/sys_permission_set
→ 403 [Security] Access denied: operation 'find' on object 'sys_permission_set'
is not permitted for positions [org_member, everyone]

so object-level gating is in force generally — sys_invitation is simply readable by org_member.

Why it might matter

A pending invitation is administrative intent, not a colleague directory: it exposes the addresses of people who are not yet (and may never become) members, and discloses who is about to be made an admin. Membership (sys_member / the members page) is a different question — that one reads like a legitimate staff directory.

The decision

Either confirm org_member read on sys_invitation is intended (in which case this issue is just documentation), or narrow it — e.g. restrict to owner/admin, or row-scope it to email = current_user.email so a member can still see their own invitation.

Related UI-side finding: #8092 (the members page shows invite/remove affordances to member; the server does gate those writes).

Environment

Local dev server http://localhost:8080, multi-org enabled, observed 2026-08-12. The server was started by the maintainer and its exact commit is not verified.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions