Skip to content

dreaminhex/saffron

Repository files navigation

The SpiceDB UI

A modern web interface for managing SpiceDB authorization systems. Built with Next.js and Tailwind CSS.

Screenshots

Dashboard
Schema Editor
Relationships
Permission Check
Terminal
Settings or Misc

Features

  1. Dashboard - Real-time overview of your SpiceDB instance with stats and activity
  2. Schema Management - Visual and text-based schema editor with validation
  3. Relationship Management - CRUD operations with smart dropdowns and search
  4. Authorization Testing - Permission checks, expansions, and subject lookups
  5. Zed Terminal - Run zed commands against the connected SpiceDB instance

Table of Contents

  1. Screenshots
  2. Features
  3. Prerequisites
  4. Quick Start
  5. Configuration
  6. Mock Data
  7. Usage
  8. API Endpoints
  9. Tech Stack
  10. Troubleshooting
  11. Development
  12. License
  13. Links

Prerequisites

  • Node.js 18+
  • Docker & Docker Compose (for containerized setup)

Quick Start

Option 1: Docker Compose (Recommended)

The easiest way to get started with both SpiceDB and Saffron:

  1. Clone and install

    git clone https://github.com/dreaminhex/saffron.git
    cd saffron
    npm install
  2. Start everything with Docker Compose

    docker-compose up -d

    This starts:

    • PostgreSQL (SpiceDB's datastore)
    • SpiceDB (authorization service)
    • Saffron UI
  3. Run database migrations (first time only)

    docker-compose exec spicedb spicedb datastore migrate head --datastore-engine postgres --datastore-conn-uri "postgres://spicedb:spicedb@postgres:5432/spicedb?sslmode=disable"
  4. Initialize with mock data

    Windows (PowerShell):

    .\init-spicedb.ps1

    Linux/Mac/WSL:

    chmod +x init-spicedb.sh
    ./init-spicedb.sh
  5. Access the application

    Open http://localhost:7777

Option 2: Local Development

For development, run SpiceDB in Docker but Saffron locally:

  1. Clone and install

    git clone https://github.com/dreaminhex/saffron.git
    cd saffron
    npm install
  2. Start only SpiceDB services

    docker-compose up -d postgres spicedb
  3. Run database migrations (first time only)

    docker-compose exec spicedb spicedb datastore migrate head --datastore-engine postgres --datastore-conn-uri "postgres://spicedb:spicedb@postgres:5432/spicedb?sslmode=disable"
  4. Initialize SpiceDB with mock data

    Windows (PowerShell):

    .\init-spicedb.ps1

    Linux/Mac/WSL:

    chmod +x init-spicedb.sh
    ./init-spicedb.sh
  5. Run Saffron locally

    npm run dev

    The .env.local file is already configured to connect to the correct SpiceDB HTTP and gRPC endpoints. If you change ports or run SpiceDB elsewhere, update this file accordingly.

    Open http://localhost:7777

Option 3: Manual SpiceDB Setup

If you want to run SpiceDB without Docker Compose (requires manual PostgreSQL setup):

  1. Start PostgreSQL

    docker run -d --name spicedb-postgres \
      -e POSTGRES_USER=spicedb \
      -e POSTGRES_PASSWORD=spicedb \
      -e POSTGRES_DB=spicedb \
      -p 5432:5432 \
      postgres:15-alpine
  2. Start SpiceDB with HTTP API

    docker run -d --name spicedb \
      -p 50051:50051 -p 8443:8443 \
      -e SPICEDB_GRPC_PRESHARED_KEY="saffron-dev-key" \
      -e SPICEDB_DATASTORE_ENGINE=postgres \
      -e SPICEDB_DATASTORE_CONN_URI="postgres://spicedb:spicedb@host.docker.internal:5432/spicedb?sslmode=disable" \
      authzed/spicedb serve --http-enabled
  3. Run database migrations

    docker exec spicedb spicedb datastore migrate head \
      --datastore-engine postgres \
      --datastore-conn-uri "postgres://spicedb:spicedb@host.docker.internal:5432/spicedb?sslmode=disable"
  4. Initialize with mock data

    chmod +x init-spicedb.sh
    ./init-spicedb.sh
  5. Configure environment

    Create .env.local:

    # HTTP API (used by UI for schema, relationships, permissions)
    SPICEDB_URL=http://localhost:8443
    SPICEDB_TOKEN=saffron-dev-key
    
    # gRPC API (used only by the Terminal page for zed emulation)
    SPICEDB_ENDPOINT=localhost:50051
    SPICEDB_PRESHARED_KEY=saffron-dev-key
    SPICEDB_INSECURE=true
    
    > **Note:** The UI itself uses only the HTTP API. The gRPC endpoint is used only for the Terminal page's zed command emulation. If you do not use the Terminal, you may ignore the gRPC settings.
  6. Start the UI

    npm run dev

    Open http://localhost:7777

Configuration

Environment Variables

Create a .env.local file in the root directory (see above for details). The default values are:

SPICEDB_URL=http://localhost:8443
SPICEDB_TOKEN=saffron-dev-key
SPICEDB_ENDPOINT=localhost:50051
SPICEDB_PRESHARED_KEY=saffron-dev-key
SPICEDB_INSECURE=true

Note: If you do not set these, the backend will fall back to legacy/test defaults (http://localhost:8080 and somerandomkeyhere), which may not work with your setup. Always use .env.local for local development.

Docker Compose Services

The docker-compose.yml defines three services:

  • postgres - PostgreSQL database (SpiceDB's datastore) on internal network
  • spicedb - Authorization service
    • gRPC API: localhost:50051
    • HTTP API: localhost:8443
  • saffron - Next.js UI application on localhost:7777

All services share a saffron-network for internal communication.

Mock Data

The initialization scripts (init-spicedb.sh / init-spicedb.ps1) load a sample organizational structure:

Users:

  • ceo, cto, an_eng_director, an_eng_manager, an_engineer
  • it_admin, an_external_user, a_villain

Groups (nested hierarchy):

  • csuiteengineeringapplicationsproductname

Resources:

  • promserver - Managed by productname team, viewed by engineering
  • jira - Managed by engineering managers, viewed by all engineering

Organization:

  • org1 - Contains all groups and resources

Usage

1. Schema Management

  • Navigate to the Schema page
  • A default schema has already been loaded - you can edit this from ./examples/spicedb/data/schema.yml
  • Edit your authorization model using SpiceDB schema language
  • Use the visual view to see parsed namespaces, relations, and permissions
  • Save changes directly to SpiceDB

2. Relationship Management

  • Go to the Relationships page
  • Add relationships using smart dropdowns:
    • Resource: Search existing or create new (e.g., business:acme-corp)
    • Relation: Auto-populated from your schema (e.g., owner, manager)
    • Subject: Manual entry (e.g., user:alice)
  • View, search, and filter existing relationships

3. Authorization Testing

Use the Check page for permission testing with the following features:

  • Permission Check: Test if a subject has permission on a resource
  • Expand Permission: Visualize permission trees
  • Lookup Subjects: Find all subjects with a specific permission

Example Permission Checks (using mock data):

✅ Should ALLOW:

  1. CEO can admin org1

    • Resource: organization:org1
    • Permission: admin
    • Subject: user:ceo
  2. Engineer can view promserver

    • Resource: resource:promserver
    • Permission: view
    • Subject: user:an_engineer
  3. CTO can manage jira

    • Resource: resource:jira
    • Permission: manage
    • Subject: user:cto
  4. External user can view promserver

    • Resource: resource:promserver
    • Permission: view
    • Subject: user:an_external_user

❌ Should DENY:

  1. External user cannot manage promserver

    • Resource: resource:promserver
    • Permission: manage
    • Subject: user:an_external_user
  2. Villain cannot access jira

    • Resource: resource:jira
    • Permission: view
    • Subject: user:a_villain
  3. Engineer cannot manage jira (only view)

    • Resource: resource:jira
    • Permission: manage
    • Subject: user:an_engineer

4. Terminal Usage

  • Use the Terminal page for executing zed queries against the database

API Endpoints

The UI creates several API routes:

  • GET /api/spicedb/stats - Dashboard statistics
  • GET /api/spicedb/health - Connection health check
  • GET /api/spicedb/activity - Recent activity feed
  • GET /api/spicedb/resources - Available resources and relations
  • GET|POST /api/spicedb/schema - Schema management
  • GET|POST|DELETE /api/spicedb/relationships - Relationship CRUD
  • POST /api/spicedb/check - Permission checking
  • POST /api/spicedb/expand - Permission expansion
  • POST /api/spicedb/lookup-subjects - Subject lookup

Tech Stack

  • Frontend: Next.js 13+, React, Tailwind CSS
  • Backend: Next.js API routes
  • Database: SpiceDB (via HTTP API)
  • Styling: Tailwind CSS with custom components
  • Icons: Tabler

Troubleshooting

SpiceDB not responding

If the initialization script hangs or SpiceDB isn't responding:

  1. Check if SpiceDB migrations have been run:

    docker-compose logs spicedb | grep -i migrate
  2. If you see "datastore is not migrated" errors, run migrations:

    docker-compose exec spicedb spicedb datastore migrate head --datastore-engine postgres --datastore-conn-uri "postgres://spicedb:spicedb@postgres:5432/spicedb?sslmode=disable"
  3. Restart SpiceDB after migration:

    docker-compose restart spicedb

Fresh start

To completely reset everything:

docker-compose down -v
docker-compose up -d
# Run migrations again
docker-compose exec spicedb spicedb datastore migrate head --datastore-engine postgres --datastore-conn-uri "postgres://spicedb:spicedb@postgres:5432/spicedb?sslmode=disable"
# Initialize data
./init-spicedb.sh

Development

Local Development Commands

npm run dev      # Start development server
npm run build    # Build for production
npm start        # Start production server

Docker Commands

# Start all services (Saffron, SpiceDB, PostgreSQL)
docker-compose up -d

# Start only SpiceDB services (for local Saffron development)
docker-compose up -d postgres spicedb

# View logs
docker-compose logs -f saffron
docker-compose logs -f spicedb

# Stop services
docker-compose down

# Stop and remove volumes (fresh start)
docker-compose down -v

# Rebuild Saffron container
docker-compose up -d --build saffron

Connecting to Services

When Saffron runs locally:

  • SpiceDB gRPC: localhost:50051
  • SpiceDB HTTP: http://localhost:8443

When Saffron runs in Docker:

  • SpiceDB gRPC: spicedb:50051 (internal network)
  • SpiceDB HTTP: http://spicedb:8443 (internal network)

License

GPL v3

Links

About

The UI for managing SpiceDB instances.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors