Queries · q067 · Head of Risk and Payments · week 1, night 1
“Among internal staff users, how much elevated/role-based access exists today, and do deactivated or suspended staff still retain active role grants rather than having access revoked promptly?”
Fictional people at a fictional company, each played by a language-model agent. Who they are and what they are told
Week 1; shared with Rosa Van den Berg, Head of Data
An enterprise prospect sent a security and compliance questionnaire covering account security, access control, privacy requests, data retention and audit trails. Sales wants answers backed by evidence from our own systems, not by policy documents.
The manager, at the start of week 1
Subject: Evidence we need for the security/compliance questionnaire (this week's priority)
Hi Claire,
This questionnaire is going to a serious enterprise prospect, and Sales wants it backed by evidence from our own systems, not by our policy wording. Rosa and I are co-owning this, so your reports will feed both the questionnaire answers themselves and a broader readiness review Rosa's side is doing. Given you only get a handful of report slots a night, let's be selective and prioritize what a security reviewer will actually probe on. In my own words, here's what I need to know:
Given the slot constraints, please treat questions 3 and 1 as the top two for this week — those are the ones Sales says the prospect calls out by name. If we only get through three of the five, drop 5 first and fold it into next week.
One more thing: since this report touches account security and personal data, please keep the output at a safe aggregate level — no need to name individual customers or staff unless I specifically ask.
Let's sync briefly before you lock in Thursday night's batch so nothing gets wasted on a bounced or bundled request.
Thanks, Aylin
Hi Claire,
Before we hand evidence to this prospect, I'd want us to be confident the underlying records are actually solid enough to stand behind in writing. A few things from my side:
If any of these raise flags on your end, I'd rather we know before it goes into a customer-facing answer than after.
Thanks, Rosa
The analyst · week 1, night 1, request 2 of 3
Aylin flagged DSAR timeliness (#3) and access control currency (#1) as the top two priorities this week, named specifically by the prospect. I'm spending all 3 slots tonight on: (a) the DSAR timeliness report, since it's the single most-probed item and a time series fits my working style; (b) a staff access-currency snapshot (elevated/system roles by account status, including whether deactivated/suspended staff still hold grants) to start on priority #1; and (c) a foundational data-quality check Rosa asked for — audit trail volume/continuity and actor-identification completeness by month — because every later report on logging, retention, and incidents this week depends on trusting that the audit trail has no silent gaps and that actions tie back to identifiable actors. I'm deliberately not touching MFA/login-security (#2) or incidents (#4/#5) tonight per Aylin's steer to drop #5 first and prioritize #1/#3; I'll plan #2 and #4 for a later night pending Thursday's sync with Aylin. All reports are kept at aggregate level (no named individuals/tenants) per Aylin's privacy instruction.
The engineer · 1 dry run on the empty schema, then the submission
WITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status, s.last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, ROUND(COUNT(user_role_id)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 2) AS avg_roles_per_user, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(role_granted_at AS date))) FILTER (WHERE user_role_id IS NOT NULL), 1) AS median_days_since_role_granted, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_never_logged_in, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(last_login_at AS date))) FILTER (WHERE last_login_at IS NOT NULL), 1) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END, status
“Query compiles with the expected 9 columns. Submitting.”
“Submitted. The report gives one row per staff status (active, invited, suspended, deactivated) with role-grant coverage, system-role holders, average grants per user, and median tenure of grants and logins — all as a snapshot at 2025-12-31. Flagged in the note that user_roles has no revocation timestamp, so this measures current access state, not revocation speed, and asked the analyst to watch the suspended/deactivated rows for stale access.”
As Claire Dubois saw it, from the small dataset the agents worked on
status | staff_user_count | users_with_any_role | pct_with_any_role | users_with_system_role | avg_roles_per_user | median_days_since_role_granted | pct_never_logged_in | median_days_since_last_login ------------+------------------+---------------------+-------------------+------------------------+--------------------+--------------------------------+---------------------+----------------------------- active | 548 | 548 | 1.0 | 548 | 1.02 | 1483.5 | 0.0 | 2.0 deactivated | 2 | 2 | 1.0 | 2 | 1.0 | 2313.0 | 0.0 | 161.5 (2 rows)
The memo and the queries that followed; links found by title, so inferred
Later queries that build on this report:
Changed only where the benchmark needs the same result on every system
WITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL),joined AS ( SELECT s.id AS user_id, s.status, s.last_login_at, s.status AS status, s.last_login_at AS last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system r.is_system AS is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id)SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_with_any_role, CAST(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, ROUND(COUNT(user_role_id)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 2) AS avg_roles_per_user, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(role_granted_at AS date))) FILTER (WHERE user_role_id IS NOT NULL), 1) AS median_days_since_role_granted, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_never_logged_in, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(last_login_at AS date))) FILTER (WHERE last_login_at IS NOT NULL), 1) AS median_days_since_last_login CAST(COUNT(user_role_id) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS avg_roles_per_user, {{percentile_cont_filter(0.5, (DATE '2025-12-31' - CAST(role_granted_at AS date)), user_role_id IS NOT NULL)}} AS median_days_since_role_granted, CAST(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_never_logged_in, {{percentile_cont_filter(0.5, (DATE '2025-12-31' - CAST(last_login_at AS date)), last_login_at IS NOT NULL)}} AS median_days_since_last_loginFROM joinedGROUP BY statusORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END, statusORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END NULLS LAST, status NULLS LAST
WITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status AS status, s.last_login_at AS last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system AS is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, CAST(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, CAST(COUNT(user_role_id) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS avg_roles_per_user, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(role_granted_at AS date))) FILTER (WHERE user_role_id IS NOT NULL) AS median_days_since_role_granted, CAST(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_never_logged_in, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(last_login_at AS date))) FILTER (WHERE last_login_at IS NOT NULL) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END NULLS LAST, status NULLS LAST
WITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status AS status, s.last_login_at AS last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system AS is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, CAST(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, CAST(COUNT(user_role_id) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS avg_roles_per_user, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN user_role_id IS NOT NULL THEN (DATE '2025-12-31' - CAST(role_granted_at AS date)) END) AS median_days_since_role_granted, CAST(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_never_logged_in, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CASE WHEN last_login_at IS NOT NULL THEN (DATE '2025-12-31' - CAST(last_login_at AS date)) END) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END NULLS LAST, status NULLS LAST
WITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status AS status, s.last_login_at AS last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system AS is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, CAST(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, CAST(COUNT(user_role_id) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS avg_roles_per_user, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CAST((DATE '2025-12-31' - CAST(role_granted_at AS date)) AS DOUBLE PRECISION)) FILTER (WHERE user_role_id IS NOT NULL) AS median_days_since_role_granted, CAST(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_never_logged_in, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY CAST((DATE '2025-12-31' - CAST(last_login_at AS date)) AS DOUBLE PRECISION)) FILTER (WHERE last_login_at IS NOT NULL) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END NULLS LAST, status NULLS LAST
WITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status AS status, s.last_login_at AS last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system AS is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, CAST(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, CAST(COUNT(user_role_id) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS avg_roles_per_user, quantileExactInclusiveIf(0.5)(toFloat64((DATE '2025-12-31' - CAST(role_granted_at AS date))), user_role_id IS NOT NULL) AS median_days_since_role_granted, CAST(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL) AS numeric(18,6)) / NULLIF(COUNT(DISTINCT user_id),0) AS pct_never_logged_in, quantileExactInclusiveIf(0.5)(toFloat64((DATE '2025-12-31' - CAST(last_login_at AS date))), last_login_at IS NOT NULL) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END NULLS LAST, status NULLS LAST
The agents' own records, as the role play wrote them; only the personal data of the person who ran it is redacted
Report request from Claire Dubois (analyst for the Head of Risk and Payments): Title: Staff access currency by account status Question: Among internal staff users, how much elevated/role-based access exists today, and do deactivated or suspended staff still retain active role grants rather than having access revoked promptly? Grain: one row per users.status value (active, invited, suspended, deactivated), restricted to users.is_staff = true, across all tenants, as a current-state snapshot as of 2025-12-31 Columns: - status - staff_user_count (count of is_staff=true users with this status, excluding deleted_at not null) - users_with_any_role (distinct users with >=1 row in user_roles) - pct_with_any_role (users_with_any_role / staff_user_count) - users_with_system_role (distinct users holding a role where roles.is_system = true) - avg_roles_per_user (count of user_roles rows / staff_user_count) - median_days_since_role_granted (median of 2025-12-31 minus user_roles.created_at, in days, over all grants for these users) - pct_never_logged_in (users.last_login_at is null) - median_days_since_last_login (median of 2025-12-31 minus last_login_at, over users with a non-null last_login_at) Details: Source: users joined to user_roles and roles (for is_system). This is a snapshot of current assignments (user_roles has no revocation/end timestamp in the schema), so please note that limitation on the report — it tells us what access exists today, not how quickly past revocations happened. Flag clearly if 'suspended' or 'deactivated' rows show non-trivial users_with_any_role or users_with_system_role counts, since that's the key signal of stale access. Order rows: active, invited, suspended, deactivated. Check your query with the warehouse's dry_run tool, then hand it in with submit.
dry_runWITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status, s.last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, ROUND(COUNT(user_role_id)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 2) AS avg_roles_per_user, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(role_granted_at AS date))) FILTER (WHERE user_role_id IS NOT NULL), 1) AS median_days_since_role_granted, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_never_logged_in, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(last_login_at AS date))) FILTER (WHERE last_login_at IS NOT NULL), 1) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END, status
STATUS: COMPILES (dry run on the empty schema, no data read) COLUMNS: status, staff_user_count, users_with_any_role, pct_with_any_role, users_with_system_role, avg_roles_per_user, median_days_since_role_granted, pct_never_logged_in, median_days_since_last_login
submitWITH staff AS ( SELECT id, status, last_login_at FROM users WHERE is_staff = true AND deleted_at IS NULL ), joined AS ( SELECT s.id AS user_id, s.status, s.last_login_at, ur.id AS user_role_id, ur.created_at AS role_granted_at, r.is_system FROM staff s LEFT JOIN user_roles ur ON ur.user_id = s.id LEFT JOIN roles r ON r.id = ur.role_id ) SELECT status, COUNT(DISTINCT user_id) AS staff_user_count, COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL) AS users_with_any_role, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE user_role_id IS NOT NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_with_any_role, COUNT(DISTINCT user_id) FILTER (WHERE is_system = true) AS users_with_system_role, ROUND(COUNT(user_role_id)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 2) AS avg_roles_per_user, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(role_granted_at AS date))) FILTER (WHERE user_role_id IS NOT NULL), 1) AS median_days_since_role_granted, ROUND(COUNT(DISTINCT user_id) FILTER (WHERE last_login_at IS NULL)::numeric / NULLIF(COUNT(DISTINCT user_id),0), 4) AS pct_never_logged_in, ROUND(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY (DATE '2025-12-31' - CAST(last_login_at AS date))) FILTER (WHERE last_login_at IS NOT NULL), 1) AS median_days_since_last_login FROM joined GROUP BY status ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'invited' THEN 2 WHEN 'suspended' THEN 3 WHEN 'deactivated' THEN 4 ELSE 5 END, status
Submitted to tonight's batch. Your work on this request is done.