From 369d4d5580336bf2b60d718964c7aaa034eebc7d Mon Sep 17 00:00:00 2001 From: Michael Netshipise Date: Sun, 14 Jun 2026 06:58:23 +0200 Subject: [PATCH] =?UTF-8?q?admin:=20GetUsersData=20=E2=80=94=20system-toke?= =?UTF-8?q?n=20user=20lookup=20(id=20+=20name=20only)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new system-token-authed admin RPC: resolves user ids to display names with NO PII (email/phone), authorized by a shared system token alone (no actor). Lets internal services label "who did this" (e.g. CMS content history) without the end-user's credentials and without a vector to harvest contact info. Adds the proto messages + the AdminClient::get_users_data wrapper. --- VERSION | 2 +- proto/st-peter-admin.proto | 22 ++++++++++++++++++++++ rust/Cargo.toml | 2 +- rust/src/lib.rs | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index ee1372d..7179039 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.2 +0.2.3 diff --git a/proto/st-peter-admin.proto b/proto/st-peter-admin.proto index 3c70b31..1131019 100644 --- a/proto/st-peter-admin.proto +++ b/proto/st-peter-admin.proto @@ -12,6 +12,10 @@ message Date { service AuthAdminService { rpc GetUser (GetUserRequest) returns (UserResponse); rpc GetUsers (GetUsersRequest) returns (UsersResponse); + // System-token-authed minimal lookup: id + display name ONLY (no PII). + // Auth is the shared system token alone (no actor) — internal services only, + // so viewing content (e.g. history) can't be used to harvest user info. + rpc GetUsersData (GetUsersDataRequest) returns (GetUsersDataResponse); rpc GetUsersByUsernames(GetUsersByUsernamesRequest) returns (UsersResponse); rpc DeleteUser (DeleteUserRequest) returns (OperationResponse); rpc RestoreUser (RestoreUserRequest) returns (OperationResponse); @@ -306,6 +310,24 @@ message UsersResponse { repeated User users = 4; } +// GetUsersData — system-token-only, returns the MINIMUM for display: id + a +// resolved display name. Deliberately omits email/phone/PII so even a trusted +// internal caller can't harvest contact info through it. +message GetUsersDataRequest { + string system_token = 1; + repeated string user_ids = 2; +} + +message UserData { + string id = 1; + string name = 2; +} + +message GetUsersDataResponse { + bool success = 1; + repeated UserData users = 2; +} + message GetAssignableRolesRequest { string actor_id = 1; string actor_token = 2; diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b417ecc..7e8de81 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "st-peter-client" -version = "0.2.2" +version = "0.2.3" edition = "2021" description = "Official Rust client for st-peter (aura-users) — authentication over gRPC with a token-verify cache" repository = "https://git.awesomike.com/pub/st-peter-client" diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 789d02d..5ea1bcf 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -405,6 +405,28 @@ impl AdminClient { self.inner.clone() } + /// System-token user lookup — returns ONLY id + display name (no PII). + /// Authorizes on the shared `system_token` alone (no actor), so an internal + /// service can label "who did this" (e.g. content history) without the + /// end-user's credentials and without exposing contact info. The token must + /// be one registered in st-peter's `system-tokens`. + pub async fn get_users_data( + &self, + system_token: &str, + user_ids: Vec, + ) -> Result> { + let resp = self + .inner + .clone() + .get_users_data(adminpb::GetUsersDataRequest { + system_token: system_token.to_string(), + user_ids, + }) + .await? + .into_inner(); + Ok(resp.users) + } + /// Assign a role to a user — targeted when `target_id` is set (the /// multi-tenancy device: e.g. `cms-content-editor` for one organization), /// optionally time-bound via `expires_at`.