A Next.js application with OIDC authentication, role-based access control, and external service integrations.
- OIDC Authentication: Secure login using OpenID Connect
- Role-Based Access Control: Granular permissions for different pages
- Protected Routes: All pages are protected after login
- Super User: First user is automatically assigned super user privileges
- Integrations Management: Connect and configure external services and applications
- User Management: Administer users and their roles
- Modern UI: Built with TailwindCSS and FontAwesome icons
- Node.js 18.x or later
- npm or yarn
- PostgreSQL 12.x or later
- This project uses cutting-edge versions:
- React 19.0.0
- Next.js 15.3.4
- TailwindCSS 4
- NextAuth.js 5.0.0-beta.4
- Prisma ORM 5.0.0
The easiest way to run the application locally is using Docker Compose, which will automatically set up the database, run migrations, and seed the database.
- Clone the repository
- Start the application using Docker Compose:
docker-compose upThis command will:
- Build the application image
- Start a PostgreSQL database
- Run database migrations automatically
- Seed the database with initial data
- Start the application server
- Access the application at http://localhost:3000
To stop the application, press Ctrl+C in the terminal where Docker Compose is running, or run:
docker-compose downTo remove all data volumes and start fresh:
docker-compose down -v- Clone the repository
- Install dependencies:
npm install
# or
yarn install- Set up environment variables by copying
.envand filling in the values:
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key-at-least-32-chars-long
OIDC_ISSUER=https://your-oidc-provider.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
DATABASE_URL="postgresql://username:password@localhost:5432/owlhub"
# AWS Credentials (required for AWS integrations)
AWS_ACCESS_KEY_ID=your-aws-access-key-id
AWS_SECRET_ACCESS_KEY=your-aws-secret-access-key
AWS_REGION=us-east-1
- Initialize the database:
npx prisma migrate dev --name init- Run the development server:
npm run dev
# or
yarn devOpen http://localhost:3000 with your browser to see the result.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
- All pages are protected by the middleware
- Unauthenticated users are redirected to the login page
- The login page redirects to the OIDC provider
- After successful authentication, users are redirected back to the application
- The first user to sign in is automatically assigned super user privileges
- Roles are created in the database
- Each user can be assigned multiple roles
- The first user is automatically assigned the "Super Admin" role
- Each page can be associated with specific roles
- Users can only access pages if they have at least one of the required roles
- Super users have access to all pages
Super users can manage roles and permissions through the admin interface:
- Create new roles
- Assign roles to users
- Define which roles have access to which pages
If the first user was not automatically made a super user during creation, you can use the provided script to make them a super user:
# Install dependencies first if you haven't already
npm install
# Run the script
npm run make-first-user-super-userNote: The script uses
npxto runts-node, ensuring it works even ifts-nodeis not installed globally.
This script will:
- Find the first user in the database (based on the earliest creation date)
- Make them a super user
- Assign them the "Super Admin" role
For more details, see the script documentation.
prisma/schema.prisma: Database schema definition- Contains models for User, Integration, AppType, SecurityFinding, and IntegrationMembership
- IntegrationMembership tracks users found in specific integrations
src/lib/prisma.ts: Prisma client initializationauth.config.ts: NextAuth.js configurationauth.ts: Authentication utilitiesmiddleware.ts: Route protection middlewaresrc/app/login/page.tsx: Login pagesrc/app/unauthorized/page.tsx: Unauthorized access pagesrc/app/admin/page.tsx: Example protected admin pagesrc/app/integrations/: Integrations managementpage.tsx: Main integrations listing and management pagenew/page.tsx: Page for adding new integrations
src/app/roles/: Role management pagessrc/app/users/: User management pagessrc/app/api/: API endpoints for various featuresauth/: Authentication endpointsintegrations/: Integrations APIapps/: App types API
src/scripts/: Utility scripts for managing the applicationmakeFirstUserSuperUser.ts: Script to make the first user a super user
scripts/: Background scripts for automated tasksfetchSecurityFindings.ts: Script to fetch security findings from GitLabrun-security-scan.sh: Shell script wrapper for running the security scan
public/app-icons/: SVG icons for app typessrc/components/: Reusable componentsAppIcon.tsx: Component for displaying app iconsPopup.tsx: Modal dialog component
The application uses Prisma ORM with PostgreSQL as the database provider. The following key models are defined in the schema:
- User: Represents a user in the system
- Integration: Represents a connection to an external service
- AppType: Defines the type of external service (e.g., GitLab, Jira)
- SecurityFinding: Stores security vulnerabilities found in integrations
- IntegrationMembership: Tracks users found in specific integrations
- Links users to the integrations they belong to
- Stores additional information about the user in that integration
- Used by the security findings script to track which users are found in which integrations
The IntegrationMembership model is used to track users found in specific integrations. It has the following fields:
integrationId: The ID of the integrationappTypeId: The ID of the app typeuserId: The ID of the userconfig: JSON string containing additional information about the user in that integration- For GitLab, this includes the GitLab user ID, username, state, and web URL
This model is populated by the fetchSecurityFindings.ts script when it finds users in GitLab integrations.
This project uses PostgreSQL as the database provider. You'll need to create a database and user before running the application:
CREATE DATABASE owlhub;
CREATE USER owlhub_user WITH ENCRYPTED PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE owlhub TO owlhub_user;
ALTER USER owlhub_user CREATEDB;Replace 'your_password' with a secure password and update your .env file with the correct connection string.
When making changes to the database schema in prisma/schema.prisma, you need to create and apply a migration. The project includes several scripts to simplify this process:
# Complete migration workflow: create migration, deploy it, and seed the database
npm run migrate
# Create a new migration with a custom name
npm run migrate:create your_migration_name
# Deploy existing migrations without creating new ones
npm run migrate:deploy
# Reset the database and reapply all migrations
npm run migrate:reset
# Run only the seed script to populate the database with initial data
npm run seed
# Check if all migrations have been deployed
npm run migrate:checkThe migrate:check command is particularly useful in CI/CD pipelines to ensure all migrations have been deployed before deploying the application. It will exit with a non-zero status code if there are pending migrations.
You can also use the Prisma CLI directly:
# Create a new migration with a descriptive name
npx prisma migrate dev --name your_migration_name
# This will:
# 1. Generate a new migration file in prisma/migrations
# 2. Apply the migration to your database
# 3. Regenerate the Prisma clientThe application includes background scripts for automated tasks:
The fetchSecurityFindings.ts script is used to fetch security findings and users from GitLab integrations:
- Located in the
scripts/directory - Runs periodically to scan all enabled GitLab integrations
- Fetches users from each GitLab instance
- Adds users to the database if they don't already exist
- Records user membership in the
IntegrationMembershiptable - Fetches security vulnerabilities (currently commented out)
- Can be run manually using the
run-security-scan.shshell script
To run the script manually:
./scripts/run-security-scan.shThe script logs its output to logs/security-scan.log.
The application uses SVG icons for app types in the integrations pages. These icons are stored in the public/app-icons/ directory and are named after the app type (e.g., gitlab.svg, jira.svg).
The project uses FontAwesome for general UI icons. The following FontAwesome packages are included:
@fortawesome/fontawesome-svg-core@fortawesome/free-solid-svg-icons@fortawesome/free-regular-svg-icons@fortawesome/free-brands-svg-icons@fortawesome/react-fontawesome
To use FontAwesome icons in your components:
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUser } from '@fortawesome/free-solid-svg-icons';
// In your component:
<FontAwesomeIcon icon={faUser} className="mr-2" />The project uses TailwindCSS v4 for styling. Utility classes are used throughout the components for consistent styling.
- Create an SVG file for the app type and save it in the
public/app-icons/directory - Name the file after the app type, using lowercase (e.g.,
github.svg) - In the database, set the
iconfield of the AppType to the name of the icon file without the extension (e.g.,github)
The AppIcon component is used to display app icons in the UI:
import AppIcon from "@/src/components/AppIcon";
// In your component:
<AppIcon iconName="gitlab" size={36} className="mr-3" />The component will automatically load the SVG file from the public/app-icons/ directory and display it. If the icon file is not found, it will display a fallback icon.
The application includes a comprehensive integrations management system that allows users to connect and configure external services:
- List Integrations: View all configured integrations
- Add New Integrations: Connect to new external services
- Enable/Disable Integrations: Toggle the active status of integrations
- Configure Integrations: Update connection settings and credentials
- Delete Integrations: Remove unwanted integrations
Each integration is associated with an app type that defines:
- Name and icon
- Required configuration fields
- Field types (text, password, etc.)
- Validation rules
To add a new integration:
- Navigate to the Integrations page
- Click "Add New Integration"
- Select an app type
- Fill in the required configuration fields
- Save the integration
To update an existing integration:
- Find the integration in the list
- Use the menu to select "Configure"
- Update the configuration fields
- Save the changes
- Create a new page in the
src/appdirectory - The middleware will automatically protect it
- Super users need to assign roles to the page for other users to access it
Super users can create new roles through the admin interface or directly in the database:
import { prisma } from "@/src/lib/prisma";
await prisma.role.create({
data: {
name: "Editor",
description: "Can edit content",
},
});import { prisma } from "@/src/lib/prisma";
await prisma.userRole.create({
data: {
userId: "user-id",
roleId: "role-id",
},
});import { prisma } from "@/src/lib/prisma";
await prisma.pageRole.create({
data: {
pageId: "page-id",
roleId: "role-id",
},
});To learn more about the technologies used in this project:
- Next.js Documentation - learn about Next.js features and API.
- NextAuth.js Documentation - learn about NextAuth.js authentication.
- Prisma Documentation - learn about Prisma ORM.
OwlHub is continuously evolving with new features and improvements planned for future releases:
-
AWS Security Scanning: Expanded security scanning for AWS resources including:
- Detection of IAM users with access keys not rotated for more than 90 days
- Identification of security vulnerabilities in AWS configurations
- Comprehensive security posture assessment
-
GitLab Security Scanning: Enhanced security scanning for GitLab repositories including:
- Vulnerability detection in code repositories
- User access management and monitoring
- Integration with GitLab's security features
-
GitHub Integration: Connect and monitor GitHub repositories
- User management
- Repository scanning
- Security vulnerability detection
-
Microsoft 365 Integration: Connect and monitor Microsoft 365 resources
- User management
- Security configuration assessment
- Compliance monitoring
-
Slack Integration: Notifications and alerts through Slack
- Real-time security alerts
- Integration status updates
- User-friendly notifications
-
Enhanced Dashboard: Improved visualization of security findings
- Customizable widgets
- Interactive charts and graphs
- Filtering and sorting options
-
Reporting System: Comprehensive reporting capabilities
- Scheduled reports
- Exportable formats (PDF, CSV)
- Customizable report templates
-
API Enhancements: Expanded API capabilities
- More endpoints for integration management
- Improved documentation
- Authentication and authorization improvements
The application includes a Dockerfile for containerized deployment. The Docker image is automatically built and pushed to GitHub Container Registry (GHCR) using GitHub Actions.
You can pull the latest Docker image from GHCR:
docker pull ghcr.io/owlhub/owlhub:latestTo run the container:
docker run -p 3000:3000 \
-e DATABASE_URL="postgresql://username:password@host:5432/owlhub" \
-e NEXTAUTH_URL="http://localhost:3000" \
-e NEXTAUTH_SECRET="your-secret-key" \
-e OIDC_ISSUER="https://your-oidc-provider.com" \
-e OIDC_CLIENT_ID="your-client-id" \
-e OIDC_CLIENT_SECRET="your-client-secret" \
ghcr.io/owlhub/owlhub:latestThe easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Note: The build script in package.json includes
prisma generateto ensure that the Prisma Client is properly generated during the Vercel build process. This is necessary because Vercel caches dependencies, which can lead to an outdated Prisma Client if the generation step is not explicitly included.
Check out the Next.js deployment documentation for more details.