awslabs / awslabs/agentcore-samples
02-use-cases - [New Sample] Multi-tenant corporate travel assistant (Travel & Hospitality)
- Dominant language
- Python
- Stars
- 3.4k
- Forks
- 1.3k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 30
Description
A conversational agent sample for **corporate/managed travel** — the pattern
behind travel management companies (TMCs) and online booking tools: **one
agent serving many corporate clients**, where each client's travelers,
policies, and trip data must stay isolated.
The assistant acts for a fictional TMC ("AnyCompany Travel") whose corporate
clients are two fictional companies. Everything is fictional and self-seeded
— no third-party API keys, no real customer data.
### Why this sample
**Vertical gap.** The repository includes general travel examples, including
the Harness travel agent and consumer-focused travel concierge blueprint, but
no end-to-end **corporate/managed travel** sample. None demonstrates one TMC
serving multiple corporate tenants with isolated traveler data, tenant-specific
policies, deterministic eligibility, booking workflows, cost attribution, and
human escalation.
**There is an open request for the core mechanism.** #864 ("Multi-tenant
content filtering at row-level based on logged in user") asks for exactly this
— *"determine who the logged in user is and have a row-level access control on
the data ingested… let the AgentCore gateway and interceptors take care of
translating to the calling user"* — and has had no reply since January. This
sample is a worked answer to it, in a domain where getting it wrong means
showing one company's negotiated rates to another.
**Pattern gap.** Three things this sample demonstrates that I couldn't find
covered together anywhere in the repo:
1. **Multi-tenant data isolation inside a single shared agent** — tenancy of
_data and identity_, not tenancy of deployed agents. Enforced in **eight
layers that each refuse a cross-tenant request independently**: Cognito
claims → Cedar (AgentCore Policy) for tool authorization → a Gateway
interceptor that _overwrites_ client-supplied identity headers rather than
validating them → tool schemas carrying no tenant field at all → IAM
(`dynamodb:LeadingKeys` with a tenant session tag) → the travel platform
answering another tenant's traveller with a 404 rather than a 403 →
per-tenant KB metadata filters built server-side from the verified claim →
`AWS_IAM` on the platform's own API. **No tool schema has a `tenant_id`
parameter**, so there is no argument for a prompt injection to poison, and
the IAM layer matters because app-layer tenant checks can be injected
around; IAM can't be. (Guardrails are a content filter here, not a tenancy
control — listing them as an isolation layer would overstate them.)
2. **Unit economics** — a per-step token/spend ledger yielding **cost per
resolved task**, attributed per tenant, with **cost and quality in one CI
gate** (a change that improves accuracy 2 points and triples spend
shouldn't merge silently).
3. **Graceful human escalation** — when the agent can't resolve, or a spend/
step budget trips, it assembles a full handoff package (summary, trip state,
what was already tried, and the session id the transcript and the cost
ledger both join on) and hands off to a human agent. **The context
package is the contribution; the contact-centre transport is a documented
extension point** — one call delivers it to Amazon Connect, Genesys,
ServiceNow or a queue, so the sample never requires a Connect instance to
deploy. This is the first question enterprises ask about any
customer-facing agent, and the escalation is treated as a _resolved path_
in the metrics, not a failure.
### Relationship to existing samples (complementary, not overlapping)
| Existing | What it covers | How this differs |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `05-blueprints/travel-concierge-agent` | agentic **payments** in a consumer-travel skin (web-search tools, card tokenization) | corporate/managed travel: tenant isolation, policy enforcement, cost attribution, escalation. No payment-rail integration — references that blueprint instead |
| `05-blueprints/multitenant-agentic-platform` | multi-tenant **platform** for deploying per-tenant agents; per-tenant token metering | one shared agent, many tenants' data; isolation enforced in IAM/Cedar; cost per _resolved outcome_, not tokens alone |
| `02-use-cases/01-conversational-agents/lakehouse-agent` | row-level security via OAuth claims (Athena) | same claims→enforcement idea, applied across DynamoDB keys, KB filters, and tool authorization |
| `02-use-cases/02-workflow-automation-agents/visa-b2b-account-payable-agent` | real payment-rail integration | payment is a mock corporate-instrument reference; card data never enters agent context |
I'd cite all four in the README so readers can navigate between them.
### AgentCore features the sample exercises
Runtime (Strands, streaming) · Gateway (Lambda targets) · Identity (Cognito, custom claims,
pre-token-generation Lambda) · Policy (Cedar authorization) · Memory
(observed preferences, distinct from the profile system-of-record) ·
Observability (traces + the cost ledger) · **Evaluations** (deterministic
code-based evaluators behind an on-demand CI gate that reads cost and quality
together, plus LLM-as-judge evaluators declared in `agentcore.json` and
deployed) · Guardrails (PII anonymised at the model's output, as a backstop —
the tool layer curates PII before it ever reaches the model).
### Shape of the sample
- **Mock TMC backend** — FastAPI on Lambda behind API Gateway, DynamoDB +
seeded data (trips, bookings, PII-rich traveler profiles, per-tenant
policies, reference data). A **private-VPC topology** — VPC-attached tool
Lambdas, interface endpoints, no NAT, so Bedrock and DynamoDB traffic never
touches the internet — ships behind an opt-in `--private` flag rather than as
the default, because 11 interface endpoints across two AZs is ~$161/month
standing and a reader cloning a sample should not meet that on an invoice.
Deploying public first and adding `--private` later is the supported path,
and a verification script asserts the topology and its endpoint policies.
- **14 tools across 9 Lambda targets** shaped as _capabilities, not endpoints_ — composite search
(lookup→search→annotate hidden in code), a deterministic policy-eligibility
verdict (computed in Python, narrated by the model — never inferred),
PII-curating profile/trips tools, location tools, escalation. Policy prose is
retrieved from a knowledge base **through a Lambda target**, not queried
directly: the per-tenant metadata filter has to be built server-side from the
verified claim, so wrapping retrieval in a tool is what makes the isolation
hold. That is the Lambda-vs-direct-target decision doing real work rather
than illustrating it.
- **Structured response contract** — typed cards (with actions/buttons) for
channels with pixels, computed facts for the model to narrate, provenance
for audit. No model-authored HTML.
- **Two seed tenants with opposite policies** so isolation is provable in a
30-second demo: same question, two travelers, two correct answers.
- **React demo UI**; escalation ships as the context package with a documented
transport extension point, so no contact-centre dependency to deploy.
### Quality commitments
Native `bedrock-agentcore` SDK (no starter toolkit) · `agentcore.json` + CDK
(AgentCore CLI v2) · one-command `deploy.sh` · README with Introduction, Architecture Diagram,
Prerequisites, Usage, Sample Prompts, Clean Up · seed data so the demo runs
without external accounts · cost estimate · honest feature claims (every
feature listed above is exercised in code, not just described in docs) ·
evaluator set + CI gate · cleanup script.
Contributor guide
Research direction
Start by comparing the existing travel-concierge-agent, multitenant-agentic-platform, lakehouse-agent, and visa-b2b-account-payable-agent samples. Then review the stated agentcore.json, CDK, deploy.sh, README, seed-data, evaluator, verification, and cleanup requirements. Done means a self-seeded corporate travel sample exercises the listed isolation, policy, cost, escalation, UI, evaluation, and deployment paths without external accounts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, fastapi, python, react
- Domain
- ai, authentication, authorization, backend, cloud, databases, frontend, full-stack, observability, security, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100