npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@mayademcom/directus-extension-hasura-sso-bridge

v1.1.2

Published

Seamless SSO bridge between Hasura and Directus admin panel.

Readme

Directus Hasura SSO Bridge

Seamless single sign-on integration between Hasura and Directus admin panel

npm version Quality Gate Status TypeScript Directus Hasura License: MIT

🚀 Features

One-Click Admin Access - Hasura users can access Directus admin without re-authentication
Automatic User Provisioning - Creates Directus users automatically from Hasura JWT
Role Mapping - Maps Hasura roles to appropriate Directus permissions
Secure Session Management - Full session handling with HTTP-only cookies
TypeScript Support - Fully typed for better developer experience
Production Ready - Comprehensive error handling and logging

📋 Requirements

  • Directus v10+ (TypeScript extension support)
  • Hasura with JWT authentication configured

🔧 Installation

Method 1: NPM Installation (Recommended)

# Navigate to your Directus project root
cd your-directus-project

# Install the extension via npm
npm install @mayademcom/directus-extension-hasura-sso-bridge

# Restart Directus
npm start

Method 2: Manual Installation

# Clone or download the extension
git clone https://github.com/mayademcom/directus-extension-hasura-sso-bridge.git

# Navigate to your Directus project
cd your-directus-project

# Copy extension to Directus extensions directory
cp -r directus-extension-hasura-sso-bridge extensions/endpoints/

# Install dependencies
cd extensions/endpoints/directus-extension-hasura-sso-bridge
npm install

# Build the extension
npm run build

# Return to project root and restart Directus
cd ../../../
npm start

Method 3: Direct Download

  1. Download the latest release from GitHub Releases

  2. Extract to extensions/endpoints/directus-extension-hasura-sso-bridge/

  3. Run npm install && npm run build in the extension directory

  4. Restart Directus

⚙️ Configuration

1. Environment Variables

Add these to your Directus .env file:

# Your existing Directus configuration...

# Hasura JWT Secret (same as your Hasura instance)
HASURA_ADMIN_JWT_SECRET=your-hasura-jwt-secret-key

# Directus JWT Secret
SECRET=your-directus-secret-key

2. Directus Roles Setup

Create these roles in Directus admin panel:

  • Administrator - Full system access
  • Editor - Content management access

Or customize role mapping in the extension configuration.

3. Verification

After installation, verify the extension is loaded:


# Check health endpoint
curl http://localhost:8055/hasura-sso-bridge/health

# Expected response:
{
   "status": "healthy",
   "service": "hasura-sso-bridge",
   "timestamp": "2024-01-15T10:30:00.000Z"
}

🎯 Usage

Basic Usage

  1. Set Hasura JWT Token as Cookie in your application
// Set the Authorization cookie with your Hasura token
document.cookie = `Authorization=${hasuraToken}; path=/; SameSite=Lax; Secure`;
  1. Navigate to SSO endpoint (no token parameter needed):
   GET https://your-directus.com/hasura-sso-bridge
  1. Automatic redirect to Directus admin panel with authenticated session

Frontend Integration

// Example: Auto-redirect button with cookie
function openDirectusAdmin() {
  const hasuraToken = getHasuraToken(); // Your token retrieval logic

  // Set token as cookie
  document.cookie = `Authorization=${hasuraToken}; path=/; SameSite=Lax; Secure`;

  // Redirect to SSO endpoint
  const ssoUrl = "https://your-directus.com/hasura-sso-bridge";
  window.open(ssoUrl, "_blank");
}

// Example: Using fetch with credentials
async function openDirectusAdminWithFetch() {
  const hasuraToken = getHasuraToken();

  // Set cookie
  document.cookie = `Authorization=${hasuraToken}; path=/; SameSite=Lax; Secure`;

  // Open in new window
  window.open("https://your-directus.com/hasura-sso-bridge", "_blank");
}
Open Content Management

React Integration

import { useAuthToken } from "./hooks/useAuth";

function CMSAccessButton() {
  const { hasuraToken } = useAuthToken();

  const openCMS = () => {
    // Set Hasura token as cookie
    document.cookie = `Authorization=${hasuraToken}; path=/; SameSite=Lax; Secure`;

    // Open SSO endpoint
    const ssoUrl = `${process.env.REACT_APP_DIRECTUS_URL}/hasura-sso-bridge`;
    window.open(ssoUrl, '_blank');
  };

  return (

      Open Content Management

  );
}

Advanced: Using Fetch API

// If you need more control, use fetch with credentials
async function authenticateWithDirectus() {
  const hasuraToken = getHasuraToken();

  // Set cookie first
  document.cookie = `Authorization=${hasuraToken}; path=/; SameSite=Lax; Secure`;

  try {
    // Call SSO endpoint with credentials
    const response = await fetch(
      `${process.env.REACT_APP_DIRECTUS_URL}/hasura-sso-bridge`,
      {
        method: "GET",
        credentials: "include", // Important: Include cookies
        headers: {
          Accept: "application/json",
        },
      }
    );

    if (response.redirected) {
      // Successfully authenticated, redirect to admin
      window.location.href = response.url;
    }
  } catch (error) {
    console.error("Authentication failed:", error);
  }
}

API Integration

# Direct API call with cookie
curl "https://your-directus.com/hasura-sso-bridge" \
  -H "Cookie: Authorization=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  -L  # Follow redirects

# Response: 302 Redirect to /admin/content with authenticated session

# Test without authentication (should return 401)
curl "https://your-directus.com/hasura-sso-bridge" -v
# Response: 401 Unauthorized

Security Notes

  • Cookie Security: The extension reads the Hasura JWT token from the Authorization cookie, not from URL parameters
  • Credentials Required: Frontend requests must include credentials: 'include' to send cookies
  • HTTPS Recommended: Use Secure flag in production to ensure cookies are only sent over HTTPS
  • SameSite Protection: Set SameSite=Lax or SameSite=Strict to prevent CSRF attacks
  • No Token in URL: Tokens are never exposed in URLs, browser history, or server logs

Cookie Configuration

// Development (HTTP)
document.cookie = `Authorization=${token}; path=/; SameSite=Lax`;

// Production (HTTPS)
document.cookie = `Authorization=${token}; path=/; SameSite=Lax; Secure`;

// With expiration (optional)
const expires = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours
document.cookie = `Authorization=${token}; path=/; SameSite=Lax; Secure; expires=${expires.toUTCString()}`;

🔐 Security & Authentication

JWT Token Format

Your Hasura JWT must include these claims:

{
  "sub": "user-id-123",
  "email": "[email protected]",
  "first_name": "John",
  "last_name": "Doe",
  "https://hasura.io/jwt/claims": {
    "x-hasura-user-id": "user-id-123",
    "x-hasura-default-role": "editor",
    "x-hasura-allowed-roles": ["editor"]
  }
}

Role Mapping

| Hasura Role | Directus Role | Permissions | | ------------- | ------------- | ----------------------- | | super_admin | Administrator | Full system access | | editor | Editor | Content management only |

Security Features

  • HTTP-Only Cookies - Prevents XSS attacks
  • Secure Session Management - Proper session lifecycle
  • Role Validation - Only authorized roles can access
  • Automatic User Provisioning - JIT (Just-In-Time) user creation
  • Token Validation - Strict JWT verification

🛠️ Advanced Configuration

Custom Role Mapping

Create a custom configuration file:

// extensions/endpoints/directus-extensio-hasura-sso-bridge/config/roles.js

export const ROLE_MAPPING: RoleMapping = {
  super_admin: "Administrator",
  editor: "Editor",
  content_manager: "Editor",
  api_user: "User",
  // Add your custom roles here
};

Session Duration

Modify session duration:

# Add to your .env file
SESSION_DURATION_HOURS=86400000 # 24 hours in milliseconds

📚 API Reference

Endpoints

GET /hasura-sso-bridge

Main SSO authentication endpoint.

Parameters:

  • token (query, required) - Hasura JWT token

Response:

  • 302 - Redirect to /admin/content with authenticated session
  • 403 - Access denied (invalid token/role)

Example:

curl -L "https://your-directus.com/hasura-sso-bridge?token=eyJ0eXAiOiJKV1Q..."

GET /hasura-sso-bridge/health

Health check endpoint for monitoring.

Response:

{
  "status": "healthy",
  "service": "hasura-sso-bridge",
  "timestamp": "2024-01-15T10:30:00.000Z"
}

GET /hasura-sso-bridge/config

Configuration information endpoint.

Response:

{
  "supportedRoles": ["super_admin", "editor"],
  "environment": "production",
  "features": ["jwt-auth", "role-mapping", "auto-provisioning"]
}

🧪 Development

Local Development


# Clone the repository
git clone https://github.com/yourusername/directus-extension-hasura-sso-bridge.git
cd directus-extension-hasura-sso-bridge
    # Install dependencies
    npm install
    # Development build with watch mode
    npm run dev

    # Type checking
    npm run type-check

    # Linting
    npm run lint

    # Build for production
    npm run build

Testing

# Test the health endpoint
curl http://localhost:8055/hasura-sso-bridge/health

 # Test configuration endpoint
 curl http://localhost:8055/hasura-sso-bridge/config

 # Test with a valid token
 curl "http://localhost:8055/hasura-sso-bridge?token=YOUR_TEST_TOKEN"

Release Process

# Release in both NPM and Github
npm run release

🚨 Troubleshooting

Common Issues

"Access denied" Error

  • Cause: Invalid JWT token or unsupported role
  • Solution: Verify token format and role mapping
  • Debug: Check /hasura-sso-bridge/config for supported roles

"Directus SECRET not configured" Error

  • Cause: Missing environment variable
  • Solution: Add SECRET to your .env file
  • Verify: Restart Directus after adding environment variables

"Role 'X' not found" Error

  • Cause: Directus role doesn't exist in database
  • Solution: Create the role in Directus admin or update role mapping
  • Check: Visit Settings > Access Control > Roles in Directus admin

Extension not loading

  • Cause: Build errors or incorrect file structure
  • Solution: Check extension logs and rebuild with npm run build
  • Verify: Check Directus logs for extension loading errors

"Invalid or expired Hasura token"

  • Cause: Token verification failed
  • Solution: Verify HASURA_ADMIN_JWT_SECRET matches your Hasura configuration
  • Debug: Use jwt.io to inspect token claims

Logs Format

All logs include the [Hasura-SSO-Bridge] prefix: [Hasura-SSO-Bridge] ✅ SSO authentication completed, redirecting to admin [Hasura-SSO-Bridge] ❌ SSO authentication failed: Invalid token [Hasura-SSO-Bridge] ⚠️ Role mapping failed for role: invalid_role

Health Monitoring

Monitor the extension with the health endpoint:

# Check extension health
curl -f http://localhost:8055/hasura-sso-bridge/health || echo "Extension unhealthy"

# Monitor in production
watch -n 30 'curl -s http://your-directus.com/hasura-sso-bridge/health | jq .status'

🔄 Migration & Updates

Updating the Extension

# Update via npm
npm update directus-extension-hasura-sso-bridge

# Restart Directus
npm start

Breaking Changes

Check CHANGELOG.md for breaking changes between versions.

Database Migration

No database migrations required - the extension uses existing Directus tables.

📊 Performance & Monitoring

Performance Considerations

  • Session Cleanup: Extension automatically cleans expired sessions
  • Memory Usage: Minimal memory footprint with efficient JWT processing
  • Database Impact: Lightweight database operations

Monitoring Endpoints


# Health check for load balancers
GET /hasura-sso-bridge/health

# Configuration validation
GET /hasura-sso-bridge/config

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes with tests
  4. Commit with conventional commits (git commit -m 'feat: add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Development Guidelines

  • Follow existing TypeScript patterns
  • Add tests for new features
  • Update documentation
  • Follow conventional commit format
  • Ensure all tests pass

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🔗 Links

💬 Support

🌟 Star History

If this extension helped you, please consider giving it a ⭐ on GitHub!

Made with ❤️ for seamless SSO integration between Hasura and Directus