skip to content

You own the end-to-end testing strategy for an application with several permission roles — admin, editor, read-only — running against a shared staging environment used by other teams. How would you design the set of test identities and the way tests obtain their sessions?

level: principalimportance: nice to knowfreq 29%

answer

  1. identities are infrastructure, not fixtures
  2. roles times workers, plus disposables
  3. default to least privilege, not admin
  4. shared staging means namespace and own
  5. new role, new fixture, or no coverage

basics

~20 s

Treat test identities as owned infrastructure: one account per role, multiplied per worker where tests mutate account state, provisioned by a setup step, credentials in secrets, sessions minted per run. On shared staging, namespace the accounts and assume nothing about state you did not create.

solid answer

~50 s

I would define an identity matrix rather than a pile of ad-hoc logins: one account per permission role, multiplied by worker index for suites that mutate account-scoped state, plus disposable accounts for the destructive tests. A setup phase provisions or checks out those accounts, authenticates each one programmatically, and writes per-role session artefacts that tests declare a dependency on. Credentials live in the CI secret store and rotate; sessions are minted per run and never committed. On a shared staging environment the extra constraints are namespacing — recognisable account names owned by the test suite, so nobody else's cleanup deletes them and ours deletes nothing of theirs — and defensive assertions, because the environment's global state is not ours to control. The strategy also has to survive the permission model changing: if roles are only encoded in account fixtures, a new role silently gets no coverage.

go deeper

for a junior

Know that different permission levels need their own test accounts, and that a test should say which role it runs as rather than defaulting to whatever account is handy.

for a middle

Explain how role accounts multiply by worker for parallel mutation-heavy suites, and why each test should restore the session of the least-privileged identity that can do its job.

for a senior

Weigh provisioning per run against a pre-seeded pool — privileged APIs, setup time and orphan cleanup versus accumulated state and credential rotation — and defend the choice for a given environment.

for a principal

Own the long game: credential rotation and secret storage, blast radius and namespacing on a shared environment, drift between fixture identities and the evolving authorization model, and an honest statement of the scale below which the whole design is over-engineering.

## Framing: identities are infrastructure The reason this is a lead-level question is that test identities behave like production infrastructure. They are provisioned, they hold credentials, they need rotation and ownership, they drift from the permission model they were meant to represent, and they are shared across teams. Answering it as "create some test users" misses everything that actually makes an authenticated suite survive a year. ## The matrix Start from two axes and one exception. **Role axis.** One account per permission level the product actually distinguishes: admin, editor, read-only, and any special cases (unverified user, trial-expired, suspended) that change what the UI renders. This axis is defined by the product's authorization model, not by convenience — if a role exists in production and has no fixture, no test can ever cover it. **Concurrency axis.** For suites that mutate account-scoped state, multiply the role accounts by the worker count so no two concurrently-running tests share an identity. The account count stays bounded by roles times workers regardless of how many tests are added. **Exception: destructive tests.** Tests that change a password, delete an account, or revoke all sessions get a disposable identity created for that test alone, because their whole purpose is to invalidate a credential. ## Provision, or pre-seed? Two defensible models, and the tradeoff is worth stating explicitly. *Provision per run* — the setup phase creates accounts via an admin API and tears them down afterwards. Pro: no accumulated drift, environments are reproducible, a wiped environment self-heals. Con: it needs a privileged API in every environment, adds setup time, and leaves orphans when a run is killed, so it needs a sweeper. *Pre-seeded stable pool* — a fixed set of accounts exists in the environment, and tests check one out by index. Pro: fast, no privileged API, works against environments you do not administer. Con: the pool accumulates state over months and must be reset on a schedule; it is also a static set of credentials that must be rotated deliberately. Most teams end up hybrid: a stable pool for the common roles, per-test provisioning for the destructive cases. ## Session acquisition However accounts are obtained, the session flow is the same and should be uniform across the suite: authenticate once per identity per run, write a state artefact, have each test declare which role it needs and restore that role's state. Making the role a *declared dependency* rather than an implicit assumption is what keeps it readable — a test that says it needs the read-only identity documents its own precondition, and a reviewer can see immediately when a test is quietly running as admin because that was convenient. The default role should be the least-privileged one that can perform the test's action. Suites that run everything as admin systematically fail to catch authorization regressions, because the one account that can do everything never notices that a permission check disappeared. ## Living on shared staging A shared environment adds constraints that a dedicated one does not: - **Namespacing and ownership.** Accounts and the data they own should be recognisably the suite's (a reserved email domain or prefix), so another team's cleanup job does not delete them and ours does not delete theirs. - **No assumptions about global state.** Anything not created by the suite may change under it — feature flags, catalogue data, other teams' fixtures. Tests must assert on what they created, not on ambient counts and "the first row". - **Shared rate limits and external sandboxes.** An auth endpoint or a payment sandbox is a shared resource; a suite that authenticates aggressively can throttle another team. Minting sessions once per identity per run rather than per test matters here for politeness as much as speed. - **Blast radius.** Destructive operations need to be provably scoped to suite-owned accounts, because on shared staging "delete all" is somebody else's afternoon. ## The failure mode to design against The interesting long-term risk is **drift between the fixture identities and the real permission model**. A new role ships; nobody adds a fixture; every test still runs as one of the old three; the new role's UI is never exercised and its authorization bugs reach production. Guard against it by deriving fixtures from the authorization model where possible, and by making "add the fixture identity" a visible part of shipping a new role rather than an afterthought — the same way a new environment variable gets added to deployment config. ## What I would concede This machinery is not free, and on a small product with two roles and a dedicated environment it is over-engineering: two accounts and a login helper are the right answer, and adding a provisioning pipeline would be cost with no return. The scale at which the matrix pays for itself is roughly where parallelism, multiple roles, and a shared environment all appear at once — and saying where the line is matters more than reciting the full design.

  • Why is running the whole suite as an admin account a strategic mistake rather than just a stylistic one?
    Because an account that can do everything can never detect a missing authorization check. If a permission guard is removed, the admin-run suite stays green and the regression reaches production. Defaulting each test to the least-privileged identity that can perform its action turns the suite into a continuous check on the authorization model.
  • How do you stop test accounts drifting away from the product's real permission model?
    Make the fixture identity part of shipping a role, not a follow-up: the definition of done for a new permission level includes its test account and at least one test that runs as it. Where the platform allows, derive fixtures from the authorization configuration so an unrepresented role is visible, rather than relying on someone remembering.
  • When is this whole design over-engineering?
    On a small product with one or two roles, low parallelism and a dedicated environment. There, two stable accounts and a shared login helper give the same protection for a fraction of the cost. The matrix earns its keep when parallel mutation, several roles and a shared environment appear together; introducing it earlier is infrastructure nobody is being paid back for.

saying these in an interview costs you the question

  • Runs every end-to-end test as an administrator account
  • Keeps test account credentials in the repository
  • Assumes a shared staging environment's global state is stable
  • Creates test identities ad hoc with no owner or cleanup
  • Adds new permission roles without adding fixture identities

context