Build a document assistant with current permissionsLESSON 18.05 · 5 OF 13 IN CHAPTER
OPTIONAL SPECIALIZATION / AI evaluation and guardrails
Step 238 of 252
LESSON 18.05 · 5 OF 13 IN CHAPTERTry it, then open the solution

Build a document assistant with current permissions

Application background

An employee asks, “How many days can I carry over?” in an internal handbook assistant. The application searches documents the employee may read, selects relevant passages and asks a model to draft an answer with references to those passages.

The model must not fill missing policy information with a plausible invention. Access can change while the answer is being prepared, and a document might contain text telling the assistant to ignore its rules.

Example walkthrough

01 · Try this input

Input / starting state
Ana asks about leave and can read the leave policy
Expected result
Return an answer supported by the allowed passage.

02 · Try this input

Input / starting state
The only matching source is private to another team
Expected result
Say there is not enough usable evidence.

03 · Try this input

Input / starting state
A source loses permission before the answer is sent
Expected result
Do not expose its text or a derived answer that depends on it.

Retrieval means finding source material for the answer. Abstention means explicitly declining to answer when the application cannot provide permitted supporting evidence.

Your assignment

Deliver: Build a question-to-answer flow with permitted source retrieval, usable references and a clear refusal to answer when supporting evidence is missing or revoked.

Required behavior: Answer only from currently authorized source material, cite exact document/version evidence, and abstain when evidence is insufficient. Retrieved text is data, not permission to call tools or alter system behavior.

The required first milestone is a working local implementation of the behavior above. The numbered implementation steps define the scope. The cloud architecture is a later extension, not something the starter has already provisioned.

Get the code and run the supplied example

The code is in the public junior-to-staff repository. Install Git and Python 3.12+. No AWS account or Python packages are required for this first run. If you already have a checkout, use it and skip cloning.

git clone https://github.com/Soulful-Iris/junior-to-staff.git
cd junior-to-staff
python3 examples/architecture-starts/knowledge_assistant.py

Supplied file: examples/architecture-starts/knowledge_assistant.py. You can also read or download the source here (download file, source below).

Read the supplied code · knowledge_assistant.py
read or download the source here · knowledge_assistant.py
"""Local mechanism demonstration for knowledge-assistant. No AWS resources are created."""
docs={'d1':{'text':'Expenses require a receipt.','allowed':True},'d2':{'text':'Secret acquisition plan','allowed':False}}
candidates=['d2','d1']; evidence=[(i,docs[i]['text']) for i in candidates if docs[i]['allowed']]
print('Authorized evidence:',evidence)
docs['d1']['allowed']=False
print('Final response:', 'withheld: access changed' if any(not docs[i]['allowed'] for i,_ in evidence) else evidence)

This program is a mechanism demonstration: it runs the small scenario in one process and prints the result. It is not an HTTP service, a complete application, or an AWS deployment. A successful run demonstrates this mechanism only. It does not establish the workload or failure guarantees of the application you will build.

Example output from the supplied run:

Generated IDs and timestamps may differ. Compare the state transitions and outcomes.

Authorized evidence: [('d1', 'Expenses require a receipt.')]
Final response: withheld: access changed

Set up your implementation workspace

Create work/knowledge-assistant/ in your checkout (or use a separate repository). Copy the supplied mechanism into that directory as mechanism.py, then extract its state transitions into functions you can call from your implementation. The record and module names below describe what you must implement. They are not a promise that files with those names already exist. Keep a README.md beside your implementation with its exact run commands and observed results.

Local components and state to implement

This table names the records, interfaces or decision inputs for your deliverable. Unless a name is explicitly linked to supplied source above, it is something you create. Implement the local state transitions first, then connect the HTTP, storage or worker boundaries required by the steps.

Record / module Key or interface Responsibility
source_chunks tenant,document,version,chunk_id Evidence with current ACL and source provenance.
answer_run subject,query,source_versions,model,prompt Reproducible answer context without unrestricted sensitive logging.
citations answer_span,document_version,quoted_range Support references that can be opened by the current caller.

Implement the assignment

1. Ship authorized search first

Implement document/chunk ingestion with source versions and deletion handling. Search by tenant, then verify current access before loading chunk text. Provide a useful source-search UI before adding generation so the baseline can be compared directly.

2. Generate from a bounded evidence set

Pass only authorized chunks and a clear answer/abstain contract. Keep source instructions inside the data boundary. Record model/prompt/index versions and token/latency budgets. An answer containing a citation still requires checking whether that source supports the specific claim.

3. Recheck before returning

Track the policy revision used during retrieval and revalidate access to cited sources at finalization. If access changed, discard the affected answer and return a safe retry/abstention. Cache keys include authorization context. A warm generated-answer cache cannot bypass revocation.

4. Review concrete cases

Use supported, unsupported, conflicting-source and revoked-source questions. Compare useful answers and justified abstentions against the search-only baseline. Retain redacted failure examples and identify whether the fault was retrieval, authorization, generation or citation mapping.

Demonstrate the completed local result

01 · Try this input

Input / starting state
Run the starting program
Expected result
The private document is excluded. Revocation during preparation withholds the answer.

02 · Try this input

Input / starting state
Ask a question absent from sources
Expected result
The assistant abstains and offers authorized source search.

03 · Try this input

Input / starting state
Put tool instructions in a document
Expected result
No tool action is authorized by the retrieved text.

Handoff: In your implementation README, include the start command, one successful operation, the failure case above and the resulting stored state or decision. State which dependencies are simulated. Someone with a fresh checkout should be able to reproduce this without your chat history.

Workload assumptions and capacity decisions

These are constructed exercise assumptions. The stated workload is a design target. The local demonstration does not establish that throughput. Use the estimation constants to check units before choosing capacity.

Input or objective Calculation / consequence
Four-second response target Example budget: 700 ms retrieval, 2,500 ms generation, 200 ms final checks, 300 ms transport and 300 ms reserve.
100,000 documents × eight chunks assumption 800,000 chunk records before embeddings and index overhead.
20 requests/s peak At three seconds mean active time, about 60 concurrent requests. Bound model and retrieval concurrency separately.

Map the local implementation to AWS

Deployment status: local only. Running the supplied command creates no AWS resources and configures no cloud connections. The diagram is a proposed deployment of the completed application. Each box needs either a deployed runtime, a provisioned service or an explicitly external dependency.

Read the diagram by following the arrows from the entry point: application code accepts the request or event, the state owner commits it, and any worker produces the later result. The table ties those roles to code and adapter work. Multiple boxes do not imply multiple Python files already exist.

Build a document assistant with current permissions: AWS services, their general roles, and the primary data flow

Bedrock generates language. The application decides which documents the caller may use. OpenSearch provides candidates, while current policy and source version checks enforce the evidence boundary.

Local responsibility Cloud destination and role Implementation still required
Local HTTP boundary or the endpoint you will add Amazon API Gateway: authenticated question entry Create routes and an integration. Translate requests and responses and configure identity validation.
Python operation or worker function AWS Lambda: answer orchestration Write a Lambda event adapter, package its dependencies and give its role only the required resource actions.
Local derived search records Amazon OpenSearch Service: chunk retrieval index Implement indexing, updates/deletions and queries. Recheck current authorization before returning sensitive results.
Deterministic model response fixture Amazon Bedrock: model inference Implement model invocation with deadlines, input boundaries and validated output. Preserve the same permission and action rules.
Local dictionary, SQLite records or state model Amazon DynamoDB: document policy metadata Design partition/sort keys and write a storage adapter with conditional updates or transactions. Python state and SQL are not uploaded as a database.
Local file, object fixture or exported payload Amazon S3: private document storage Implement upload/download and metadata adapters, scoped access, object naming, retention and incomplete-upload cleanup.

Provision resources, then connect the application

Resource or boundary Initial configuration and reason
Bedrock invocation Explicit model configuration, request deadline and least-privilege invocation role. Model output never grants tool permission.
Retrieval Tenant filters plus current ACL checks. Source deletions invalidate retrieval and answer-cache eligibility.
Telemetry Record aggregate latency/token use and redacted evidence identities. Keep sensitive document text out of general logs.

Use one disposable AWS environment for the cloud exercise. Put the named resources in infra/template.yaml or your existing IaC tool, pass resource IDs through configuration, and scope each runtime role to its own tables, buckets and queues. The diagram is a design to implement. It is not a claim that these resources have been deployed. Record the commands you used to deploy and remove the exercise resources.

For concrete provisioning commands, configuration wiring and cleanup, use the AWS foundation guide. It includes a deployable table/queue/object-storage foundation and explains which application and service adapters you still implement.

A provisioned queue or table does not make the local program use it. Configure resource IDs in the deployed runtime, replace the local adapter, and replay the same successful and failing operation against that runtime. Record the deployed commit and observable result, then remove the disposable resources using your infrastructure tool.

Extend the design after the baseline works

Worked follow-up: Answer during a policy revision without mixing incompatible sources

An answer can cite every sentence accurately yet combine rules that never applied together. Permission checks alone do not establish temporal or policy consistency.

Starting design Changed requirement
Retrieved sources are individually authorized. Some documents describe policy 4 while others already describe policy 5.

Revised architecture. Follow the changed responsibility and failure path below. This is a design to implement. The supplied local example does not provision these components.

Diagram: Worked follow-up: Answer during a policy revision without mixing incompatible sources

What to implement. Attach policy family, revision, effective interval and source version to indexed chunks. Select an applicable policy snapshot before generation. If required sources conflict or are missing, return a clear conflict or insufficient-evidence outcome rather than asking the model to choose authority. Recheck access before delivering the answer. Keep the previous index generation available while the new corpus is being built.

Walk through the result. Policy 4 permits refunds within 30 days and policy 5 permits 14. Ask about a purchase during the transition. Show which effective-date rule selects the policy and cite that revision. If the effective date is absent, ask for it or decline the definitive answer. Deliver the retrieval filter and conflict response.

Allow answers using multiple document versions during an ongoing policy update. Decide whether mixed-version evidence is acceptable and how conflicts are surfaced rather than silently resolved by the model.

Additional design cases, alternatives and original source notes

Your contract. Answers require verifiable citations, a 4-second response target, and no content from a document the caller cannot currently open. Retrieval quality is valuable but never grants access. This is a constructed exercise with invented numbers.

01 · Try this input

Input / starting state
Authorized user asks about current policy
Expected result
Grounded answer cites retrievable current document version

02 · Try this input

Input / starting state
User loses document access after embedding
Expected result
Neither snippets nor paraphrases derived from that document appear

03 · Try this input

Input / starting state
Index sync lags for 20 minutes
Expected result
Show a freshness limitation or refuse to answer where current truth is required

04 · Try this input

Input / starting state
Model produces a plausible citation that does not support claim
Expected result
Reject that citation/claim or mark answer uncertain. Never invent evidence

Design the permission boundary first

Keep a versioned document catalog with current ACL and deletion state. Retrieve candidates from an index, then authorize every candidate and citation against the live catalog before showing titles, snippets, or generated content. Cache by caller's authorization scope and document versions, with revocation-driven invalidation or a fresh authorization gate. Do not cache a final answer across users. A generation call receives only authorized excerpts. Validate claims against citations, measure unsupported answers and denial leakage in an evaluation set, and return a cautious response when retrieval or policy service is unavailable.

AWS box Job here Alternative and deciding factor
Amazon S3 (document store) Hold source bytes and version IDs Existing document system as authoritative source if access changes originate there
Amazon Bedrock Knowledge Bases (retrieval index) Parse, embed and retrieve candidate passages Amazon OpenSearch Service (search index) for direct control of lexical/vector retrieval
Amazon DynamoDB (authorization catalog) Hold current ACL and document state for final checks Amazon RDS if ACL relationships and transactions fit relational queries
Amazon Bedrock (model inference) Generate from authorized excerpts with citations Existing model serving stack with comparable isolation, observability, and budget
Amazon CloudWatch (telemetry) Monitor retrieval freshness, denial leaks, cost and latency Existing platform monitoring with measurable per-stage budgets

Bedrock Knowledge Bases synchronization after an update or deletion is an index maintenance step, not an instantaneous authorization revocation. Filter before model context. If uncertain about access, omit the passage. Distinguish document ingestion version, retrieval version, and ACL version in logs.

Senior follow-up: Retrieval runs out of time with two sources missing. Return a bounded partial answer or explicitly decline. Prove that fallback never relaxes permissions.

Staff follow-up: The source corpus spans business units with different retention and legal policies. Define ownership of metadata, deletion propagation, offline quality evaluation, and incident response when a citation leaked.

Practice artifact: Draw retrieval and authorization as separate boxes, trace one revoked paragraph through cache/index/model, and define five evaluation cases with expected citations or abstentions.

Source boundary: Original prompt. A June 2026 Spotify engineering article describes expert-owned data context. Bedrock sync documentation describes index refresh. Neither says this was a Spotify interview question.

Sources and further reading · 2