# How CodeWiki Authenticates with Private GitHub Repositories Using Tokens

> Learn how CodeWiki authenticates with private GitHub repos. Discover its token-based approach for secure API requests and seamless integration.

- Repository: [Luong Quang Dung/codewiki](https://github.com/quangdungluong/codewiki)
- Tags: how-to-guide
- Published: 2026-02-16

---

**CodeWiki authenticates with private GitHub repositories by accepting a personal access token (PAT) from the client, storing it in the repository fetcher class, and injecting it into the `Authorization` header of every GitHub API request.**

CodeWiki, an open-source project by `quangdungluong/codewiki`, generates AI-powered documentation for code repositories. To access private GitHub repositories, the application implements a token-based authentication flow that forwards client-provided credentials to the GitHub REST API. This approach ensures secure access without storing sensitive tokens server-side beyond the scope of a single request.

## Token-Based Authentication Flow in CodeWiki

The authentication system follows a four-step pipeline: capturing the token from the API request, propagating it through the service layer, constructing authenticated HTTP headers, and executing branch-agnostic repository retrieval.

### Capturing the Personal Access Token

Authentication begins at the API boundary. The request models in [`api/models.py`](https://github.com/quangdungluong/codewiki/blob/main/api/models.py) define an optional `token` field that clients populate with a GitHub personal access token.

```python

# api/models.py

class ChatCompletionRequest(BaseModel):
    owner: str
    repo: str
    token: Optional[str] = None  # GitHub PAT for private repos

    # ... additional fields

```

When a user submits a wiki generation request to the `/api/wiki/generate` endpoint defined in [`api/wiki.py`](https://github.com/quangdungluong/codewiki/blob/main/api/wiki.py), the FastAPI route handler extracts this token and passes it to the repository fetcher.

### Propagating the Token to Repository Fetchers

The token propagates through two primary service classes: the modern `RepositoryStructureFetcher` in [`utils/repository_structure.py`](https://github.com/quangdungluong/codewiki/blob/main/utils/repository_structure.py) and the legacy `GithubService` in [`api/services/github_service.py`](https://github.com/quangdungluong/codewiki/blob/main/api/services/github_service.py). Both classes store the token as an instance variable during initialization.

```python

# utils/repository_structure.py

class RepositoryStructureFetcher:
    def __init__(self, owner: str, repo: str, token: Optional[str] = None):
        self.owner = owner
        self.repo = repo
        self.token = token  # Stored for subsequent API calls

```

This design ensures the token remains available throughout the lifecycle of the repository analysis process without requiring repeated client input.

### Injecting Authentication Headers

Both service classes implement a `create_github_headers` helper method that constructs the HTTP headers required by the GitHub REST API. When a token is present, the method injects it using the `token` authentication scheme.

```python
def create_github_headers(self, token: Optional[str]) -> Dict[str, str]:
    headers = {"Accept": "application/vnd.github.v3+json"}
    if token:
        headers["Authorization"] = f"token {token}"
    return headers

```

The resulting `Authorization: token <PAT>` header accompanies every GitHub API request, including tree traversal operations and README retrieval. This header format complies with GitHub's REST API authentication specifications for personal access tokens.

## Implementing GitHub API Authentication in Python

The authentication logic integrates directly into the repository content retrieval workflow. After constructing the headers, the application executes authenticated HTTP requests to fetch repository metadata and file structures.

### Fetching the Repository Tree with Authentication

The `RepositoryStructureFetcher` uses the authenticated headers when requesting the repository's git tree structure. This operation supports private repositories by including the authorization token in the request.

```python
def fetch_tree(self, branch: str = "main"):
    api_url = f"https://api.github.com/repos/{self.owner}/{self.repo}/git/trees/{branch}?recursive=1"
    headers = self.create_github_headers(self.token)
    response = requests.get(api_url, headers=headers)
    
    if response.status_code == 404:
        raise ValueError("Repository not found or private without valid token")
    return response.json()

```

This implementation resides in [`utils/repository_structure.py`](https://github.com/quangdungluong/codewiki/blob/main/utils/repository_structure.py) and demonstrates the complete authentication flow from token storage to API execution.

## Handling Private Repository Access and Error Cases

CodeWiki implements branch-agnostic retrieval and comprehensive error handling to manage the complexities of private repository access.

### Branch-Agnostic Repository Retrieval

Private repositories may use either `main` or `master` as their default branch. The fetcher attempts both branches sequentially when the initial request fails, ensuring compatibility across different repository configurations.

When the token is missing or invalid, GitHub returns a 404 (Not Found) or 401 (Unauthorized) status code. The application catches these responses and raises descriptive exceptions that the frontend translates into user-facing messages indicating that the repository might be private or the token might be invalid.

## API Usage Example

To authenticate with a private repository when generating documentation, include your personal access token in the request payload.

### cURL Request with Authentication Token

```bash
curl -X POST https://<codewiki-host>/api/wiki/generate \
  -H "Content-Type: application/json" \
  -d '{
        "owner": "quangdungluong",
        "repo":  "codewiki",
        "repo_url": "https://github.com/quangdungluong/codewiki",
        "repo_info": {"type":"web"},
        "token": "ghp_XXXXXXXXXXXXXXXXXXXX"
      }'

```

Replace `ghp_XXXXXXXXXXXXXXXXXXXX` with your GitHub personal access token that has `repo` scope permissions. The `token` field propagates through the system and authenticates all subsequent GitHub API requests.

## Summary

- **Token-based authentication**: CodeWiki accepts GitHub personal access tokens via the `token` field in `ChatCompletionRequest` and `WikiTaskRequest` models defined in [`api/models.py`](https://github.com/quangdungluong/codewiki/blob/main/api/models.py).
- **Header injection**: The `create_github_headers` method in [`utils/repository_structure.py`](https://github.com/quangdungluong/codewiki/blob/main/utils/repository_structure.py) constructs the `Authorization: token <PAT>` header required by GitHub's REST API.
- **Service propagation**: Both `RepositoryStructureFetcher` and `GithubService` store the token instance variable and use it for all API calls, including tree retrieval and README fetching.
- **Error handling**: Invalid or missing tokens result in 401/404 responses from GitHub, which CodeWiki surfaces as user-friendly messages indicating potential privacy restrictions.

## Frequently Asked Questions

### What type of GitHub token does CodeWiki require?

CodeWiki requires a **GitHub personal access token (PAT)** with repository access permissions. For private repositories, the token must have the `repo` scope enabled. Classic tokens or fine-grained personal access tokens both work, provided they grant read access to the target repository's contents.

### Where do I provide my GitHub token when using CodeWiki?

You provide the token in the JSON payload of the POST request to the `/api/wiki/generate` endpoint. Specifically, include it as the `token` field alongside the `owner`, `repo`, and `repo_url` fields. The backend extracts this value from the request model and uses it to authenticate all subsequent GitHub API calls.

### How does CodeWiki handle authentication errors from GitHub?

When GitHub returns a 401 (Unauthorized) or 404 (Not Found) status code—typically indicating an invalid, expired, or missing token—CodeWiki catches these exceptions in the `RepositoryStructureFetcher` class. The application raises a descriptive error that propagates to the frontend, displaying a message that the repository might be private or that the provided token may be invalid, prompting the user to verify their credentials.

### Is my GitHub token stored permanently by CodeWiki?

No, CodeWiki does not store tokens permanently. The token exists only as an instance variable on the `RepositoryStructureFetcher` or `GithubService` class during the lifetime of a single wiki generation request. Once the repository structure is fetched and the documentation generation completes, the token goes out of scope and is not persisted to any database or long-term storage, minimizing security risks.