Skip to content

auth0-blog/ruby-rag-fga

Repository files navigation

Ruby on Rails RAG System with Auth0 FGA

This repository contains a sample project using a Ruby on Rails code sample that combines Retrieval-Augmented Generation (RAG) with Fine-Grained Authorization (FGA). Users authenticate via Auth0, and Auth0 FGA controls which documents each user can query — ensuring the LLM only answers from authorized content.

Read the article Secure a Ruby on Rails RAG System with Auth0 FGA to learn more.

⚠️ This project is intended for demonstration purposes only and is not meant for production use. ⚠️

Overview

  • Authentication: Auth0 Universal Login via OmniAuth
  • Fine-Grained Authorization: OpenFGA (Auth0 FGA) controls per-document access
  • Vector Search: PostgreSQL + pgvector with HNSW cosine similarity indexing
  • Embeddings: OpenAI text-embedding-3-small (1536 dimensions)
  • LLM Completions: OpenAI gpt-4o-mini
  • Frontend: Vanilla JavaScript chat interface

Tech Stack

Component Technology
Backend Ruby 4.0.1, Rails 7.1 (API mode)
Database PostgreSQL 17 + pgvector
Authentication Auth0 (omniauth-auth0)
Authorization OpenFGA (openfga-ruby-sdk)
Embeddings OpenAI text-embedding-3-small
LLM OpenAI gpt-4o-mini
Frontend Vanilla JS

Prerequisites

  • Ruby 4.0.1
  • PostgreSQL 17 with pgvector extension
  • An Auth0 tenant (Regular Web Application)
  • An Auth0 FGA store (or local OpenFGA instance)
  • An OpenAI API key

Installation

  1. Clone and install dependencies

    git clone <repository-url>
    cd ruby-rag-fga
    bundle install
  2. Set up PostgreSQL with pgvector

    brew install postgresql@17
    brew services start postgresql@17
  3. Create and seed the database

    rails db:create
    rails db:migrate
    rails db:seed

    This creates 5 sample documents (15 chunks total):

    • Ruby on Rails Guide
    • PostgreSQL Administration
    • Auth0 Identity Platform
    • OpenAI API Reference
    • Internal Company Roadmap 2026
  4. Configure environment variables

    cp .env.example .env

    Fill in your values (see Environment Variables below).

  5. Set up FGA authorization model and tuples

    rake fga:setup

    This writes the authorization model and creates owner tuples for all seeded documents. Copy the output FGA_MODEL_ID into your .env.

  6. Start the server

    rails server

    Visit http://localhost:3000 — you'll be redirected to Auth0 login.

Auth0 Configuration

Create a Regular Web Application in your Auth0 dashboard:

Setting Value
Allowed Callback URLs http://localhost:3000/auth/auth0/callback
Allowed Logout URLs http://localhost:3000

How It Works

End-to-End Flow

  1. User visits /chat → redirected to Auth0 Universal Login
  2. After authentication, user is created/updated in the database
  3. User sends a message in the chat interface
  4. FGA list_objects returns the document IDs the user can view
  5. Query is embedded via OpenAI
  6. pgvector nearest-neighbor search runs filtered to authorized documents only
  7. Top-k chunks are assembled into context and sent to the LLM
  8. Response is returned with sources and processing time

Authorization Model (OpenFGA)

type user

type document
  relations
    define owner: [user]
    define viewer: [user] or owner
  • owner implies viewer — document owners can always view their documents
  • viewer can be granted independently for shared access
  • The RAG pipeline calls list_objects before every query to enforce access

RAG Pipeline

User Question
  → FGA: list_objects (get authorized doc IDs)
  → OpenAI: generate query embedding
  → pgvector: nearest neighbors WHERE document_id IN (authorized IDs)
  → Build context from top-k chunks
  → OpenAI: generate completion with context
  → Return answer + sources

Project Structure

app/
  controllers/
    auth0_controller.rb       # Auth0 callback, logout
    chat_controller.rb         # Serves chat UI (requires auth)
    api/chat_controller.rb     # POST /api/chat endpoint
    concerns/secured.rb        # Authentication concern
  models/
    user.rb                    # Auth0 user with create_or_update_from_auth0
    document.rb                # Document with file_path and user association
    document_chunk.rb          # Vector-embedded chunks (neighbor gem)
  services/
    fga_service.rb             # OpenFGA client (list_objects, check, write)
    openai_service.rb          # Embeddings + completions
    rag_query_service.rb       # Orchestrates the full RAG + FGA pipeline
  views/
    chat/index.html.erb        # Chat interface
config/
  initializers/auth0.rb        # OmniAuth Auth0 configuration
lib/
  tasks/fga.rake               # Rake tasks for FGA setup
db/
  seeds.rb                     # 5 sample documents with chunks

API

POST /api/chat

Requires an authenticated session.

Request:

{ "message": "What is Active Record?" }

Response:

{
  "message": "What is Active Record?",
  "response": "Active Record is the Object-Relational Mapping (ORM) layer...",
  "sources": [
    {
      "document_title": "Ruby on Rails Guide",
      "chunk_index": 2,
      "content_preview": "Active Record is the Object-Relational...",
      "relevance_score": 0.92
    }
  ],
  "processing_time": 1.23
}

Rake Tasks

Task Description
rake fga:setup Write auth model + seed tuples (run once)
rake fga:write_model Write the authorization model only
rake fga:seed_tuples Create owner tuples for all documents

Environment Variables

Variable Description
OPENAI_API_KEY OpenAI API key
OPENAI_BASE_URL OpenAI-compatible base URL
AUTH0_CLIENT_ID Auth0 application client ID
AUTH0_CLIENT_SECRET Auth0 application client secret
AUTH0_DOMAIN Auth0 tenant domain (e.g. your-tenant.auth0.com)
FGA_API_URL FGA API URL (e.g. https://api.us1.fga.dev)
FGA_STORE_ID FGA store ID
FGA_MODEL_ID FGA authorization model ID
FGA_CLIENT_ID FGA client ID (client credentials)
FGA_CLIENT_SECRET FGA client secret
FGA_API_TOKEN_ISSUER FGA token issuer URL
FGA_API_AUDIENCE FGA API audience

Database Schema

  • usersname, email (unique), auth0_sub (unique)
  • documentstitle, file_path, user_id (FK)
  • document_chunkscontent, chunk_index, embedding (vector[1536], HNSW cosine index), document_id (FK)

License

Copyright 2026 Okta, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0

About

A sample RAG app implementing Auth0 FGA

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

No contributors