Building a Secure Flight Booking AI Agent with Langflow
- Share:
LangFlow allows developers and non-developers alike to build AI applications through a visual, drag-and-drop interface. It makes it easier to work with LLMs in workflows and, therefore, serves as the primary tool for developing AI applications.
When these applications handle sensitive data such as financial details, security becomes a top priority. Without proper safeguards, there’s a risk of unauthorized access to personal information or critical operations, which could erode user trust and compromise the system.
There are four key perimeters to implement this type of protection in LangFlow applications. Those are:
- Prompt Filtering: Ensures user inputs align with predefined access policies.
- RAG Protection: Controls who can access retrieved data based on their permissions.
- Secure External Access: Limits interactions with external APIs to authorized users only.
- Response Enforcement: Guarantees that users only see the information they’re permitted to view.
In this guide, we’ll use these perimeters to build a secure flight booking system from the ground up. To do that, we’ll use Permit.io, an authorization service, to enforce access controls at every stage. The tutorial will cover creating AI-based workflows for searching flights, checking travel policies, and booking trips, all while keeping sensitive data safe.
Tool Overview
Before we get our hands dirty, let’s examine the tools we will use to build this application.
- Langflow is a low-code framework that enables developers to visually design and deploy AI apps with LLMs. It simplifies the integration of AI components by allowing you to create complex workflows via a drag-and-drop interface. In our project, we’ll use Langflow to build three workflows: flight search, information queries, and booking operations, connecting our LLM components with security layers.
- Permit.io is an authorization-as-a-service that helps developers implement fine-grained access control in their application. In our system, it will handle access control by protecting sensitive flight data and implementing rules like “only verified users can book flights” or “premium members can access special rates.”
Together, these two tools help us create a secure flight booking pipeline: managing workflows and ensuring every operation follows security rules from search to booking.
Prerequisites
This tutorial assumes you have:
- Basic knowledge of Attribute Based Access Control
- An Astra DB vector database with:
- An Astra DB application token
- A collection in Astra
Configuring Attribute-Based Access Control Policies
Before we start building our AI agent flow, let’s configure our authorization model in Permit.io.
Here’s what we want our policy to restrict:
- Regular users should be able to search for flights but not see sensitive details like seat availability or pricing.
- Premium members should get extra privileges, like booking, modifying, and accessing detailed flight data.
- Regional users should only be able to search for flights in their allowed area.
- Unverified users should have very limited access—they’ll see basic flight info but can’t book or modify anything.
To enforce these rules, we’ll need to create the following resources, actions, attributes, and condition sets:
Resources:
Flight
- Available Actions:
search
,info
,viewprice
,viewavailability
- Attributes:
type
(String) – Specifies the type of operation (info, search, booking).sensitivity
(String) – Defines data sensitivity (public, protected, private).
Booking
- Available Actions:
create
,modify
,cancel
,view
- Attributes:
type
(String) – Defines booking operation types.sensitivity
(String) – Controls access to booking data based on its sensitivity.
User Attributes
User access is determined by three key attributes:
membership_tier
(Array) – Defines a user's access level (e.g.,basic
,premium
).region
(String) – Specifies the user’s geographical location (domestic
,international
).verified
(Boolean) – Indicates if the user’s identity has been confirmed (true
/false
).
Condition Sets
These condition sets define who can access what, controlling how users interact with resources:
Membership Tier Access:
user.membership_tier
includesresource.class
ANDuser.verified == true
Regional Restrictions:
user.region == "domestic"
Sensitive Data Access:
user.membership_tier
includes"premium"
Let’s set up attribute-based (ABAC) policies using the Permit.io dashboard.
Setup a New Project and Credentials
To get started, let’s set up a new project and get credentials to connect Permit SDK to our project. To do that, follow the steps:
- Create a Permit.io account if you haven’t already
- Create a new project named
flight-booking
in the dashboard - Select your preferred environment (Development/Production) and copy your API Key
Define Resources
- Navigate to Policy → Resources in your Permit.io dashboard.
- First, let’s create a
flight
resource. This will handle everything related to flight information and searches:
{
"actions": [
"search", // Search for available flights
"info", // Get flight details
"viewprice", // Access pricing information
"viewavailability" // Check seat availability
],
"attributes": {
"type": "String", // Controls the type of operation ("info", "search", "booking")
"sensitivity": "String" // Defines data sensitivity ("public", "protected", "private")
}
}
- Next, create a booking resource for managing actual flight bookings:
{
"actions": [
"create", // Create new bookings
"modify", // Change existing bookings
"cancel", // Cancel bookings
"view" // View booking details
],
"attributes": {
"type": "String", // Defines booking operation types
"sensitivity": "String" // Controls booking data sensitivity
}
}
User Attributes
Now, let’s define user attributes to enable fine-grained access control based on user properties like membership tier, region, and verification status.
In Directory → Users → Settings page, define the following user attributes:
{ "membership_tier": "Array", "region": "String", "verified": "Boolean"}
Creating Condition Sets
Now let’s configure the condition sets for our flight booking system:
- Navigate to Policy → ABAC Rules
- Click ABAC User Sets
- Create the following sets:
For membership tier access:
user.membership_tier includes resource.class AND user.verified == true
For regional restrictions:
user.region == "domestic"
For sensitive data access:
user.membership_tier includes "premium"
Enforcing Policies
Now we’ll use the policy editor to enforce our access control rules. In the policy matrix, you’ll see our resources and actions with checkboxes for each condition set at the top:
For the
booking
resource:cancel: - ✓ members □ regional □ sensitive create: - ✓ members ✓ regional ✓ sensitive modify: - ✓ members □ regional ✓ sensitive view: - ✓ members □ regional □ sensitive
For the
flight
resource:info: - □ members □ regional □ sensitive (public access) search: - □ members ✓ regional □ sensitive viewavailability: - ✓ members □ regional □ sensitive viewprice: - ✓ members □ regional ✓ sensitive
These checkboxes enforce our conditions, when multiple boxes are checked for an action, all conditions must be satisfied for the action to be allowed.
Now our access control infrastructure is properly configured, let’s start building our flows.
Building the Flows
Now that we’ve set up our access control infrastructure, let’s build our Flight Booking Agent! We’ll create three flows that demonstrate how to implement security while providing a great user experience.
Setting up local PDP container
First, you’ll need to run your local PDP container for Permit’s ABAC policies:
docker pull permitio/pdp-v2:latest
docker run -it -p 7766:7000 \\
--env PDP_DEBUG=True \\
--env PDP_API_KEY=<YOUR_API_KEY> \\
permitio/pdp-v2:latest
Replace <YOUR_API_KEY>
with your Permit API Key. If you don’t have Docker, install it from here.
Flight Search Flow
Let’s build our first and most fundamental flow the flight search. This flow will help users find available flights while ensuring they only see what they’re authorized to access.
First, we’ll gather all the components we need. Open your Langflow canvas and from the components panel, drag over a Text Input (we’ll use this for the JWT token), a Chat Input (for the actual search queries), and a JWT Validator. You’ll also need a Permission Check component. This is important for our security layer. Add an If-Else Router, City Selection Agent, Astra DB, Parse Data, and two Chat Output components.
Now, let’s set up each component carefully. Start with the Text Input, this is where you enter your JWT token. Next, configure your JWT Validator with your JWKS URL:
JWKS URL: "<https://test.com/.well-known/jwks.json>"
// Replace with your actual JWKS URL
For the Permission Check component, you’ll need to input your Permit.io credentials and specify what resource we’re protecting:
PDP URL: "<http://localhost:7766>" // Your local PDP endpoint
API Key: "your-permit-api-key" // Your Permit.io API key
Resource: "flight"
Action: "search"
The City Selection Agent is where things get interesting. This is our intelligent assistant that will parse user queries and format them properly. Configure it like this:
Model: gpt-4o-mini
Agent Instructions: "You are a flight search assistant. Your job is to:
1. Extract departure and arrival cities from user queries
2. Validate that these are real cities with airports
3. Format the search request for our database
4. Handle cases where cities are unclear or invalid"
For the database interaction, set up your Astra DB component with your database details:
Collection Name: "flights"
Database: "flight_db" // Your database name
Finally, the Parse Data component will format our results nicely for users:
Template:
"""
Flight {row_number}: {departure_city} to {arrival_city}
Departure: {departure_time}
Airline: {airline}
Flight Number: {flight_number}
Price: ${price}
Available Seats: {seats}
"""
Now comes the important part - connecting everything together. Start by connecting your Text Input’s Message output to the JWT Validator’s JWT Token input. The Chat Input’s “Message” output should go to the If-Else Router’s True Input input.
Now click the Playground and try some realistic search queries like “Find flights from New York to London next week” or “Show me flights from SFO to JFK tomorrow morning”. If everything is working correctly, you’ll either see a nicely formatted list of flights (for authorized users) or an access denied message (for unauthorized users).
Flight Information Flow
Next, let’s create a flow that handles flight policy and information queries. This flow is a bit different from our search flow, instead of searching flight schedules, it helps users understand policies, baggage rules, and other travel information.
Start by gathering your components. Like before, you’ll need some familiar components:
- Text Input for the JWT token
- Chat Input for questions
- JWT Validator
- Permission Check.
Now we’re also adding a Local Expert Agent who will be our knowledge base expert, along with a URL Component to fetch policy information. Don’t forget the Parse Data component and two Chat Outputs for handling both successful and denied requests.
The JWT Validator setup remains the same as our search flow, no need to change that configuration. For the Permission Check, we’ll adjust it slightly for information access:
PDP URL: "<http://localhost:7766>"
API Key: "your-permit-api-key"
Resource: "flight"
Action: "info"
Here’s where it gets interesting, our Local Expert Agent. This is the brain of our information flow, so let’s configure it carefully:
Mode: gpt-4o-mini
Instructions: "You are a knowledgeable Local Expert that provides accurate flight policy and service information. You should:
1. Answer questions about baggage policies
2. Explain flight rules and restrictions
3. Provide information about services and amenities
4. Always maintain privacy by not revealing sensitive pricing or route details without authorization"
To give our Expert Agent access to accurate information, set up the URL Component with our policy endpoints:
URLs: ["<https://api.flightpolicies.com/baggage>", "<https://api.flightpolicies.com/services>"]
Output Format: "Text"
To present the information clearly, configure the Parse Data component with this template:
Template:
"""
Policy Information:
------------------
{policy_title}
Details:
{policy_details}
Additional Information:
{additional_info}
------------------
"""
The connections here create a flow of information from user query to expert response. Connect your Text Input to the JWT Validator and then the Chat Input to the If-Else Router’s True Input. The JWT Validator feeds into the Permission Check, which determines if the user can access the information.
When testing this flow, try asking natural questions like “What’s the baggage allowance for international flights?” or “Tell me about your pet travel policy.” The Expert Agent will provide detailed, accurate responses while respecting security boundaries.
Flight Booking Flow
Let’s build our most secure flow - the booking system. Looking at the components in the screenshot, we’ll need both standard security components and some specialized ones for handling bookings.
- Add these components to your canvas:
- Text Input & Chat Input (for token and booking requests)
- JWT Validator (for authentication)
- Data Protection (for securing resources)
- Permission Check (for booking authorization)
- If-Else Router (for routing based on permissions)
- API Request (for making bookings)
- OpenAI & Data to Message (for handling responses)
- Filter Data (for processing results)
- Astro Assistant Agent (for managing booking interactions)
- Chat Output (for user responses)
- Let’s configure the components:
JWT Validator settings:
JWKS URL: "<https://test.com/.well-known/jwks.json>"
Data Protection and Permission Check settings:
PDP URL: "<http://localhost:7766>"
API Key: "your-permit-api-key"
Resource Type/Resource: "booking"
Action: "create"
API Request settings:
URL: "<https://api.flights.com/v1/bookings>"
Method: "POST"
OpenAI settings:
Model Name: gpt-4o-mini
Temperature: 0.15
Stream: off
If-Else Router settings:
Match Text: "True"
Operator: "equals"
Case Sensitive: off
Assistant Agent settings:
Model: gpt-4o-mini
Agent Instructions: "You are a booking assistant that helps process flight booking requests..."
- Looking at the screenshot, connect the components this way:
- Text Input connects to the JWT Validator
- Chat Input splits to OpenAI and Permission Check
- JWT Validator links to both Permission Check and Data Protection
- Permission Check’s “Allowed” output goes to the API Request
- Data Protection connects to Filter Data
- API Request feeds into the Assistant Agent
- Everything routes to appropriate Chat Outputs
When testing, try some booking requests and watch how each security layer validates the request before allowing the booking to proceed.
Conclusion
We’ve built a secure flight booking system that demonstrates all four Langflow security perimeters. The JWT Validator handles Prompt Filtering by validating JWTs and extracting user IDs, ensuring only authorized inputs like flight searches or booking requests move forward. RAG Protection is powered by the Data Protection component, which restricts retrieved data to allowed resource IDs, keeping sensitive flight and booking details safe. The Permissions Check component enforces Secure External Access, checking if users can perform actions like accessing APIs for bookings, with distinct outputs for allowed or denied requests. Finally, Response Enforcement is achieved through the combined efforts of Permissions Check and Data Protection, shaping what users see, such as tailored flight lists or policy info based on their permissions and authorized data.
By integrating Langflow’s AI prowess with Permit.io’s access control, we’ve created a system that:
- Protects sensitive travel data
- Enforces appropriate access levels
- Maintains security across all operations
- Provides a smooth user experience
Security in AI applications goes beyond data protection—it’s about building trust while delivering what users need. As you craft your own projects, consider adapting these perimeters to your goals.
Happy building! Got questions? Need help? Join our Slack community!
Written by
Ekekenta Clinton
Senior Technical Writer | Developer Advocate focused on Web Development Technologies | Community Manager | API Documentation | Documentation Engineer | Docs-as-Code | Jira | Markdown