A modern, secure application portal with user management, SSO integration, and Docker support
Quick Start • Features • Installation • Documentation • API
📖 Available in multiple languages:
- About
- Key Features
- Screenshots
- Quick Start
- Detailed Installation
- Configuration
- Architecture
- Security
- API Reference
- Troubleshooting
- Contributing
- License
Airboard is a comprehensive internal portal platform designed to empower organizations with centralized access to applications, real-time communications, and actionable insights—all in one place.
In a modern professional environment, organizations need more than just a link directory. Airboard addresses this by providing a complete digital workplace solution:
- Unified Application Portal - Centralized dashboard with customizable access to all your tools
- News Hub - Rich internal communication system with articles, tutorials, announcements, and FAQs
- Analytics Dashboard - Track application usage, user engagement, and content performance
- Announcement System - Broadcast important messages to teams instantly
- User Favorites - Personalized experience with favorite apps and content
- Delegated Management - Group Admin role for managing private app groups
- Role-Based Management - Granular permissions for Admins, Group Admins, Editors, and Users
- Multi-Language Support - Available in French, English, Spanish, and Arabic
- SSO Integration - Seamless authentication with Authentik, Microsoft 365, LDAP, and more
- Docker-Ready - Deploy in minutes with full containerization
- Enterprise Communication: Publish company news, policy updates, and knowledge base articles
- IT Services: Application portal + technical documentation + usage analytics
- HR & Internal Comms: Share announcements, employee handbooks, tutorials, and FAQs
- Department Dashboards: Customized views per team (HR, Finance, Sales) with relevant apps
- Project Collaboration: Team-specific portals with apps, announcements, and documentation
- Analytics & Insights: Track most-used applications, monitor engagement, understand user behavior
Airboard transforms how organizations manage digital resources, internal communications, and user engagement.
-
Dual Authentication
- Classic username/password login
- SSO via Authentik (Microsoft 365, Google, LDAP, etc.)
- Auto-provisioning of SSO users
- Automatic role mapping via Authentik groups
-
Enhanced Security (OWASP 2025)
- JWT authentication with refresh tokens
- Configurable bcrypt hashing (cost 10-31)
- CSRF and XSS protection
- Security headers (CSP, CORS)
- Strict input validation
- SQL injection protection
- Rate limiting on sensitive endpoints
-
Integrated OAuth2
- Google OAuth2
- Microsoft OAuth2
- Configuration via admin interface
- Secure token management
-
Role System
- Admin: Full system access
- Group Admin: Delegated management of private groups and applications
- Editor: Create and manage articles
- User: Access to assigned applications
-
User Management
- Complete CRUD operations
- Group and role assignment
- User favorites management
- Customizable user profiles
-
Group Management
- Create and organize groups
- Public and private groups
- Assign Group Admins
- Granular access control
-
Delegated Management
- Group Admins can manage their assigned groups
- Create private application groups
- Manage applications within their groups
- Create and modify articles
- No access to users or global settings
-
Private Application Groups
- Visible only to assigned groups
- Group ownership (OwnerGroupID)
- Permissions verified at each operation
- Complete separation from public groups
-
Application Organization
- Public and private application groups
- Custom icons (Iconify)
- Thematic colors per group
- Configurable URLs and descriptions
- Advanced sorting and filtering
-
User Favorites
- Pin favorite applications
- Quick access from dashboard
- Real-time synchronization
-
Usage Analytics
- Track clicks per application
- Unique users
- 30-day activity charts
- Top applications
-
Rich Editor (Tiptap)
- Full WYSIWYG editor
- Code blocks with syntax highlighting
- Tables, lists, links
- Text alignment
- Images and media
-
Content Organization
- Categories (General, Tutorials, Announcements, FAQ)
- Multiple dynamic tags
- SEO-friendly slugs
- Pin important articles
-
User Engagement
- Reaction system (👍, ❤️, 🎉)
- Per-user view tracking
- Unique view counters
- Detailed analytics
-
Display Modes
- Grid view (cards)
- List view (compact)
- Table view (very compact)
- Advanced filters (category, type, tags)
- Full-text search
-
Interactive Polls
- Single choice or multiple choice polls
- Anonymous or named voting
- Scheduled polls (start/end date)
- Target specific groups or all users
- Link polls to news articles or announcements
-
Poll Management
- Create and edit polls (Admin & Group Admin)
- Real-time results visualization
- Result visibility control (always, after voting, after closing)
- Vote tracking and analytics
-
User Participation
- Easy voting interface
- View results based on permissions
- Vote history tracking
- Voter details (if not anonymous)
-
Integration
- Polls widget on dashboard
- Embedded in news articles
- Standalone polls page
- Export results to CSV
-
Notification System
- Real-time in-app notifications
- Notification bell with unread count
- Multiple notification types (system, news, announcements, events)
- Priority levels (normal, important, urgent)
-
Notification Types
- System notifications (login, role changes, access granted/revoked)
- Content notifications (new articles, new polls, announcements)
- Engagement notifications (reactions, comments, mentions)
- Custom admin notifications
-
User Experience
- Unread/read status tracking
- Mark as read/unread
- Mark all as read
- Delete notifications
- Redirect to action URL on click
-
Management
- Notification center page
- Filter by type and status
- Automatic cleanup of old notifications
- Push notifications (planned)
-
Dynamic Banners
- Display on dashboard
- Types: Info, Warning, Error, Success
- Validity period (start/end date)
- Display priority
-
Centralized Management
- Create and modify via admin
- Activation/deactivation
- Preview
-
User Achievements
- Level-based progression
- XP system with customizable rules
- Badges for milestones (First login, Article reader, Active contributor, etc.)
- Achievement history and tracking
-
Leaderboards
- Global XP rankings
- Top users by activity
- Weekly/monthly performance tracking
- Customizable ranking criteria
-
Rewards
- XP gained from: first login, article views, reactions, comments, poll votes
- Badge unlocking at milestones
- Achievement notifications
- User level progression
-
Gamification Dashboard
- Personal stats (level, XP, badges)
- Progress to next level
- Recent achievements
- Leaderboard widget on home page
-
User Suggestions
- Submit suggestions/ideas
- Categories (Feature, Bug, Improvement, Other)
- Rich text descriptions with attachments
- Voting on suggestions (upvote/downvote)
-
Community Engagement
- Comments on suggestions
- Threaded discussions
- Vote aggregation for popular ideas
- Approved/rejected/implemented status tracking
-
Admin Management
- Suggestion dashboard with filtering
- Status workflow (Pending → Approved → Implemented)
- Response messages to users
- Export suggestions for analysis
-
User Experience
- Dedicated suggestions page
- Category filtering
- Sort by votes/date
- Notification when suggestion status changes
-
Full-Text Search
- Search across all content types (apps, articles, announcements, FAQs)
- Instant results as you type
- Keyword highlighting in results
- Search history and recent searches
-
Advanced Filters
- Filter by type (Application, Article, Announcement)
- Filter by category
- Filter by tags
- Filter by date range
- Permission-based filtering (only show content user has access to)
-
Smart Search
- Relevance scoring
- Typo tolerance
- Multi-language support
- Contextual suggestions
-
Search Performance
- Indexed searching for fast results
- Debounced queries to reduce server load
- Caching of popular searches
- Analytics on search trends
-
Analytics Dashboard
- Global statistics (users, apps, articles)
- Daily activity charts
- Top applications and users
- News analytics
-
Usage Tracking
- Clicks per application
- Article views
- Reactions and engagement
- Data export
- Multi-Language Support
- French (fr)
- English (en)
- Spanish (es)
- Arabic (ar)
- Integrated language selector
- Complete translations
- Auto-Update System
- Automatic new version checking
- GitHub Releases integration
- Update notifications
- Accessible changelog
- Configure via GITHUB_REPO
-
Modern Design
- Responsive TailwindCSS
- Dark mode
- Smooth animations
- Intuitive navigation
-
Reusable Components
- Standardized modals
- Application cards
- Validated forms
- Loaders and notifications
# Clone the repository
git clone https://github.com/your-username/airboard.git
cd airboard
# Start Docker (if needed)
sudo systemctl start docker
# Configure variables (optional)
cp .env.example .env
# Edit .env if needed
# Build and start
docker-compose build
docker-compose up -d
# Check status
docker-compose psAccess: http://localhost
Default accounts:
- Admin:
admin/admin123 - User:
user/user123
IMPORTANT: Change default passwords on first login.
- Create a new project in Coolify
- Deploy from Git:
https://github.com/your-username/airboard.git - Build Pack:
docker-compose - File:
docker-compose.prod.yaml - Configure environment variables (see Configuration)
- Deploy
# Backend
cd backend
go mod download
go run main.go
# Frontend (another terminal)
cd frontend
npm install
npm run devAccess: http://localhost:3000
For Docker (Production):
- Docker 20.10+
- Docker Compose 2.0+
- 2 GB RAM minimum
- 10 GB disk space
For Development:
- Go 1.21+
- Node.js 18+
- PostgreSQL 15+
- 4 GB RAM minimum
Ubuntu/Debian:
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add user to docker group
sudo usermod -aG docker $USER
# Start Docker
sudo systemctl start docker
sudo systemctl enable docker
# Verify
docker --version
docker-compose --versionCentOS/RHEL:
sudo yum install -y docker docker-compose
sudo systemctl start docker
sudo systemctl enable dockergit clone https://github.com/your-username/airboard.git
cd airboard# Copy template
cp .env.example .env
# Edit with your values
nano .envCritical variables to change in production:
# Database (REQUIRED)
DB_PASSWORD=your_secure_password
# JWT (REQUIRED)
JWT_SECRET=your-very-long-jwt-secret-minimum-32-characters
# Application
PUBLIC_URL=https://your-domain.com
# SSO (if used)
SSO_ENABLED=true
SSO_ADMIN_GROUPS=airboard-admins,your-admin-group
# GitHub Updates (optional)
GITHUB_REPO=your-username/airboard
GITHUB_TOKEN=ghp_your_github_token# Build images
docker-compose build
# Start services
docker-compose up -d
# Check logs
docker-compose logs -f
# Check status
docker-compose ps# Test access
curl http://localhost/health
# Check database
docker-compose exec postgres psql -U airboard -d airboard -c "\dt"
# Backend logs
docker-compose logs backend
# Frontend logs
docker-compose logs frontend# Fork or clone
git clone https://github.com/your-username/airboard.git
cd airboard
# Push to your GitHub repo
git remote set-url origin https://github.com/YOUR_USERNAME/airboard.git
git push-
Create a Project
- Name: Airboard
- Environment: Production
-
Add a Service
- Type: Git Repository
- Repository: your GitHub repo
- Branch: main
- Build Pack: docker-compose
-
Select docker-compose.prod.yaml
- In Settings > Build
- Docker Compose File:
docker-compose.prod.yaml
-
Configure Environment Variables
Minimum variables:
DB_PASSWORD=secure_password_123
JWT_SECRET=very-long-jwt-secret-at-least-32-random-chars
PUBLIC_URL=https://airboard.your-domain.com
SSO_ENABLED=falseComplete variables (recommended):
# Database
DB_HOST=postgres
DB_PORT=5432
DB_USER=airboard
DB_PASSWORD=very_secure_password_123
DB_NAME=airboard
# JWT
JWT_SECRET=your-super-long-and-random-jwt-secret-minimum-32-chars
JWT_TOKEN_EXPIRATION_HOURS=24
JWT_REFRESH_EXPIRATION_DAYS=7
# Security
BCRYPT_COST=12
# Application
GIN_MODE=release
PUBLIC_URL=https://airboard.your-domain.com
SIGNUP_ENABLED=true
# SSO (if using Authentik)
SSO_ENABLED=true
SSO_AUTO_PROVISION=true
SSO_DEFAULT_ROLE=user
SSO_DEFAULT_GROUP=Common
SSO_ADMIN_GROUPS=airboard-admins,it-admins
# GitHub Updates (optional)
GITHUB_REPO=your-username/airboard
GITHUB_TOKEN=ghp_your_personal_token-
Deploy
- Click "Deploy"
- Wait for build completion (5-10 minutes)
- Check logs
-
DNS Configuration
- Add DNS A record to Coolify IP
- Or CNAME to Coolify domain
# Test health
curl https://airboard.your-domain.com/health
# Should return: {"status":"healthy"}Internet → Nginx Proxy Manager → Authentik → Coolify → Airboard
Create an Application:
- Applications > Create
- Name: Airboard
- Slug: airboard
- Provider: Create new Proxy Provider
Configure Provider:
- Type: Proxy Provider
- Authorization flow: default-provider-authorization-implicit-consent
- External host:
https://airboard.your-domain.com - Internal host:
http://coolify-airboard:80 - Mode: Forward auth (single application)
Create Groups:
- Directory > Groups > Create
- Create
airboard-adminsfor administrators - Create
airboard-usersfor standard users - Assign users to groups
Create Proxy Host:
- Hosts > Proxy Hosts > Add Proxy Host
- Domain Names:
airboard.your-domain.com - Forward Hostname/IP: Coolify domain or IP
- Forward Port: 80
- Cache Assets: ON
- Block Common Exploits: ON
- Websockets Support: ON
Configure Authentik Authentication:
- Access List > Create Access List
- Authorization > Authentik
- Provider: Select Airboard provider
Advanced Configuration (Custom Nginx Config):
location / {
proxy_pass $forward_scheme://$server:$port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Authentik SSO Headers (CRITICAL)
proxy_set_header X-authentik-email $authentik_email;
proxy_set_header X-authentik-username $authentik_username;
proxy_set_header X-authentik-groups $authentik_groups;
proxy_set_header X-authentik-uid $authentik_uid;
}In Coolify, set:
SSO_ENABLED=true
SSO_AUTO_PROVISION=true
SSO_DEFAULT_ROLE=user
SSO_DEFAULT_GROUP=Common
SSO_ADMIN_GROUPS=airboard-admins- Access
https://airboard.your-domain.com - Redirect to Authentik
- Login with Microsoft 365 / Google / LDAP
- Authentik authenticates and returns to Airboard
- Airboard auto-provisions user
- Redirect to dashboard
# Install Go
wget https://go.dev/dl/go1.21.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
node --version
npm --version
# Install PostgreSQL
sudo apt install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo systemctl enable postgresql# Connect to PostgreSQL
sudo -u postgres psql
# Create database and user
CREATE DATABASE airboard;
CREATE USER airboard WITH PASSWORD 'airboard123';
GRANT ALL PRIVILEGES ON DATABASE airboard TO airboard;
\qcd backend
# Create .env
cat > .env << EOF
DB_HOST=localhost
DB_PORT=5432
DB_USER=airboard
DB_PASSWORD=airboard123
DB_NAME=airboard
JWT_SECRET=dev-secret-key-not-for-production
GIN_MODE=debug
SSO_ENABLED=false
EOF
# Install dependencies
go mod download
# Start server
go run main.goBackend starts on http://localhost:8080
cd frontend
# Install dependencies
npm install
# Create .env.local
cat > .env.local << EOF
VITE_API_URL=http://localhost:8080/api/v1
EOF
# Start dev server
npm run devFrontend starts on http://localhost:3000
- Frontend: http://localhost:3000
- Backend API: http://localhost:8080/api/v1
- Health check: http://localhost:8080/health
Test accounts:
- Admin:
admin/admin123 - User:
user/user123
All variables can be configured via:
- Coolify: Environment Variables section
- Docker Compose: Shell variables or
.envfile - Development:
.envfile in root directory
| Variable | Description | Default | Required |
|---|---|---|---|
DB_HOST |
PostgreSQL host | postgres |
No |
DB_PORT |
PostgreSQL port | 5432 |
No |
DB_USER |
Database user | airboard |
No |
DB_PASSWORD |
Database password | airboard123 |
YES (prod) |
DB_NAME |
Database name | airboard |
No |
| Variable | Description | Default | Required |
|---|---|---|---|
JWT_SECRET |
JWT secret key (min 32 chars) | Auto-generated | YES (prod) |
JWT_TOKEN_EXPIRATION_HOURS |
Access token duration (hours) | 24 |
No |
JWT_REFRESH_EXPIRATION_DAYS |
Refresh token duration (days) | 7 |
No |
BCRYPT_COST |
Bcrypt cost (10-31) | 12 |
No |
Secure JWT_SECRET generation:
# Option 1: OpenSSL
openssl rand -base64 64
# Option 2: Python
python3 -c "import secrets; print(secrets.token_urlsafe(64))"
# Option 3: Leave empty for auto-generation
JWT_SECRET=| Variable | Description | Default | Required |
|---|---|---|---|
GIN_MODE |
Gin mode (debug/release) |
release |
No |
PUBLIC_URL |
Public app URL | http://localhost |
No |
SIGNUP_ENABLED |
Enable classic signup | true |
No |
IMPORTANT: SSO is enabled by default. Disable if not using Authentik.
| Variable | Description | Default | Required |
|---|---|---|---|
SSO_ENABLED |
Enable SSO | true |
YES (disable if no SSO) |
SSO_AUTO_PROVISION |
Auto-create SSO users | true |
No |
SSO_DEFAULT_ROLE |
Default role (user/admin) |
user |
No |
SSO_DEFAULT_GROUP |
Default group | Common |
No |
SSO_ADMIN_GROUPS |
Admin groups (comma-separated) | airboard-admins |
No |
SSO headers detected:
X-authentik-email- User emailX-authentik-username- UsernameX-authentik-groups- Groups (comma-separated)X-authentik-uid- Unique ID
| Variable | Description | Configuration |
|---|---|---|
| Google OAuth | Google configuration | Via admin interface |
| Microsoft OAuth | Microsoft configuration | Via admin interface |
Configure via /admin/oauth in the interface.
| Variable | Description | Example |
|---|---|---|
GITHUB_REPO |
GitHub repo (format owner/repo) |
username/airboard |
GITHUB_TOKEN |
GitHub token (optional) | ghp_xxxxx |
Leave GITHUB_REPO empty to disable checks.
| Variable | Description | Default |
|---|---|---|
STORAGE_TYPE |
Type (local/s3/minio) |
local |
UPLOAD_DIR |
Local directory | ./uploads |
S3_BUCKET |
S3/MinIO bucket name | - |
S3_REGION |
S3 region | - |
S3_ENDPOINT |
MinIO endpoint | - |
S3_ACCESS_KEY |
Access Key | - |
S3_SECRET_KEY |
Secret Key | - |
Before deploying to production:
- Change
DB_PASSWORD- Strong password (16+ chars) - Configure
JWT_SECRET- Random secret (32+ chars) - Set
PUBLIC_URL- Production HTTPS URL - Configure
SSO_ENABLED-trueif SSO,falseotherwise - Verify
BCRYPT_COST- Minimum 12, recommended 13 - Enable
GIN_MODE=release- Production mode - Configure
SSO_ADMIN_GROUPS- Real groups - Change default passwords -
adminanduser - Enable HTTPS - Via Nginx/Caddy/Traefik
- Configure DB backups - PostgreSQL backups
- Check logs - No errors at startup
Production configuration example:
DB_PASSWORD=K8$mP9#nQ2@vL5*wR7&xT4!yU6
JWT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
PUBLIC_URL=https://tools.company.com
SSO_ENABLED=true
SSO_ADMIN_GROUPS=airboard-admins,it-admins,sysadmins
GIN_MODE=release
BCRYPT_COST=13| Component | Technology | Role |
|---|---|---|
| Backend | Go 1.21 + Gin | REST API server |
| Frontend | Vue.js 3 + Vite | SPA application |
| Database | PostgreSQL 15 | Data persistence |
| ORM | GORM | Database abstraction |
| Authentication | JWT | Token-based auth |
| SSO | Authentik | IdP integration |
| Text Editor | Tiptap | WYSIWYG for news |
| Containerization | Docker + Compose | Orchestration |
| Reverse Proxy | Nginx | Production web server |
| Styling | TailwindCSS | Utility-first CSS |
| Icons | Iconify | Icon library |
| State | Pinia | Vue state management |
| Routing | Vue Router | Client routing |
| i18n | vue-i18n | Internationalization |
backend/
├── main.go # Entry point, routes, migrations
├── config/
│ └── config.go # Env config, SSO
├── handlers/
│ ├── auth.go # Login, SSO, refresh
│ ├── users.go # User CRUD
│ ├── groups.go # Group CRUD
│ ├── applications.go # Application CRUD
│ ├── group_admin.go # Group Admin endpoints
│ ├── analytics.go # Analytics
│ ├── announcements.go # Announcements
│ ├── news.go # News & reactions
│ └── news_categories.go # Categories & tags
├── middleware/
│ ├── auth.go # JWT validation
│ ├── group_admin.go # Group Admin permissions
│ ├── cors.go # CORS headers
│ ├── sso.go # SSO header detection
│ └── editor.go # Editor middleware
├── models/
│ ├── models.go # User, Group, App, Analytics
│ └── news.go # News, Category, Tag, Reaction
└── services/
└── sso_mapper.go # SSO user sync
Key patterns:
- SSO Flow: Nginx forward headers → SSO middleware → auto-provision → JWT
- Auth: JWT with refresh tokens
- Authorization: Role middlewares (
RequireAuth,RequireAdmin,RequireGroupAdmin,RequireEditor) - Group Admin: Delegated management with permission checks
- Database: GORM with auto-migrations
- Routes: Grouped under
/api/v1/
frontend/src/
├── main.js # Entry point
├── App.vue # Root component, SSO auto-login
├── router/
│ └── index.js # Routes + guards
├── stores/
│ ├── auth.js # Auth state + SSO
│ ├── app.js # App state
│ └── favorites.js # Favorites
├── services/
│ └── api.js # All API endpoints
├── views/
│ ├── dashboard/ # Dashboard, Analytics
│ ├── admin/ # Admin pages
│ ├── group-admin/ # Group Admin pages
│ ├── auth/ # Login, OAuth callback
│ ├── NewsCenter.vue # News hub
│ └── NewsDetail.vue # Article detail
├── components/
│ ├── layout/ # Sidebar, Navbar
│ ├── admin/ # Admin modals
│ ├── group-admin/ # Group Admin modals
│ ├── news/ # News components
│ │ ├── RichTextEditor.vue
│ │ ├── TiptapRenderer.vue
│ │ ├── NewsCard.vue
│ │ └── ViewModeSelector.vue
│ └── dashboard/ # Dashboard components
└── locales/
├── fr.json # French translations
├── en.json # English translations
├── es.json # Spanish translations
└── ar.json # Arabic translations
Key patterns:
- State: Pinia for auth, settings, favorites
- SSO Auto-Login:
App.vuechecks SSO session on mount - API: Centralized in
services/api.js - Guards: Auth + role verification in router
- Editing: Tiptap for rich content
Main models:
- User - Users with role, SSO, managed groups
- Group - User groups with admins
- AppGroup - App categories (public/private)
- Application - Individual applications
- News - Articles with JSON content (Tiptap)
- NewsCategory - Categories (General, Tutorials, etc.)
- Tag - Tags for articles
- NewsReaction - User reactions
- ApplicationClick - Click analytics
- Announcement - Banner announcements
Important relationships:
User ←→ Groups (many-to-many)
User ←→ ManagedGroups (many-to-many, Group Admins)
Group ←→ Admins (many-to-many, Group Admins)
Group ←→ AppGroups (many-to-many)
AppGroup → OwnerGroup (belongs-to, for private groups)
Application → AppGroup (belongs-to)
News → Category (belongs-to)
News ←→ Tags (many-to-many)
NewsReaction → User + News (belongs-to)
- User access →
https://airboard.company.com - NPM detects → not authenticated
- Redirect → Authentik
- Authentik auth → Microsoft 365 / Google / LDAP
- NPM forwards →
X-authentik-*headers - SSO middleware → detects headers
- SSO Mapper service:
- Search user by email
- Auto-provision if not exists
- Sync Authentik groups → Airboard groups
- Assign admin role if group matches
SSO_ADMIN_GROUPS
- JWT generation → token + refresh token
- Frontend response → localStorage storage
- Redirect →
/dashboard
Airboard implements OWASP security best practices:
- JWT verification on all protected endpoints
- Role middlewares (
RequireAdmin,RequireGroupAdmin,RequireEditor) - Ownership validation for Group Admins
- No direct access to other groups' resources
- Bcrypt hashing for passwords (configurable cost 10-31)
- JWT signed with strong secret (min 32 chars)
- Expirable tokens and refresh tokens
- HTTPS mandatory in production
- SQL protection via GORM (prepared statements)
- Strict user input validation
- Tiptap data sanitization
- No shell command execution with user input
- Layered architecture (handlers → services → models)
- Separation of concerns
- Least privilege principle (Group Admins)
- Systematic server-side validation
- Security headers (CSP, CORS, X-Frame-Options)
- Release mode in production (
GIN_MODE=release) - Secure logs (no secrets)
- Configuration via environment variables
- Regularly updated dependencies
- CVE checking with
go modandnpm audit - Official Docker images
- Automatic security scanning
- Rate limiting on login
- Multi-factor authentication (via SSO)
- Expirable sessions
- Refresh tokens with rotation
- Uploaded file integrity verification
- MIME type validation
- File size limits
- No uploaded code execution
- Authentication logs
- Admin action logs
- Security error logs
- SSO monitoring
- External URL validation
- No requests to user URLs
- Allowed domain whitelist
Nginx (production):
# CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'";
# XSS Protection
add_header X-XSS-Protection "1; mode=block";
# Anti-clickjacking
add_header X-Frame-Options "SAMEORIGIN";
# Type sniffing
add_header X-Content-Type-Options "nosniff";
# HTTPS only
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";- Enable HTTPS - Mandatory in production (Let's Encrypt, Cloudflare)
- Change secrets -
DB_PASSWORD,JWT_SECRET - Increase bcrypt -
BCRYPT_COST=13or 14 - Restrict DB access - No external exposure
- Enable firewall - Ports 80/443 only
- Regular backups - Daily PostgreSQL dumps
- Centralized logs - Monitoring and alerts
- Updates - Check GitHub releases
- Security audits - Regular testing
- Recommend SSO - Centralized authentication
http://localhost:8080/api/v1 # Development
https://airboard.company.com/api/v1 # Production
All protected endpoints require an Authorization header:
Authorization: Bearer <jwt_token>
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /auth/login |
Classic login | No |
| POST | /auth/refresh |
Refresh JWT | No |
| GET | /auth/sso/auto-login |
SSO auto-login | Headers |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /group-admin/app-groups |
Managed app groups | Group Admin |
| GET | /group-admin/managed-groups |
Managed groups | Group Admin |
| GET | /group-admin/applications |
Apps in managed groups | Group Admin |
| POST | /group-admin/applications |
Create application | Group Admin |
| PUT | /group-admin/applications/:id |
Update application | Group Admin |
| DELETE | /group-admin/applications/:id |
Delete application | Group Admin |
| POST | /group-admin/news |
Create article | Group Admin |
| PUT | /group-admin/news/:id |
Update article | Group Admin |
| DELETE | /group-admin/news/:id |
Delete article | Group Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /users |
List users | Admin |
| GET | /users/:id |
Get user | Admin |
| POST | /admin/users |
Create user | Admin |
| PUT | /admin/users/:id |
Update user | Admin |
| DELETE | /admin/users/:id |
Delete user | Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /admin/groups |
List groups | Admin |
| POST | /admin/groups |
Create group | Admin |
| PUT | /admin/groups/:id |
Update group | Admin |
| DELETE | /admin/groups/:id |
Delete group | Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /dashboard |
User dashboard | User |
| GET | /admin/applications |
List applications | Admin |
| POST | /admin/applications |
Create application | Admin |
| PUT | /admin/applications/:id |
Update application | Admin |
| DELETE | /admin/applications/:id |
Delete application | Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /favorites |
List favorites | User |
| POST | /favorites/:id |
Add favorite | User |
| DELETE | /favorites/:id |
Remove favorite | User |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /news |
List articles (filters) | User |
| GET | /news/article/:slug |
Article detail | User |
| POST | /news/:id/view |
Increment views | User |
| GET | /news/:id/reactions |
Article reactions | User |
| POST | /news/:id/react |
Add reaction | User |
| DELETE | /news/:id/react |
Remove reaction | User |
| POST | /editor/news |
Create article | Editor |
| PUT | /editor/news/:id |
Update article | Editor |
| DELETE | /editor/news/:id |
Delete article | Editor |
| POST | /admin/news/:id/pin |
Pin article | Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /analytics/dashboard |
Analytics dashboard | Admin |
| POST | /analytics/click |
Track app click | User |
| GET | /admin/news/analytics |
News analytics | Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /announcements/active |
Active announcements | User |
| GET | /admin/announcements |
List announcements | Admin |
| POST | /admin/announcements |
Create announcement | Admin |
| PUT | /admin/announcements/:id |
Update announcement | Admin |
| DELETE | /admin/announcements/:id |
Delete announcement | Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /polls |
List polls (with filters) | User |
| GET | /polls/:id |
Get poll details | User |
| POST | /polls/:id/vote |
Vote on a poll | User |
| DELETE | /polls/:id/vote |
Remove vote | User |
| GET | /polls/:id/results |
Get poll results | User |
| POST | /admin/polls |
Create poll | Admin |
| PUT | /admin/polls/:id |
Update poll | Admin |
| DELETE | /admin/polls/:id |
Delete poll | Admin |
| POST | /admin/polls/:id/close |
Close poll | Admin |
| GET | /admin/polls/stats |
Poll statistics | Admin |
| POST | /group-admin/polls |
Create poll | Group Admin |
| PUT | /group-admin/polls/:id |
Update poll | Group Admin |
| DELETE | /group-admin/polls/:id |
Delete poll | Group Admin |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /notifications |
List user notifications | User |
| GET | /notifications/unread-count |
Get unread count | User |
| PUT | /notifications/:id/read |
Mark as read | User |
| PUT | /notifications/:id/unread |
Mark as unread | User |
| PUT | /notifications/mark-all-read |
Mark all as read | User |
| DELETE | /notifications/:id |
Delete notification | User |
| DELETE | /notifications/clear-all |
Clear all notifications | User |
| POST | /admin/notifications |
Create notification | Admin |
| POST | /admin/notifications/broadcast |
Broadcast to groups | Admin |
| GET | /admin/notifications/stats |
Notification statistics | Admin |
Login:
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'Create Application (Group Admin):
curl -X POST http://localhost:8080/api/v1/group-admin/applications \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name":"My App",
"url":"https://app.example.com",
"icon":"mdi:rocket",
"color":"#4F46E5",
"app_group_id":1
}'Create Article:
curl -X POST http://localhost:8080/api/v1/editor/news \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"My Article",
"content":"{\"type\":\"doc\",\"content\":[...]}",
"category_id":1,
"type":"article",
"tag_ids":[1,2]
}'Create Poll:
curl -X POST http://localhost:8080/api/v1/admin/polls \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"title":"What is your favorite framework?",
"description":"Help us improve our stack",
"poll_type":"single",
"is_anonymous":false,
"show_results":"after",
"options":[
{"text":"Vue.js","order":1},
{"text":"React","order":2},
{"text":"Angular","order":3}
]
}'Vote on Poll:
curl -X POST http://localhost:8080/api/v1/polls/1/vote \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"poll_option_id":1
}'Get Notifications:
curl -X GET http://localhost:8080/api/v1/notifications \
-H "Authorization: Bearer <token>"Mark Notification as Read:
curl -X PUT http://localhost:8080/api/v1/notifications/1/read \
-H "Authorization: Bearer <token>"Symptoms: Login page shown instead of auto-login
Solutions:
- Check
SSO_ENABLED=truein environment variables - Verify Authentik headers in DevTools (Network > Headers)
- Check backend logs:
docker-compose logs backend | grep SSO - Verify NPM forwards headers (Advanced config)
- Test with curl:
curl -H "X-authentik-email: test@example.com" \
-H "X-authentik-username: test" \
http://localhost:8080/api/v1/auth/sso/auto-loginSymptoms: API calls return 404
Solutions:
- Check
proxy_set_header Host $host;in NPM - Verify correct Coolify domain
- Check frontend
nginx.confproxies/api/v1/ - Test backend directly:
curl http://backend:8080/health
Symptoms: Backend crashes on startup
Solutions:
- Check
DB_HOST=postgres(Docker service name) - Verify
DB_PASSWORDmatches in postgres and backend - Wait for health check:
docker-compose logs postgres - Test connection:
docker-compose exec postgres psql -U airboard
Symptoms: "port already allocated"
Solutions:
- Check ports 80, 8080, 5432 are free:
sudo netstat -tulpn - Stop conflicting services:
sudo systemctl stop nginx - Use
docker-compose.prod.yamlwithexposeinstead ofports
Symptoms: High response times
Solutions:
- Check Docker resources:
docker stats - Increase RAM: Modify Docker limits
- Check DB indexes:
docker-compose exec postgres psql -U airboard -c "\d+ news" - Reduce
BCRYPT_COSTif login slow (min 10, max 13) - Check logs:
docker-compose logs --tail=100
Symptoms: Errors on backend startup
Solutions:
- Remove volume:
docker-compose down -v - Recreate DB:
docker-compose up -d postgres - Check migration logs:
docker-compose logs backend | grep "migrating" - Manual connection:
docker-compose exec postgres psql -U airboard -d airboard
\dt # List tables
\q # QuitSymptoms: Slow build, disk space
Solutions:
- Clean images:
docker system prune -a - Optimize build: Multi-stage already implemented
- Check layers:
docker images
Solutions:
# Complete logs
docker-compose logs
# Real-time logs
docker-compose logs -f
# Backend only
docker-compose logs -f backend
# Last 100 lines
docker-compose logs --tail=100To start from scratch:
# Stop and remove everything
docker-compose down -v
# Remove images
docker rmi airboard-backend airboard-frontend
# Rebuild
docker-compose build --no-cache
docker-compose up -d- HOW-TO-USE.md - Complete usage guide
- First login and configuration
- Daily usage
- Administration
- Group Admin management
- Best practices
- Detailed architecture
- Development patterns
- Adding features
- Advanced configuration
- Development workflow
.env.example- Environment variables templatedocker-compose.yaml- Local orchestrationdocker-compose.prod.yaml- Production orchestration (Coolify)
Contributions are welcome! Follow these steps:
# Fork on GitHub, then:
git clone https://github.com/YOUR_USERNAME/airboard.git
cd airboardgit checkout -b feature/my-feature- Follow existing code style
- Add tests if applicable
- Update documentation
git add .
git commit -m "feat: Add my feature"Commit convention:
feat:- New featurefix:- Bug fixdocs:- Documentationstyle:- Formattingrefactor:- Refactoringtest:- Testschore:- Maintenance
git push origin feature/my-featureOpen a Pull Request on GitHub with:
- Clear description
- Screenshots if UI
- Tests performed
- Clean and commented code
- No hardcoded secrets
- Environment variables for config
- Server-side validation
- Appropriate error handling
- Informative logs
| Feature | Status |
|---|---|
| JWT Auth | Complete |
| Authentik SSO | Complete |
| Group Admin Role | Complete |
| Private/Public Groups | Complete |
| OAuth2 (Google/MS) | Complete |
| News Hub | Complete |
| Polls & Surveys | Complete |
| In-App Notifications | Complete |
| Analytics | Complete |
| Multi-language | Complete |
| Docker | Complete |
| OWASP 2025 Security | Complete |
| Automated tests | In Progress |
| LDAP Integration | Planned |
| Kubernetes Support | Planned |
| Mobile App | Planned |
| Push Notifications | Planned |
| Public API | Planned |
| WebSocket Real-time | Planned |
- Documentation: This README + HOW-TO-USE.md +
- Issues: GitHub Issues
- Discussions: GitHub Discussions
This project is licensed under the MIT License. See LICENSE for details.
- Vue.js - The progressive JavaScript framework
- Gin - Fast HTTP web framework for Go
- Docker - Container platform
- TailwindCSS - Utility-first CSS framework
- Authentik - Open-source identity provider
- Coolify - Self-hosted Heroku alternative
- GORM - ORM library for Golang
- Pinia - Vue state management
- Tiptap - WYSIWYG editor
- All open-source contributors
Current version: 2.0.0
Last update: February 2026
Maintenance: Active
Production ready: Yes
If you find this project useful, give it a star!















