Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified docs/images/phase-1-registration-and-application-setup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/phase-4-token-exchange.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/phase-5-protected-resource-access.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 97 additions & 36 deletions docs/oauth/overview.md

Large diffs are not rendered by default.

49 changes: 26 additions & 23 deletions docs/oauth/phase-1-registration-and-application-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

![Phase 1](../images/phase-1-registration-and-application-setup.png)

## **Overview**
## Overview

Phase 1 establishes the foundation of our OAuth 2.0 implementation for the testbed. It covers the **registration of applications** (representing ActivityPub services) and the creation of **immutable OAuth credentials**. This step is essential to establish trust between the authorization server (Source Service) and the client applications (Destination Services) participating in the LOLA data portability flow.

By completing this phase, each service obtains a unique **client ID** and **client secret** that identify it throughout the OAuth flow, enabling secure interactions during subsequent phases such as authorization, token exchange, and protected resource access.
By completing this phase, each service obtains a unique **Client ID** and **Client Secret** that identify it throughout the OAuth flow, enabling secure interactions during subsequent phases such as authorization, token exchange, and protected resource access.

## **Objectives of Phase 1**
## Objectives of Phase 1

- Enable new services to register with the Source Service and establish a trusted OAuth relationship.
- Generate **immutable credentials** (client ID and client secret) that remain consistent for the lifetime of the application.
- Generate **immutable credentials** (Client ID and Client Secret) that remain consistent for the lifetime of the application.
- Provide a user interface and workflow for managing OAuth application settings.
- Enforce **security best practices** by ensuring credentials are securely generated, stored, and not user-editable.

## **Context in the LOLA Flow**
## Context in the LOLA Flow

Within the **LOLA** portability process:

Expand All @@ -25,9 +25,9 @@ Within the **LOLA** portability process:

This **one user → one service → one application** model simplifies the flow while maintaining security and realism for testing ActivityPub implementations.

## **Core Components**
## Core Components

### **1. OAuth Application Form**
### 1. OAuth Application Form

The OAuthApplicationForm (**`forms/oauth_connection_form.py`**) provides the interface for registering and configuring an OAuth application.

Expand All @@ -44,17 +44,18 @@ The OAuthApplicationForm (**`forms/oauth_connection_form.py`**) provides the int

Proper validation and default configuration prevent common security pitfalls such as open redirect vulnerabilities or weak client handling.

### **2. Credential Generation & Storage**
### 2. Credential Generation & Storage

Credential handling is implemented via the get_user_application() method (oauth_utils.py):

- **Immutable Credential Creation:** If the user has no existing application, new credentials are generated using secure random functions.
- **Session-Based Raw Secret Storage:**
- The client secret is hashed when stored in the database for security.
- The raw secret is temporarily stored in the user’s session and attached as a runtime-only attribute to the application object.
- This allows it to be used for token exchange later without exposing it beyond its intended lifespan.
- Client secrets are currently stored in raw form in the database for simplicity in the testbed environment.
- The raw secret is temporarily stored in the user's session and attached as a runtime-only attribute to the application object.
- This session storage enables token exchange during the OAuth flow without requiring database retrieval of the secret.
- **Note:** Hashed client secret storage is planned as a future security enhancement for production deployments.

### **3. Index View**
### 3. Index View

The index() view serves as the **entry point** for Phase 1, integrating the form and utility logic:

Expand All @@ -63,14 +64,16 @@ The index() view serves as the **entry point** for Phase 1, integrating the form
- Handles form submissions for updating application details like redirect URIs.
- Enforces immutability of client ID and client secret through both frontend (read-only fields) and backend (overridden save() method) safeguards.

## **Security Considerations**
## Security Considerations

- **Immutable Credentials:** Client ID and client secret cannot be edited after creation.
- **Session Storage:** Raw secrets are stored only in secure server-side sessions and never persisted in plaintext.
- **Immutable Credentials:** Client ID and Client Secret cannot be edited after creation.
- **Current Storage Approach:** Client Secrets are stored in raw form in the database for testbed simplicity, with session-based access during OAuth flows.
- **Session Management:** Raw secrets are temporarily stored in secure server-side sessions to enable token exchange without additional database queries.
- **Redirect URI Validation:** Ensures callback URLs are safe and properly formatted; additional validation (e.g., allowlists, HTTPS-only) is recommended for production.
- **Audit Logging:** Key events (credential creation, retrieval, anomalies) are logged for traceability.
- **Future Security Enhancement:** Hashed Client Secret storage is planned for production deployments to enhance security.

## **User Experience Flow**
## User Experience Flow

1. **Initial Registration (New Application):**
- User accesses the registration form.
Expand All @@ -79,14 +82,14 @@ The index() view serves as the **entry point** for Phase 1, integrating the form
2. **Subsequent Visits (Existing Application):**
- Form is pre-filled with existing application data.
- Credentials remain immutable; only redirect URIs or service name can be updated.
- Raw client secret may be retrieved from session if needed for token exchange.
- Raw Client Secret may be retrieved from session if needed for token exchange.
3. **Update Flow:**
- User can update non-sensitive fields (e.g., redirect URIs).
- Client secret regeneration is not part of this phase but may be considered for future enhancements.
- Client Secret regeneration is not part of this phase but may be considered for future enhancements.

## **Implementation Details**
## Implementation Details

### **Form Snippet**
### Form Snippet

```python
class OAuthApplicationForm(forms.ModelForm):
Expand All @@ -103,7 +106,7 @@ class OAuthApplicationForm(forms.ModelForm):
}
```

### **Credential Handling Logic**
### Credential Handling Logic

```python
def get_user_application(user, request=None):
Expand Down Expand Up @@ -134,14 +137,14 @@ def get_user_application(user, request=None):
return application
```

## **Future Enhancements**
## Future Enhancements

- **Credential Rotation:** Implement a secure flow for regenerating client secrets when necessary.
- **Advanced URI Validation:** Enforce HTTPS and allowlist domains in production environments.
- **Scope Management:** Extend registration to include configurable scopes for fine-grained access control.
- **Enhanced Auditing:** Expand logging for compliance with security frameworks (SOC 2, ISO 27001).

## **Significance of Phase 1**
## Significance of Phase 1

This phase creates the **secure foundation** for the entire OAuth implementation in our testbed. By enforcing credential immutability, secure secret handling, and clear user workflows, we establish trust and ensure a robust basis for subsequent phases:

Expand Down
38 changes: 19 additions & 19 deletions docs/oauth/phase-2-authorization-request-and-user-consent.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# **Phase 2: Authorization Request & User Consent**
# Phase 2: Authorization Request & User Consent

![Phase 2](../images/phase-2-authorization-request-and-user-consent.png)

## **Overview**
## Overview

Phase 2 is the stage where the user explicitly authorizes the **Destination Service** to access their data from the **Source Service**. This phase introduces **user consent**, a core principle of OAuth 2.0 and the foundation of data portability in the LOLA implementation.

In this phase, the Destination Service constructs an **authorization request** and redirects the user to the Source Service’s authorization endpoint. The Source Service handles user authentication (if necessary) and presents a **consent screen** detailing the data to be shared. Upon user approval, the process transitions into **Phase 3: Authorization Code & Callback Handling**.

## **Objectives of Phase 2**
## Objectives of Phase 2

- Provide a secure mechanism for **user consent** within the OAuth flow.
- Ensure the **Destination Service** properly constructs the authorization request, including all required parameters.
- Validate **redirect URIs**, **scopes**, and **client credentials** at the Source Service.
- Prevent **CSRF attacks** using a cryptographically secure state parameter.
- Clearly communicate the scope and purpose of data sharing in the consent screen.

## **Context in the LOLA Flow**
## Context in the LOLA Flow

Within LOLA portability:

Expand All @@ -26,9 +26,9 @@ Within LOLA portability:

This explicit consent step differentiates LOLA from many typical OAuth implementations, which often request narrower scopes (e.g., profile or email access).

## **Core Components**
## Core Components

### **1. Authorization URL Construction**
### 1. Authorization URL Construction

The **Destination Service** initiates the flow by building an authorization URL that includes the following parameters:

Expand All @@ -51,7 +51,7 @@ state=secureRandomState

This URL is constructed dynamically in the **Destination Service’s** view, often using the current request’s scheme and host for the callback URI.

### **2. State Parameter Security**
### 2. State Parameter Security

The state parameter is critical for **CSRF protection**:

Expand All @@ -72,7 +72,7 @@ This pattern prevents:
- store_state_in_session()
- validate_state_from_session()

### **3. Consent Screen**
### 3. Consent Screen

The consent screen (authorize.html) is presented by the **Source Service** and includes:

Expand All @@ -88,7 +88,7 @@ The consent screen (authorize.html) is presented by the **Source Service** and i
- Hidden fields for necessary OAuth parameters.
- Clear visual hierarchy and plain language for user comprehension.

### **4. Validation Logic**
### 4. Validation Logic

Custom validation is implemented in ActivityPubOAuth2Validator:

Expand All @@ -102,31 +102,31 @@ Custom validation is implemented in ActivityPubOAuth2Validator:

This ensures that only valid, registered redirect URIs and scopes can proceed through the authorization process.

## **Interaction Flow**
## Interaction Flow

### **1. Initiation**
### 1. Initiation

- User clicks “Import from [Source Service]” on the Destination Service.
- Destination Service constructs the authorization URL with required parameters and a secure state.

### **2. Redirection**
### 2. Redirection

- User’s browser is redirected to /oauth/authorize at the Source Service.

### **3. Authentication**
### 3. Authentication

- If not already authenticated, the user logs into the Source Service.

### **4. Consent Presentation**
### 4. Consent Presentation

- Source Service displays the consent screen, showing requested data and permissions.

### **5. User Decision**
### 5. User Decision

- If approved: Source Service issues an authorization code and redirects to the registered redirect_uri.
- If denied: Redirect occurs with error parameters indicating denial.

## **Security Considerations**
## Security Considerations

- **State Parameter** – Prevents CSRF and replay attacks.
- **Redirect URI Validation** – Defends against open redirect and code interception attacks.
Expand All @@ -135,9 +135,9 @@ This ensures that only valid, registered redirect URIs and scopes can proceed th
- **Logging** – Records key events for auditability (invalid scopes, URIs, approvals).


## **Implementation Example**
## Implementation Example

### **Authorization URL Construction (Destination Service)**
### Authorization URL Construction (Destination Service)

```python
@login_required
Expand Down Expand Up @@ -171,7 +171,7 @@ def test_authorization_view(request):
return redirect(auth_url)
```

## **Significance of Phase 2**
## Significance of Phase 2

This phase embodies the **core consent principle** of OAuth: the user explicitly approves the data transfer. By enforcing strict scope validation, secure redirect URI handling, and robust CSRF protection, Phase 2 ensures:

Expand Down
32 changes: 16 additions & 16 deletions docs/oauth/phase-3-authorization-code-and-callback-handling.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# **Phase 3: Authorization Code & Callback Handling**
# Phase 3: Authorization Code & Callback Handling

![Phase 3](../images/phase-3-authorization-code-and-callback-handling.png)

## **Overview**
## Overview

Phase 3 represents the secure bridge between **user consent** (Phase 2) and **token exchange** (Phase 4) in our OAuth 2.0 flow. At this stage, the **Source Service (Authorization Server)** issues a **short-lived authorization code** to the **Destination Service (Client)** after the user has granted consent. This code is delivered via a secure redirect to the client’s registered callback URI and serves as proof that the user has approved the data transfer.

In the context of LOLA portability, this phase confirms user intent to transfer their entire ActivityPub account data from the Source Service to the Destination Service, enabling the next step: requesting an access token.

## **Objectives of Phase 3**
## Objectives of Phase 3

- Deliver a **temporary, one-time-use authorization code** securely to the Destination Service.
- Maintain security integrity by validating the **state parameter** to prevent CSRF attacks.
- Ensure the code is properly **bound** to the specific client, scope, and redirect URI.
- Provide a clear **callback handling process** that prepares for token exchange.
- Handle **success and error scenarios** gracefully for the end-user and client application.

## **Context in the LOLA Flow**
## Context in the LOLA Flow

This phase begins **after** the user has consented to the data transfer (Phase 2) and ends **before** the Destination Service exchanges the code for an access token (Phase 4). The key outcomes of this phase are:

Expand All @@ -25,9 +25,9 @@ This phase begins **after** the user has consented to the data transfer (Phase 2
- Validation of the state parameter to confirm request integrity.
- Preparation for the token exchange process.

## **Core Components**
## Core Components

### **1. Authorization Code Generation**
### *

- **Triggered by User Consent:** Once the user approves access on the Source Service’s consent screen, Django OAuth Toolkit generates an **authorization code**.
- **Security Properties:**
Expand All @@ -36,7 +36,7 @@ This phase begins **after** the user has consented to the data transfer (Phase 2
- Bound to the requesting client_id, approved scope, and redirect_uri.
- One-time use — automatically invalidated upon successful token exchange.

### **2. Secure Redirection**
### 2. Secure Redirection

After generating the authorization code:

Expand All @@ -49,7 +49,7 @@ https://destination.com/callback?code=abc123&state=xyz789

This preserves the security context established earlier and signals the Destination Service to begin callback handling.

### **3. Callback Handling**
### 3. Callback Handling

The **Destination Service** processes the callback via a dedicated view (oauth_callback):

Expand All @@ -58,7 +58,7 @@ The **Destination Service** processes the callback via a dedicated view (oauth_c
- Distinguishes between success (valid code) and error scenarios (denied or invalid requests).
- Prepares the code for token exchange in Phase 4.

### **4. State Parameter Validation**
### 4. State Parameter Validation

State validation ensures the callback originates from the legitimate request:

Expand All @@ -68,9 +68,9 @@ State validation ensures the callback originates from the legitimate request:

If validation fails, the request is rejected and logged as a potential security incident.

## **Implementation Details**
## Implementation Details

### **Authorization Code Handling (Callback View)**
### Authorization Code Handling (Callback View)

```python
def oauth_callback(request):
Expand Down Expand Up @@ -108,7 +108,7 @@ def oauth_callback(request):
return render(request, 'oauth_callback.html', context)
```

### **State Validation Utility**
### State Validation Utility

```python
def validate_state_from_session(request, state):
Expand All @@ -125,15 +125,15 @@ def validate_state_from_session(request, state):
return secrets.compare_digest(stored_state, state)
```

## **Security Considerations**
## Security Considerations

- **Time-Limited Codes:** Authorization codes expire after 10 minutes.
- **One-Time Use:** Codes are invalidated immediately after token exchange.
- **Client Binding:** Codes are tied to the specific client_id and redirect_uri used during authorization.
- **State Parameter Validation:** Protects against CSRF and callback forgery.
- **HTTPS Enforcement:** All production environments should transmit authorization codes exclusively over HTTPS.

## **User Experience Flow**
## User Experience Flow

1. **User Consent Granted:** Phase 2 completes, and the Source Service issues an authorization code.
2. **Redirection to Callback:** User is redirected to the Destination Service’s registered callback URI.
Expand All @@ -142,14 +142,14 @@ def validate_state_from_session(request, state):
- Authorization code is extracted and displayed/stored.
4. **Preparation for Token Exchange:** The code is now ready to be exchanged for an access token in Phase 4.

## **Future Enhancements**
## Future Enhancements

- **PKCE Support:** Add code challenge/verification for public clients.
- **Enhanced Error Handling:** Provide user-friendly error pages with actionable next steps.
- **Replay Detection Metrics:** Add monitoring for repeated invalid state or expired code attempts.
- **Automated Transition to Token Exchange:** Optionally trigger Phase 4 immediately after successful callback.

## **Significance of Phase 3**
## Significance of Phase 3

This phase ensures a **secure transition** between user consent and token issuance, preserving the integrity of the OAuth flow:

Expand Down
Loading