Skip to content
← Free FDE training guides

Free learning / 40-minute Identity 101 lab

Identity 101: a login is not permission

Separate authentication, authorization and tenant scope. Follow a document through its access checks, then run five real local database cases before adding retrieval and agents.

No account needed. Use your own copy for writing and keep the original as a reference.

Engineering lab library / Run locally

See which requests may reach the data.

Predict five cases, compare the actual query and returned-row counts, then change one request input at a time. Keep trusted identity separate from generated arguments.

Real in-memory SQLite reads with fictional records. Identity verification is supplied as a fixture; no login, model, network or production database is used.

  1. Start here / Python 3.11+ · Standard library

    Document access and tenant scope

    Compare an allowed read, missing identity, a tenant claim, a restricted record and a revoked grant.

    Python 3.11+ standard library · No model, network or account

You sign in to a support application and ask an assistant to find a maintenance procedure. The assistant finds a close match. Before it reads the document, the application has another job: establish whose request this is and whether that person may read that particular document.

This original 40-minute lesson separates those decisions. Start with the visual, predict five cases, then run a small Python program that performs actual database queries. All organizations and records are fictional. No account, model or network connection is needed.

1. Start with the building badge

UNDERSTAND THE SYSTEM

Follow a document request through its access checks

A building badge identifies you; permission opens a particular room. Follow the same distinction in software: a verified caller, one active organization and a document read. These are authored lab cases with real local query behavior and a supplied identity fixture.

FOLLOW ONE EXAMPLE

See what moves and why.

Authored illustration
01 / EXPLORE THE PARTSTap a part to explain it
Direction of information or workReturn / feedback

WHAT THIS PART DOES

Proposed request

A user or agent proposes a document ID. These arguments cannot grant a role or change the active organization.

CONNECTED TO
  • Propose a read: Access check
Read the connections in plain English
  1. 01
    Proposed request → Access check

    Treat the requested document and optional tenant claim as untrusted input.

  2. 02
    Trusted context → Access check

    Use the verified active workspace, never a tenant selected by the model.

  3. 03
    Access check → Document query

    Bind the document ID and trusted scope as query parameters.

  4. 04
    Current read grant → Document query

    Join the document to the current caller's read grant in the same organization.

  5. 05
    Document query → Returned content

    No matching row means no document content is returned.

  6. 06
    Access check → Returned content

    Missing identity or a mismatched scope can stop before a document query.

Check your understanding: A valid North login asks for North/P-8. Must the application return it?

No. The caller still needs permission for that document and action. The restricted lab case has a valid supplied identity and matching organization, but its scoped query returns zero rows. Enforce that boundary before data enters model context.

A badge check establishes who you are. The lock on a room decides whether you may enter. If two companies occupy the building, having a valid badge does not give you access to both companies' files.

In software, authentication establishes a person or workload identity. Authorization decides whether that identity may perform an action on a resource. Tenant isolation keeps one organization's data and actions within its permitted scope. A tenant is often a customer organization in a shared application.

The analogy stops at the door: software may need to check every document request, background job and citation, even after sign-in. A person can belong to multiple organizations while working within one explicitly selected workspace.

For an FDE building an agent, this is practical architecture. The model can suggest a document to read. The application's trusted code determines who is asking and which records are available. An instruction such as “use the South tenant” cannot grant that authority. These responsibilities follow the OWASP authorization guidance.

2. Read the small access map

The exercise has two organizations, North and South, that both use document ID P-7. The same short identifier therefore names different records in different organizations.

RecordContentU-7 may read it?
North / P-7A fictional North checklistYes, in the North workspace
South / P-7A different fictional South checklistYes, in the South workspace
North / P-8Fictional internal incident notesNo

The supplied trusted context is U-7 in north. It represents the result of identity and workspace verification; this exercise does not implement that verification. The request's document_id is untrusted input. An optional tenant field is checked against the trusted scope and cannot switch it.

Three terms will help you read the code. A principal is the person or workload making the request. A grant is a recorded permission, such as U-7 being allowed to read North/P-7. A scoped query constrains the database read using that caller, active organization, requested document and allowed action.

3. Run five access cases

Download fde-identity-boundary-lab.py into an empty practice folder. Use Python 3.11 or newer. The program creates a fresh in-memory SQLite database for each run and closes it afterward; it does not write files or open a listener.

Before running each command, predict whether a query will execute and whether any document text will return.

Code example
python3 --version
python3 fde-identity-boundary-lab.py allowed
python3 fde-identity-boundary-lab.py anonymous
python3 fde-identity-boundary-lab.py claim-tenant
python3 fde-identity-boundary-lab.py restricted
python3 fde-identity-boundary-lab.py revoked

Inspect trusted_context_fixture, untrusted_request and each observation's query_executed, rows_returned and response. These are local teaching traces, not production error responses or a model transcript.

CaseExpected observationWhat it teaches
allowedOne query, one permitted row, North checklistCaller, organization, document and read grant all match.
anonymousNo query; sign_in_requiredThere is no verified caller context to authorize.
claim-tenantNo query; not_availableAsking for South cannot change the trusted North workspace.
restrictedQuery returns zero rows; not_availableBeing in North does not grant access to every North document.
revokedFirst read succeeds; the next returns zero rowsRemoving the grant affects the next access check, even for the same caller.

In revoked, the program retains the first observation so you can compare it with the second. Revocation prevents the later read; it cannot erase information already delivered. This single-process example does not test concurrent requests, cached responses or distributed revocation.

4. See where the boundary is enforced

Open the read_document function. It receives trusted principal separately from the proposed request. Without a principal it returns before querying. A mismatched tenant claim also returns before querying. The remaining read joins documents to current grants and constrains the result by organization, document, caller and action.

Code example
SELECT d.id, d.text FROM documents AS d
JOIN grants AS g ON g.tenant = d.tenant AND g.document_id = d.id
WHERE d.tenant = ? AND d.id = ? AND g.subject = ? AND g.action = 'read'

The values are bound as query parameters. The organization comes from trusted context. The document ID is an input to a permission-constrained lookup; knowing it is not sufficient to retrieve it. A missing document and a document with no matching grant both produce not_available without returning document text.

This is application-enforced query scoping. SQLite is not independently applying row-level tenant policy here, and a different unrestricted query could bypass the example's function. A production design must cover every path, including search, citations, exports, workers and caches. The OWASP multi-tenant guidance is a starting point for examining those paths.

5. Change one input and explain the result

Make two separate copies of the original file. Preserve the original for comparison.

In the first copy, find the line marked Experiment A. Change only "south" to "north", then run claim-tenant using that copy's filename. It should return North/P-7. You changed the requested organization to match the existing workspace; you did not grant South access or switch workspaces.

In the second copy, find the line marked Experiment B. Change only "P-8" to "P-7", then run restricted. It should return North/P-7 because the supplied read grant covers that record. P-8 remains restricted.

Save your predicted and observed results. Point to the exact comparison or query condition responsible. If you cannot explain why the result changed, revisit the access map before adding a framework.

6. Carry this into an agent workflow

Sketch a request from a signed-in user through an agent's read_procedure tool to a data service. Draw trusted caller context on a separate path from generated tool arguments. Mark where a document can first enter model context.

Now give the model a highly relevant result from the other organization. Explain why it must be excluded before the model receives its content. Then remove the user's read grant and consider a previously cached answer or a queued job. Identify the current permission check each path would need; neither path is implemented by this exercise.

Keep a small evidence sheet: five predictions, actual query and row counts, the two edited-copy outcomes, your data-flow sketch and one remaining production gap. Have another person explain why a valid login can still produce not_available.

7. Continue into protected retrieval engineering

Continue in the authorized Academy lesson, Keep retrieval inside the right boundary, to add source freshness, cache scope, citation access and a receiving-team design task. The existing agent-engineering workbook provides a deeper context-building exercise.

Primary references checked 21 October 2026: OWASP Authorization Cheat Sheet and OWASP Multi-Tenant Security Cheat Sheet. The lab and lesson are original LockedIn Labs material. They do not establish a production security assessment or vendor certification.

Before you move on

Keep the evidence of your work.

  • Five access predictions compared with actual local query and row counts.
  • Two changed-copy results separating requested inputs from trusted scope.
  • A data-flow sketch and an untested cache or background-job boundary.

Keep these in your own working copy. Reading this page does not save work or record completion.

Suggested next free session

Investigate retrieval before trusting the answer

Apply the access boundary to source relevance, freshness and evidence quality. This is a suggested sequence; choose the practice that addresses your current gap.

Open the next free guide
Have Academy access?

Continue with worked explanations, practice and review in the related lesson.

Open the related Academy lesson →
Back to top ↑