A rail-focused cyber readiness platform for training, triage, response planning, and vulnerability review.
Built with Next.js, React, Tailwind CSS, OpenAI Responses API, and the NVD CVE API.
Project note
RailSecure is built as a practical readiness tool for awareness, incident response drills, vulnerability review, and standards support in a rail and transport context. It uses real APIs and structured AI workflows, but it should still be treated as a decision-support tool rather than a substitute for internal policy, legal advice, or operational authority.
RailSecure brings several related jobs into one place.
Instead of bouncing between a phishing trainer, a playbook document, a vulnerability feed, a standards reference page, and a separate AI chat, the app keeps those workflows together in one clean workspace. The goal is to make day-to-day cyber readiness work easier, calmer, and more useful.
- At a Glance
- What the Platform Covers
- Feature Map
- How the App Fits Together
- Architecture
- AI Workflow and Guardrails
- Tech Stack
- Pages and User Flows
- API Routes
- Getting Started
- Environment Variables
- Available Scripts
- Deployment on Vercel
- Project Structure
- Implementation Notes
- Verification
| Area | Summary |
|---|---|
| Purpose | A rail-sector cyber readiness workspace with guided training and operational support |
| Frontend | Next.js App Router with React 19 |
| AI model default | gpt-5.4-mini |
| AI style | Task-specific workflows with structured outputs, not one generic chatbot |
| Data sources | OpenAI Responses API and NVD CVE API 2.0 |
| Storage | No database in the current build |
| Password handling | Local-only generation and strength checking in the browser |
| Deployment target | Vercel |
RailSecure includes:
- phishing simulation and email triage
- password generation and local strength checks
- incident scenario drills
- incident playbook generation
- playbook draft comparison
- scoped compliance support
- curated reference guidance
- live NVD vulnerability review
- awareness content built around real rail and transport incidents
That mix is intentional. The app is designed to help someone move from awareness to triage to action without losing context halfway through.
| Area | Route | What it does | Why it matters |
|---|---|---|---|
| Overview | / |
Introduces the platform and links to each module | Gives the app a clear front door |
| Phishing Lab | /phishing |
Generates phishing simulations, scores analyst responses, and triages pasted emails | Useful for awareness training and first-line email review |
| Password Studio | /passwords |
Generates passwords in the browser and checks password strength locally | Keeps sensitive password input off the backend |
| Incident Lab | /incident-lab |
Generates realistic incident scenarios and evaluates response strategies | Supports drills and tabletop exercises |
| Playbooks | /playbooks |
Builds scenario-specific playbooks and compares them against user drafts | Helps improve response quality and consistency |
| Quiz | /quiz |
Creates short multiple-choice awareness checks | Good for quick knowledge checks and workshop use |
| Compliance | /compliance |
Answers scoped questions about controls, reporting, governance, and defensive tooling | Turns standards and obligations into practical guidance |
| Vulnerabilities | /vulnerabilities |
Pulls CVEs from NVD, supports filtering, and adds AI explanations | Makes vulnerability review more useful than a flat feed |
| References | /references |
Curated standards and guidance library plus a scoped explainer assistant | Keeps official anchors close to the answer |
| Awareness | /awareness |
Presents real transport and rail incidents, recurring patterns, and discussion prompts | Useful for awareness sessions and resilience conversations |
flowchart TD
A["User"] --> B["Next.js App Router UI"]
B --> C["Page Components"]
C --> D["/api/ai"]
C --> E["/api/cves"]
D --> F["Input validation with Zod"]
D --> G["Guardrails and moderation"]
D --> H["Task-specific AI workflows"]
H --> I["OpenAI Responses API"]
E --> J["NVD CVE API 2.0"]
H --> K["Structured JSON output parsing"]
K --> C
J --> C
The key design decision is that RailSecure does not behave like a free-form chat app. Each feature uses a narrow, well-defined workflow with a schema behind it, which keeps the results more predictable and much easier to present cleanly in the UI.
flowchart LR
subgraph Frontend
A1["App Router pages"]
A2["Reusable UI components"]
A3["Client helpers"]
end
subgraph Server
B1["API routes"]
B2["Guardrails"]
B3["AI orchestration"]
B4["NVD fetch layer"]
B5["Schemas"]
end
subgraph External services
C1["OpenAI API"]
C2["NVD API"]
end
A1 --> A2
A2 --> A3
A1 --> B1
B1 --> B2
B1 --> B3
B1 --> B4
B3 --> B5
B3 --> C1
B4 --> C2
| Choice | Why it matters |
|---|---|
| Route-based modules | Each workflow has a clear home, which makes the app easier to navigate and maintain |
| Structured AI outputs with Zod | The UI gets typed, validated data instead of messy free-form text |
| Server-side guardrails | Helps prevent prompt injection, scope drift, and malformed requests |
| Local-only password checks | Sensitive inputs do not need to leave the browser |
| Dedicated NVD route | Vulnerability fetching and normalization stay separate from UI concerns |
| Shared follow-up and export actions | Results can be copied, downloaded, simplified, or reframed quickly |
RailSecure uses the OpenAI Responses API through task-specific helper functions in lib/railsecure-ai.ts.
Each AI workflow follows the same basic shape:
- validate the input payload with Zod
- apply text limits and sanity checks
- run prompt-injection checks
- optionally moderate the input
- call a task-specific AI workflow
- request structured output
- parse and validate the returned JSON before sending it to the UI
sequenceDiagram
participant U as User
participant UI as UI module
participant API as /api/ai
participant G as Guardrails
participant AI as RailSecure AI layer
participant O as OpenAI
U->>UI: Submit a task
UI->>API: POST action and payload
API->>G: Validate, limit, and scope-check
G-->>API: Safe input or refusal
API->>AI: Run task-specific workflow
AI->>O: Responses API request
O-->>AI: Structured output
AI->>AI: Parse and validate JSON
AI-->>API: Typed result
API-->>UI: JSON response
UI-->>U: Render structured output
| Layer | What it checks |
|---|---|
| Input trimming and length limits | Empty input, oversized text, and basic input quality |
| Prompt injection patterns | Attempts to override the workflow or reveal hidden instructions |
| Moderation | Flags unsafe content before the main model call when needed |
| Scope checks | Blocks generic coding or unrelated prompts in the scoped assistants |
| Structured output validation | Rejects malformed model output before it reaches the UI |
The compliance and reference assistants are intentionally narrow.
- The compliance assistant is for rail-sector cybersecurity compliance, controls, reporting, governance, awareness, and defensive tooling.
- The reference assistant is for standards, official guidance, sector practice, and related explanation.
- Neither assistant is intended to act as a general coding helper.
| Variable | Default |
|---|---|
OPENAI_MODEL |
gpt-5.4-mini |
OPENAI_FAST_MODEL |
gpt-5.4-mini |
OPENAI_MODERATION_MODEL |
omni-moderation-latest |
| Category | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16.2.1 | Routing, rendering, and production build pipeline |
| UI | React 19 | Component model and interactive client features |
| Styling | Tailwind CSS 4 | Layout, design tokens, and utility styling |
| AI SDK | OpenAI Node SDK | Responses API and moderation integration |
| Validation | Zod | Input and output schemas |
| Markdown | react-markdown and remark-gfm |
Clean rendering of exported or AI-generated markdown content |
| Password scoring | zxcvbn |
Local browser-side password strength analysis |
| Vulnerability data | NVD CVE API 2.0 | Live CVE feed and KEV-aware filtering |
| Icons | lucide-react |
UI iconography |
The phishing module supports two practical jobs:
- generate a safe phishing simulation
- review a pasted email for likely phishing risk
It also supports follow-up actions such as:
- explain simply
- top actions
- manager brief
- go deeper
The password module is deliberately local-first.
- password generation uses browser cryptography
- password scoring uses
zxcvbn - manual password checks stay in the browser
This page generates realistic scenarios and then reviews a proposed first response. The feedback is built around:
- containment
- escalation
- communications
- evidence handling
- recovery priorities
- reporting considerations
The playbook builder uses a six-phase structure:
| Phase |
|---|
| Preparation |
| Identification |
| Containment |
| Eradication |
| Recovery |
| Lessons learned |
Users can also compare their own draft against the generated playbook to identify:
- aligned areas
- missing areas
- risky gaps
- next improvements
The quiz module creates short multiple-choice checks with:
- 2 to 6 questions
- four answer options per question
- immediate scoring
- explanations after submission
This page combines a control and tooling map with a scoped assistant that can answer questions about:
- NIS2
- GDPR
- CER
- ISO 27001
- IEC 62443
- governance
- controls
- awareness programme design
- defensive OT and IT tooling
The vulnerability page turns the NVD feed into a more usable operator view:
- keyword search
- severity filters
- date range filters
- KEV-only filtering
- severity context
- AI-generated CVE summaries
- export and follow-up actions
This module combines:
- curated official links
- standards and guidance references
- a scoped explainer assistant
- source-linked outputs where relevant
The awareness page is built to support discussions and workshops. It includes:
- transport and rail cyber incidents
- recurring patterns across those incidents
- discussion prompts
- practical resilience framing
| Route | Method | Purpose |
|---|---|---|
/api/ai |
POST |
Handles structured AI actions such as phishing generation, scenario review, playbook generation, compliance answers, CVE explanations, and follow-up rewrites |
/api/cves |
GET |
Fetches, normalizes, and filters NVD vulnerability data for the vulnerability explorer |
| Action |
|---|
phishing.generate |
phishing.evaluate |
phishing.analyze |
scenario.generate |
scenario.evaluate |
guide.generate |
guide.compare |
compliance.answer |
reference.answer |
cve.explain |
followup.rewrite |
quiz.generate |
- Node.js 20 or newer is recommended
- npm
- an OpenAI API key
- optionally, an NVD API key for better headroom on vulnerability requests
npm installCreate a .env.local file in railsecure-vercel/ and add the variables you need:
OPENAI_API_KEY=your_openai_api_key
OPENAI_MODEL=gpt-5.4-mini
OPENAI_FAST_MODEL=gpt-5.4-mini
OPENAI_MODERATION_MODEL=omni-moderation-latest
NVD_API_KEY=your_nvd_api_keynpm run devThen open http://localhost:3000.
| Variable | Required | Purpose |
|---|---|---|
OPENAI_API_KEY |
Yes | Authenticates requests to OpenAI |
OPENAI_MODEL |
No | Primary model for structured generation tasks |
OPENAI_FAST_MODEL |
No | Faster model path for lighter tasks such as quizzes, follow-ups, and CVE explainers |
OPENAI_MODERATION_MODEL |
No | Model used for moderation checks |
NVD_API_KEY |
No | Used when calling NVD for better rate-limit headroom |
| Script | What it does |
|---|---|
npm run dev |
Starts the local development server |
npm run build |
Creates a production build |
npm run start |
Runs the production server |
npm run lint |
Runs ESLint across the app |
RailSecure is structured to deploy cleanly on Vercel.
- Push the
railsecure-vercelapp to a Git repository. - Import the project into Vercel.
- Add the environment variables in the Vercel dashboard.
- Deploy.
- The app uses App Router and fits naturally into the Vercel deployment model.
- The AI and NVD routes run on the Node.js runtime.
- No database setup is required for the current version.
- Sensitive values should live in environment variables, not in committed source.
railsecure-vercel/
+-- app/
| +-- api/
| | +-- ai/route.ts
| | \-- cves/route.ts
| +-- awareness/page.tsx
| +-- compliance/page.tsx
| +-- incident-lab/page.tsx
| +-- passwords/page.tsx
| +-- phishing/page.tsx
| +-- playbooks/page.tsx
| +-- quiz/page.tsx
| +-- references/page.tsx
| +-- vulnerabilities/page.tsx
| +-- globals.css
| +-- layout.tsx
| \-- page.tsx
+-- components/
| +-- assistant-guidance-panel.tsx
| +-- compliance-workbench.tsx
| +-- follow-up-panel.tsx
| +-- incident-lab.tsx
| +-- password-studio.tsx
| +-- phishing-lab.tsx
| +-- playbook-builder.tsx
| +-- quiz-board.tsx
| +-- reference-library.tsx
| +-- result-actions.tsx
| +-- shell-card.tsx
| +-- status-pill.tsx
| \-- vulnerability-explorer.tsx
+-- lib/
| +-- client.ts
| +-- content.ts
| +-- guardrails.ts
| +-- nvd.ts
| +-- openai.ts
| +-- railsecure-ai.ts
| +-- schemas.ts
| \-- utils.ts
+-- public/
| \-- assets/
\-- README.md
| File | Role |
|---|---|
app/layout.tsx |
Global shell, navigation, footer, and page framing |
app/page.tsx |
Overview page |
lib/railsecure-ai.ts |
Task-specific AI orchestration and structured output handling |
lib/guardrails.ts |
Input checks, moderation, and scope enforcement |
lib/nvd.ts |
NVD fetch and normalization layer |
lib/content.ts |
Static content, module options, references, incidents, and page copy |
lib/schemas.ts |
Input and output schemas for AI actions |
components/result-actions.tsx |
Copy and download actions for generated content |
components/follow-up-panel.tsx |
Rewrites and alternate views for an existing result |
The app leans heavily on structured AI responses because they are much easier to validate and render cleanly.
If a model response is malformed:
- the server attempts to clean and extract the JSON candidate
- the JSON is validated against the relevant schema
- the call can retry with more output room when needed
The NVD layer:
- clamps
daysandlimitvalues into safe ranges - supports keyword and severity filtering
- supports KEV-only filtering
- normalizes CVSS and weakness data
- adds a timeout so requests do not hang indefinitely
The password tooling is intentionally local:
- generation uses
crypto.getRandomValues - checking uses
zxcvbnin the browser - manual password analysis does not need a server round trip
The current build does not include:
- user accounts
- gamification
- persistent user history
- database-backed storage
That is intentional for this version.
The current project has been checked with:
npm run lint
npm run buildBoth commands pass on the current codebase.
RailSecure is meant to be useful in the plain, practical sense of the word. It should help someone run a quick drill, brief a manager, review a vulnerability, or sharpen a response plan without having to jump between too many tools or reframe the same problem over and over.
That is the standard this version was built around.