skip to content

Every customer names its directory groups differently, so how do you map those groups to your roles without a deploy?

level: seniorimportance: should knowfreq 36%

answer

  1. their vocabulary, your roles
  2. rows per connection, edited at runtime
  3. unmapped grants nothing, still logs
  4. two sets: provider-derived and local
  5. a rule that stops matching is an alert

basics

~20 s

Hold the mapping as tenant-scoped rows - the group value the customer sends on the left, your role on the right - read on every sign-in and editable at runtime. Grant nothing for an unmapped value, record it, and alert when a rule stops matching.

solid answer

~50 s

Your roles are yours; the group names are the customer's, and they will not standardise. So the mapping is data: rows scoped to a connection, each pairing a group value the customer actually sends with a role you define, edited by an operator at runtime rather than shipped in a build. Three decisions come with it. An **unmapped group** grants nothing and is recorded, so support can add a rule rather than guess; it does not refuse the sign-in. Provider-derived roles are **recomputed on every sign-in** and kept in a set separate from roles granted locally inside your product, so a directory change takes effect without wiping what your own administrators granted. And because a customer can rename a group at any time, a rule that used to match and now matches nothing is an **alert**, not a silent no-op - that rename is the commonest way access disappears with no error anywhere.

code

json · 10 lines
json
{
  "connectionId": "conn-8842",
  "defaultRole": "housekeeper",
  "rules": [
    { "groupValue": "HSKP_LEAD_ALL", "role": "shift-supervisor", "lastMatchedAt": "2026-09-18T05:12:00Z", "matches7d": 214 },
    { "groupValue": "HSKP_LEAD_READONLY", "role": "rota-viewer", "lastMatchedAt": "2026-09-18T06:40:00Z", "matches7d": 38 },
    { "groupValue": "PROPERTY_MGR", "role": "property-admin", "lastMatchedAt": "2026-07-02T11:03:00Z", "matches7d": 0 }
  ],
  "unmappedSeen7d": { "HSKP_SHIFT_LEAD": 211, "FIRE_WARDEN": 46 }
}

go deeper

for a junior

Remember that the customer sends its own group names and your product has its own roles, so something has to translate between them. That translation is configuration, not something baked into the code.

for a middle

Explain the rows and their reads: exact match on the group value the customer sends, an unmapped value granting nothing but being recorded, and a default role for anyone admitted.

for a senior

Show the operational judgment: provider-derived roles recomputed separately from locally granted ones, the sign-in-scoped lag that creates, last-matched counters that expose a rename, and a floor that refuses to leave a tenant without an administrator.

for a principal

Own the boundary. Your roles are the product's contract and must not be dictated by a customer's directory naming; decide what you will absorb as mapping configuration and what you will decline, because every exception here is permanent.

## Why this cannot be code One brand calls the group `Housekeeping-Supervisors`. Another calls it `HSKP_LEAD_ALL`. A third sends an opaque identifier rather than a name at all. None of them will rename anything to suit you, and each one you encode is a release. Held as rows, a new brand's mapping is an afternoon's data entry by support; held in code, it is a deploy and a merge conflict. A mapping row is minimal: the connection it belongs to, the exact group value as the customer sends it, the role it grants, and bookkeeping - who added it and when it last matched. A per-product **default** may reasonably live in code ("every admitted person gets the base role"); the per-customer rows may not. ## The unmapped value The most common runtime event is a group you have never seen, because directories contain hundreds of groups and your mapping covers five. - **Grant nothing for it.** A group you do not recognise carries no meaning you can act on. - **Do not refuse the sign-in.** Somebody who belongs to one mapped group and forty unmapped ones is an ordinary employee, not an error. - **Record the value with a counter per connection.** The list of unmapped values seen this week is exactly the screen a support engineer needs when a customer says "our new supervisors cannot see the rota". - **Never map by substring.** `HSKP_LEAD` matching `HSKP_LEAD_READONLY` is how a read-only group silently becomes a supervisor. Match exactly. ## Recompute or persist | | Recompute on every sign-in | Persist at first sign-in | |---|---|---| | Directory change takes effect | At the person's next sign-in | Never, without a separate sweep | | A removed group | Removes the role next sign-in | Leaves the role in place indefinitely | | Roles granted inside your product | Wiped, unless kept in a separate set | Survive naturally | | Failure mode | A bad mapping strips many people at once | Stale grants nobody notices for a year | The workable answer takes the first column and fixes its one weakness: hold **provider-derived** grants in their own set, recomputed wholesale on each sign-in from the groups this sign-in carried, and hold **locally granted** roles in another set that the recompute does not touch. The person's effective authority is the union. Then a customer removing somebody from a group removes the role at the next sign-in, and a role your own support granted for a trial is not collateral damage. The lag is worth stating precisely: with recompute-on-sign-in, a group change takes effect **the next time that person signs in**, not the moment the customer makes it. Somebody already signed in keeps what they had until then - if that gap matters for a particular customer, the fix is a shorter session or an explicit revocation, not a change to the mapping design. ## Drift, and the failure with no error A customer renames `HSKP_LEAD_ALL` to `HSKP_SHIFT_LEAD`. Nothing breaks. Sign-ins succeed, no exception is raised, no log line says anything went wrong - the rule simply stops matching and every supervisor in that brand quietly loses the supervisor role. You find out when somebody phones. What catches it: 1. **Last-matched timestamps per rule.** A rule that matched two hundred times last week and zero times this week is an alert, and it names the tenant. 2. **Unmapped-value counters.** The new group name shows up on the unseen list at exactly the moment the old rule goes quiet - the two signals together read as a rename. 3. **A floor on privileged roles.** A recompute that would leave a tenant with nobody holding its administrator role should refuse and alert rather than proceed. It is a legitimate state in theory and almost always a mapping fault in practice. 4. **A weekly per-tenant summary** of roles granted through the mapping, which turns a silent change into something a customer's own administrator can notice. ## What stays yours The customer sends group memberships. It does not send your roles, and asking it to is tempting and wrong: it pushes your permission model into a directory you do not control, ties your naming to their change process, and breaks the moment a second customer disagrees about what a role should be called. Take their vocabulary at the boundary, translate it into yours, and keep what a role actually grants entirely on your side.

  • A customer asks you to have its directory send your role names directly, so no mapping is needed. What do you say?
    Decline it as the general design. It puts your permission model inside a directory you cannot change, couples your role naming to their change-control process, and collapses the moment a second customer wants different names or you rename a role. Accept their vocabulary at the boundary and translate. If one customer genuinely sends matching values, that is just a mapping whose two sides happen to read alike.
  • A mapping edit strips the supervisor role from two hundred people at their next sign-in. How would you have caught it before they noticed?
    Preview the change before saving: run the proposed rules against the last few days of recorded group values for that connection and show the operator the delta - roles gained, roles lost, and by how many people. A change that removes a role from hundreds should require a confirmation, and a change that leaves nobody holding an administrator role should be refused outright.
  • Should a group mapping be able to grant the tenant-administrator role inside your product?
    Yes, or administration itself becomes a manual onboarding step for every brand. But treat it as the mapping's most dangerous row: exact-match only, changes to it audited separately, an alert when the set of people it resolves to changes sharply, and a refusal to apply a recompute that would leave the tenant with no administrator at all.

A staff door list that names job titles the company has since renamed. Nobody is turned away with an error and no alarm sounds - the names on the badges simply stop matching the names on the list, and the list looks perfectly healthy while the shift stands outside.

saying these in an interview costs you the question

  • Hard-codes each customer's group names in application code
  • Matches group values by substring or prefix rather than exactly
  • Refuses the sign-in when a group has no mapping rule
  • Recomputes all roles and wipes grants made inside the product
  • Treats a rule that suddenly matches nothing as a normal no-op
  • Asks the customer's directory to send your role names instead of its groups