Typorithm · medium

10. Authentication, ownership and account isolation

qatestingtest-designindependent-practice
Saved on this device
Full lesson · 4 learning steps Open any exercise for focused practice
1

Step 1 of 4 · intro card

10. Authentication, ownership and account isolation

0%

Concept and contract

Test public data and private account resources under different principals.

Authentication establishes who is making a request. Authorization decides whether that principal may perform an operation on a resource. Test both dimensions with synthetic accounts rather than assuming a successful login grants access to every account’s saved data.

A public role catalogue and a private saved list intentionally have different policies. Keep the public endpoint available anonymously while enforcing ownership on account-specific reads and writes. A test that requires login everywhere could hide a product regression instead of improving security.

Mechanism and worked example

The worked table uses Alice, Bob and an anonymous caller.

The worked table uses Alice, Bob and an anonymous caller. Alice may read Alice’s saved list, cannot read Bob’s list and can still browse public roles. The lab chooses 403 for authenticated foreign access and 401 when authentication is missing.

Use the server-established principal, not a body field naming Alice. Then verify the returned record ids or absence of side effects. A denial response that still writes another account’s saved list is a serious contract failure.

Complete worked example

json

{
  "cases": [
    {
      "caller": "alice",
      "owner": "alice",
      "status": 200
    },
    {
      "caller": "alice",
      "owner": "bob",
      "status": 403
    },
    {
      "caller": null,
      "owner": "alice",
      "status": 401
    },
    {
      "caller": null,
      "resource": "public roles",
      "status": 200
    }
  ]
}
Reasoning
The cases distinguish own, foreign, anonymous and deliberately public access.

Counterexamples and common mistakes

The weak check logs in as Alice and reads only Alice’s own list.

The weak check logs in as Alice and reads only Alice’s own list. A server ignoring account ownership would pass it. The missing evidence is a cross-account attempt with an independently known owner and a checked postcondition.

Do not run these exercises against real accounts or external systems. The companion server binds to loopback and uses fictional identities. Production authorization investigations require their own scope, permissions and data-handling policy.

Counterexample: what this check misses

json

{
  "caller": "alice",
  "owner": "alice",
  "status": 200,
  "claim": "Cross-account isolation is verified"
}
Reasoning
A successful owner read does not exercise the ownership-denial branch.

Independent practice: small task

Write three cases for Alice reading Alice’s list, Alice reading Bob’s list and an anonymous caller reading Alice’s list.

Write three cases for Alice reading Alice’s list, Alice reading Bob’s list and an anonymous caller reading Alice’s list. Add a public catalogue read to show that the private policy is not applied globally. Start with two known synthetic saved ids.

Check Bob’s list remains unchanged after a denied write in the optional extension. The basic task should clearly distinguish the four observations without requiring a complex identity provider or real credentials.

Step 1: Prepare Alice and Bob fixture ids. Step 2: Compare owner, foreign and anonymous reads.

Practice starter: solve before reading the solution

json

{
  "cases": [
    {
      "caller": "alice",
      "owner": "bob",
      "status": "TODO"
    },
    {
      "caller": null,
      "resource": "public roles",
      "status": "TODO"
    }
  ]
}
Reasoning
Use two fictional users and keep public access as a separate positive case.
  • Hint 1: Use only the loopback lab.
  • Hint 2: A denied write must not change the other account.

Solution, tests and trade-offs

The solution expects 200, 403, 401 and 200 respectively.

The solution expects 200, 403, 401 and 200 respectively. Its fixture records are controlled locally. The verifier exercises both principals and confirms the foreign account does not acquire a saved id after a rejected operation.

A passing synthetic case is evidence for the tested endpoints and policy, not a complete security assessment. Add method, resource and role variants when the real application’s authorization model requires them. Keep the resulting coverage claim precise.

Practice solution and acceptance checks

json

{
  "cases": [
    {
      "caller": "alice",
      "owner": "alice",
      "status": 200
    },
    {
      "caller": "alice",
      "owner": "bob",
      "status": 403
    },
    {
      "caller": null,
      "owner": "alice",
      "status": 401
    },
    {
      "caller": null,
      "resource": "public roles",
      "status": 200
    }
  ]
}
Reasoning
The stated statuses reflect this lab policy, with postconditions checked for denied writes.

Interview reasoning and next step

In interviews, explain an insecure direct-object access risk with two fictional users and a concrete resource.

In interviews, explain an insecure direct-object access risk with two fictional users and a concrete resource. Show why a status-only check and an own-account-only check are insufficient. Mention the public-resource exception deliberately.

Next, verify multi-page reads and combined filters, where valid individual responses can still omit, duplicate or leak records across a complete result set.

Optional stretch — after the core task works: Verify another HTTP method under the same ownership policy.

Computer practice: download the companion lab at https://applydjinn.com/typorithm/qa-lab-20261105.zip. Read its README, install the pinned tools and run the accepted examples before attempting a starter. The mobile reader preserves your reading and self-check progress; the local lab runs browser tests separately.

Test public data and private account resources under different principals.