Skip to content

Latest commit

 

History

History
296 lines (232 loc) · 8.14 KB

File metadata and controls

296 lines (232 loc) · 8.14 KB

Forge Utah Foundation - Authentication & Authorization

Overview

The Forge Platform provides a centralized authentication and authorization service that handles:

  • OAuth 2.0 authentication via Slack
  • JWT token generation with role-based claims
  • RBAC (Role-Based Access Control) for fine-grained permissions
  • Multi-application support for all Forge Utah services

Architecture

Components

  1. Auth Server (cmd/auth-server/main.go)

    • Handles OAuth flow with Slack
    • Issues JWT tokens with RBAC claims
    • Provides authorization endpoints
    • Manages user roles and permissions
  2. TUI Client (cmd/test-tui/main.go)

    • Terminal interface for testing authentication
    • Demonstrates integration patterns
  3. RBAC System

    • Role and permission management
    • Casbin-based policy enforcement
    • Persistent storage of access control data

Authentication Flow

1. Web Application Flow

sequenceDiagram
    User->>App: Access protected resource
    App->>Auth Portal: Redirect to /login?app_id=myapp&callback=...
    Auth Portal->>User: Show Forge Utah login page
    User->>Auth Portal: Click "Login with Slack"
    Auth Portal->>Slack: OAuth redirect
    User->>Slack: Authorize
    Slack->>Auth Portal: Callback with code
    Auth Portal->>Auth Portal: Generate JWT with roles
    Auth Portal->>App: POST tokens to callback URL
    App->>User: Authenticated session
Loading

2. TUI/CLI Application Flow

# Application opens browser to auth portal
https://auth.forge.utah/login?app_id=forge-cli&callback=http://localhost:8081/auth

# Auth server attempts to:
1. POST tokens to callback URL (if provided)
2. Auto-detect TUI on localhost ports 8081-8083
3. Display code for manual entry

JWT Token Structure

{
  "user_id": "user_abc123",
  "email": "user@forge.utah",
  "name": "John Doe",
  "slack_id": "U0123456789",
  "workspace_id": "TC92KEFJT",
  "roles": ["verified", "meetup_organizer"],
  "permissions": [
    "content:read",
    "content:write",
    "meetups:create",
    "meetups:manage"
  ],
  "type": "access",
  "iat": 1703001234,
  "exp": 1703087634
}

RBAC System

Role Hierarchy

Role Description Default Permissions
viewer Default for new users View public content, meetups, projects
verified Verified community members Create content, RSVP to events, view profiles
moderator Community moderators Moderate content, ban users
meetup_organizer Event organizers Create/manage meetups, view analytics
admin Organization administrators Manage users, projects, settings
super_admin Full system access All permissions (admin:all)

Permission Format

Permissions follow the format: resource:action

Resources:

  • content - Posts, comments, discussions
  • meetups - Events and gatherings
  • users - User accounts and profiles
  • projects - Forge Utah projects
  • settings - System configuration
  • admin - Administrative functions

Actions:

  • read - View resource
  • write - Create/edit resource
  • delete - Remove resource
  • moderate - Moderate content
  • manage - Full management
  • verify - Verify users
  • ban - Ban users
  • all - All actions

API Endpoints

Authentication Endpoints

Endpoint Method Description
/ or /login GET Login portal page
/auth/start GET Get OAuth URL (API)
/callback GET OAuth callback from Slack
/auth/exchange POST Exchange code for tokens

Authorization Endpoints

Endpoint Method Description Required Permission
/auth/check POST Check user permission None
/auth/roles GET Get user's roles None
/auth/permissions GET Get user's permissions None

Admin Endpoints

Endpoint Method Description Required Permission
/admin/roles GET List all roles users:read
/admin/permissions GET List all permissions users:read
/admin/users/{id}/roles GET Get user's roles users:read
/admin/users/{id}/roles POST Assign role to user users:write
/admin/users/{id}/roles/{role} DELETE Remove role from user users:write

Integration Guide

1. Redirect to Login

// Web application
const loginUrl = new URL('https://auth.forge.utah/login');
loginUrl.searchParams.append('app_id', 'my-app');
loginUrl.searchParams.append('app_name', 'My Application');
loginUrl.searchParams.append('callback', 'https://myapp.com/auth/callback');
loginUrl.searchParams.append('redirect_uri', 'https://myapp.com/dashboard');

window.location.href = loginUrl.toString();

2. Handle Callback

// Receive tokens at your callback URL
type AuthCallback struct {
    Code         string    `json:"code"`
    AccessToken  string    `json:"access_token"`
    RefreshToken string    `json:"refresh_token"`
    User         User      `json:"user"`
    ExpiresAt    time.Time `json:"expires_at"`
}

func handleAuthCallback(w http.ResponseWriter, r *http.Request) {
    var callback AuthCallback
    json.NewDecoder(r.Body).Decode(&callback)
    
    // Store tokens and create session
    session.Set("access_token", callback.AccessToken)
    session.Set("user", callback.User)
}

3. Verify Permissions

// Check permission via API
func checkPermission(token, resource, action string) (bool, error) {
    body := map[string]string{
        "token":    token,
        "resource": resource,
        "action":   action,
    }
    
    resp, err := http.Post("https://auth.forge.utah/auth/check", "application/json", body)
    // Handle response
}

// Or decode JWT locally for quick checks
claims := jwt.Parse(token)
if slices.Contains(claims["permissions"], "meetups:create") {
    // User can create meetups
}

Configuration

Environment Variables

# Slack OAuth
SLACK_CLIENT_ID=your_slack_client_id
SLACK_CLIENT_SECRET=your_slack_client_secret
SLACK_REDIRECT_URI=https://auth.forge.utah/callback
SLACK_TEAM_ID=TC92KEFJT  # Forge Utah workspace

# JWT Configuration
JWT_SECRET=your-secret-key-change-in-production
JWT_EXPIRY_HOURS=24

# Server Configuration
PORT=3000
SERVER_URL=https://auth.forge.utah

# Casbin RBAC
CASBIN_MODEL_PATH=./config/auth_model.conf
CASBIN_POLICY_PATH=./config/auth_policy.csv

Slack App Setup

  1. Create a Slack app at https://api.slack.com/apps
  2. Add OAuth scopes:
    • users:read
    • users:read.email
    • team:read
  3. Set redirect URL to: https://auth.forge.utah/callback
  4. Install app to Forge Utah workspace

Security Considerations

  1. JWT Security

    • Tokens expire after 24 hours (configurable)
    • Refresh tokens valid for 30 days
    • Secret key must be strong and rotated regularly
  2. CORS Configuration

    • Currently allows all origins (*) for development
    • Should be restricted to known applications in production
  3. Permission Checks

    • Always verify permissions server-side
    • JWT claims are for optimization, not security
    • Use /auth/check endpoint for critical operations
  4. Data Protection

    • RBAC data stored in ./data/rbac/
    • Ensure proper file permissions
    • Regular backups recommended

Deployment

See deployment.md for production deployment instructions.

Testing

# Run auth server
go run cmd/auth-server/main.go

# Test with TUI client
go run cmd/test-tui/main.go

# Test permission check
curl -X POST https://auth.forge.utah/auth/check \
  -H "Content-Type: application/json" \
  -d '{
    "token": "your-jwt-token",
    "resource": "meetups",
    "action": "create"
  }'

Troubleshooting

"ForgeBot" appears instead of user name

  • Ensure the Slack app has proper user scopes
  • Check that OAuth response includes authed_user field

RBAC service fails to initialize

  • Check that ./data/rbac/ directory is writable
  • Verify Casbin model file exists at configured path

Token validation fails

  • Ensure JWT_SECRET matches between services
  • Check token expiration time
  • Verify token type is "access" not "refresh"