Skip to content

Feature Request: Pass Request Object to Custom Auth Backend #18

@Sarthak422004

Description

@Sarthak422004

Feature Request: Pass Request Object to Custom Auth Backend

Description

The current BaseAuth.authenticate() method only receives Response and HTTPAuthorizationCredentials parameters. This limits custom authentication implementations to only Bearer token-based auth.

Many applications need to authenticate using custom headers (e.g., x-signature, x-user-id, x-api-key) which requires access to the Request object.

Current Implementation

base_auth.py

class BaseAuth(ABC):
    @abstractmethod
    def authenticate(
        self, res: Response, credential: HTTPAuthorizationCredentials
    ) -> dict[str, Any] | None:
        ...

auth_backend.py

def verify_current_user(
    res: Response,
    credential: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False)),
    ...
) -> dict[str, Any]:
    ...
    user: dict | None = auth_backend.authenticate(res, credential)
    ...

Proposed Changes

1. Update base_auth.py

from fastapi import Response, Request

class BaseAuth(ABC):
    @abstractmethod
    def authenticate(
        self, 
        res: Response, 
        credential: HTTPAuthorizationCredentials,
        request: Request = None  # Add optional request parameter
    ) -> dict[str, Any] | None:
        """Authenticate the user based on the provided credentials.
        
        Args:
            res: FastAPI Response object
            credential: HTTPAuthorizationCredentials (Bearer token)
            request: FastAPI Request object (optional, for accessing custom headers)
        """
        raise NotImplementedError

2. Update auth_backend.py

from fastapi import Depends, Response, Request

def verify_current_user(
    request: Request,  # Add Request dependency
    res: Response,
    credential: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False)),
    config: GraphConfig = InjectAPI(GraphConfig),
    auth_backend: BaseAuth = InjectAPI(BaseAuth),
) -> dict[str, Any]:
    ...
    user: dict | None = auth_backend.authenticate(res, credential, request)  # Pass request
    ...

Use Case: Signed Header Authentication

With this change, users can implement header-based authentication:

class SignedHeaderAuth(BaseAuth):
    def authenticate(
        self,
        res: Response,
        credential: HTTPAuthorizationCredentials,
        request: Request = None
    ) -> dict[str, Any]:
        # Access custom headers
        user_id = request.headers.get("x-user-id")
        signature = request.headers.get("x-signature")
        role = request.headers.get("x-user-role")
        
        # Validate signature...
        
        return {"user_id": user_id, "role": role}

Backward Compatibility

The request parameter is optional with default None, so existing custom auth implementations will continue to work without modification.

File Locations

  1. agentflow_cli/src/app/core/auth/base_auth.py
  2. agentflow_cli/src/app/core/auth/auth_backend.py

Benefits

  • Enables header-based authentication (API keys, signed headers, HMAC)
  • Allows access to request metadata (IP, cookies, query params)
  • No breaking changes to existing implementations
  • Follows FastAPI patterns

Impact

  • Severity: Enhancement
  • Affected Users: Anyone needing non-Bearer-token authentication
  • Current Workaround: Manually patch the library files locally

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions