Skip to content

Add API Authentication & Authorization [10](#header-10) #31

@fuzziecoder

Description

@fuzziecoder

🎯 Issue Summary

Implement JWT-based authentication and role-based authorization for API endpoints.

📋 Current Behavior

All API endpoints are publicly accessible without authentication.

Security Risks:

  • No user authentication
  • No access control
  • Anyone can execute/delete pipelines

✨ Proposed Solution

Implement JWT authentication with:

  • User registration/login
  • Token-based authentication
  • Role-based access control (Admin, Developer, Viewer)

🔧 Technical Requirements

1. Dependencies

  • Add python-jose[cryptography], passlib[bcrypt] to requirements
  • Add python-multipart for form data

2. User Model

  • Create backend/models/user.py with User model
  • Fields: id, username, email, hashed_password, role
  • Store users in database

3. Authentication

  • Create backend/api/routes/auth.py
  • Implement POST /api/auth/register
  • Implement POST /api/auth/login (returns JWT)
  • Implement POST /api/auth/refresh (refresh token)

4. Authorization

  • Create backend/api/dependencies/auth.py
  • Implement get_current_user dependency
  • Implement require_role dependency
  • Protect endpoints with dependencies

5. Middleware

  • Add JWT validation middleware
  • Extract user from token
  • Inject user into request context

📝 Acceptance Criteria

  • ✅ Users can register and login
  • ✅ JWT tokens issued on successful login
  • ✅ Protected endpoints require valid token
  • ✅ Role-based access enforced (Admin can delete, Viewer cannot)
  • ✅ Token expiration and refresh working

💡 Implementation Example

# backend/api/dependencies/auth.py  [11](#header-11)
from fastapi import Depends, HTTPException  
from fastapi.security import HTTPBearer  
from jose import jwt  
  
security = HTTPBearer()  
  
async def get_current_user(token: str = Depends(security)):  
    try:  
        payload = jwt.decode(token.credentials, SECRET_KEY, algorithms=["HS256"])  
        user_id = payload.get("sub")  
        return await User.get_by_id(user_id)  
    except:  
        raise HTTPException(status_code=401, detail="Invalid token")  
  
# Usage:  [12](#header-12)
@router.delete("/{id}")  
async def delete_pipeline(id: str, user: User = Depends(get_current_user)):  
    if user.role != "admin":  
        raise HTTPException(status_code=403, detail="Forbidden")  
    # Delete pipeline

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions