DeepWiki-Open can access private repositories across multiple platforms using personal access tokens. This comprehensive guide covers token creation, management, security best practices, and troubleshooting for GitHub, GitLab, and BitBucket.

Overview

Private repository access requires authentication tokens that prove your authorization to access the repository content. DeepWiki supports multiple platforms and token types with different permission models.

GitHub

Classic and fine-grained personal access tokens with repository scope

GitLab

Personal access tokens with read_repository scope

BitBucket

App passwords with repository read permissions

Enterprise

Organization and enterprise-specific considerations

GitHub Access Tokens

GitHub offers two types of personal access tokens with different scopes and capabilities.

Classic Personal Access Tokens

1

Navigate to Token Settings

  1. Go to GitHub.com and sign in
  2. Click your profile picture → Settings
  3. In the left sidebar, click Developer settings
  4. Click Personal access tokensTokens (classic)
Classic tokens provide broad access but are easier to set up for multiple repositories.
2

Generate New Token

  1. Click Generate new tokenGenerate new token (classic)
  2. Enter a descriptive note (e.g., “DeepWiki Documentation Access”)
  3. Set expiration (recommended: 90 days for security)
  4. Select scopes based on your needs:
3

Copy and Store Token

  1. Click Generate token
  2. Important: Copy the token immediately - you won’t see it again
  3. Store securely (see security best practices below)
GitHub classic tokens start with ghp_ and are 40 characters long. Never share or commit tokens to code repositories.

Fine-Grained Personal Access Tokens (Beta)

For more granular control over repository access:
1

Create Fine-Grained Token

  1. In Developer settingsPersonal access tokens
  2. Click Fine-grained tokensGenerate new token
  3. Configure token details:
    • Token name: Descriptive name
    • Expiration: 90 days recommended
    • Resource owner: Select your account or organization
2

Select Repository Access

Choose repository access level:
Best for: Specific repositories
  • Click “Selected repositories”
  • Choose specific repositories from dropdown
  • More secure, limited scope
Permissions needed:
  • Repository permissions: Contents (Read)
  • Metadata: Read
3

Configure Permissions

Set minimum required permissions:
{
  "Contents": "Read",
  "Metadata": "Read", 
  "Pull requests": "Read",
  "Issues": "Read"
}
Fine-grained tokens provide better security through specific repository and permission selection.

GitHub Enterprise

For GitHub Enterprise Server instances:

GitLab Access Tokens

GitLab uses personal access tokens with specific scope-based permissions.

Personal Access Token Creation

1

Access Token Settings

  1. Sign in to GitLab.com or your GitLab instance
  2. Click your avatar → Edit profile
  3. In the left sidebar, click Access Tokens
GitLab tokens are more granular than GitHub classic tokens, allowing precise permission control.
2

Create New Token

  1. Click Add new token
  2. Configure token settings:
    • Token name: Descriptive name (e.g., “DeepWiki Access”)
    • Expiration date: Set appropriate expiration
    • Select scopes: Choose required permissions
3

Generate and Store

  1. Click Create personal access token
  2. Copy the generated token immediately
  3. Store securely with appropriate labels
GitLab tokens start with glpat- followed by 20 characters. They cannot be viewed again after creation.

GitLab Self-Managed

For self-hosted GitLab instances:
Configuration requirements:
  • Same token creation process
  • Verify network connectivity to your GitLab instance
  • Check SSL certificate configuration
{
  "repo_url": "https://gitlab.company.com/team/private-project",
  "access_token": "glpat-xxxxxxxxxxxxxxxxxxxx",
  "gitlab_base_url": "https://gitlab.company.com"
}

BitBucket Access

BitBucket uses app passwords instead of traditional tokens, with different permission models.

App Password Creation

1

Access App Password Settings

  1. Sign in to BitBucket.org
  2. Click your avatar → Personal BitBucket settings
  3. In the left menu, click App passwords
BitBucket app passwords are repository-specific credentials with granular permissions.
2

Create App Password

  1. Click Create app password
  2. Configure password settings:
    • Label: Descriptive name (e.g., “DeepWiki Documentation”)
    • Permissions: Select required access levels
3

Generate Password

  1. Click Create
  2. Copy the generated app password
  3. Store with username for authentication
BitBucket app passwords are unique strings (not prefixed). You’ll need both your username and app password for authentication.

BitBucket Server/Data Center

For on-premises BitBucket instances:
BitBucket Server uses personal access tokens:
  1. Go to your BitBucket Server instance
  2. Click your avatar → Manage account
  3. Click Personal access tokens
  4. Create token with Repository read permission
{
  "repo_url": "https://bitbucket.company.com/projects/TEAM/repos/private-repo",
  "access_token": "your-personal-access-token",
  "bitbucket_base_url": "https://bitbucket.company.com"
}

Token Security Best Practices

Secure Token Storage

Access Control

1

Principle of Least Privilege

Minimize token permissions:
  • Use read-only scopes when possible
  • Avoid admin or write permissions
  • Prefer fine-grained tokens over classic tokens
  • Regular audit of token permissions
Review token permissions quarterly to ensure they match current needs.
2

Network Security

Restrict token usage:
# Nginx configuration for IP restrictions
location /api/wiki/generate {
    allow 192.168.1.0/24;  # Internal network
    allow 10.0.0.0/8;      # Private network
    deny all;              # Block external access
    
    proxy_pass http://deepwiki-backend;
}
API endpoint protection:
# Rate limiting by token
from functools import lru_cache

@lru_cache(maxsize=1000)
def get_rate_limit(token: str):
    return RateLimiter(requests_per_minute=10)

def validate_token_request(token: str):
    rate_limiter = get_rate_limit(token)
    if not rate_limiter.allow_request():
        raise RateLimitExceeded("Token rate limit exceeded")
3

Monitoring and Alerting

Token usage monitoring:
{
  "token_monitoring": {
    "track_usage": true,
    "alert_on_failures": true,
    "log_access_patterns": true,
    "detect_anomalies": true
  },
  "alerts": {
    "token_expiry_warning": "7d",
    "unusual_usage_pattern": true,
    "failed_authentication": {
      "threshold": 5,
      "window": "1h"
    }
  }
}
Security event logging:
import logging

security_logger = logging.getLogger('security')

def log_token_usage(token_hash: str, repo_url: str, success: bool):
    security_logger.info({
        'event': 'token_usage',
        'token_hash': token_hash,
        'repository': repo_url,
        'success': success,
        'timestamp': datetime.now().isoformat(),
        'ip_address': get_client_ip()
    })

Using Tokens with DeepWiki

API Integration

Direct API calls:
# GitHub private repository
curl -X POST "http://localhost:8001/wiki/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "repo_url": "https://github.com/company/private-repo",
    "access_token": "ghp_xxxxxxxxxxxxxxxxxxxx",
    "model_provider": "google"
  }'

# GitLab private repository  
curl -X POST "http://localhost:8001/wiki/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "repo_url": "https://gitlab.com/company/private-project",
    "access_token": "glpat-xxxxxxxxxxxxxxxxxxxx", 
    "model_provider": "google"
  }'

# BitBucket private repository
curl -X POST "http://localhost:8001/wiki/generate" \
  -H "Content-Type: application/json" \
  -d '{
    "repo_url": "https://bitbucket.org/company/private-repo",
    "access_token": "your-app-password",
    "username": "your-username",
    "model_provider": "google"
  }'

Web Interface Integration

1

Token Input Component

Secure token input:
import { useState } from 'react';

function TokenInput({ onTokenChange, platform }) {
  const [token, setToken] = useState('');
  const [showToken, setShowToken] = useState(false);
  
  const handleTokenChange = (value) => {
    setToken(value);
    onTokenChange(value);
  };
  
  const tokenPatterns = {
    github: /^(ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]+)$/,
    gitlab: /^glpat-[a-zA-Z0-9]{20}$/,
    bitbucket: /^[a-zA-Z0-9]+$/
  };
  
  const isValidToken = tokenPatterns[platform]?.test(token);
  
  return (
    <div className="token-input">
      <label htmlFor="access-token">
        {platform.charAt(0).toUpperCase() + platform.slice(1)} Access Token
      </label>
      <div className="input-group">
        <input
          id="access-token"
          type={showToken ? 'text' : 'password'}
          value={token}
          onChange={(e) => handleTokenChange(e.target.value)}
          placeholder={`Enter ${platform} access token`}
          className={isValidToken ? 'valid' : 'invalid'}
        />
        <button
          type="button"
          onClick={() => setShowToken(!showToken)}
          aria-label={showToken ? 'Hide token' : 'Show token'}
        >
          {showToken ? '👁️' : '👁️‍🗨️'}
        </button>
      </div>
      {!isValidToken && token.length > 0 && (
        <div className="error">
          Invalid {platform} token format
        </div>
      )}
    </div>
  );
}
2

Token Validation

Client-side validation:
async function validateRepositoryAccess(repoUrl, accessToken, platform) {
  try {
    const response = await fetch('/api/validate-token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        repo_url: repoUrl,
        access_token: accessToken,
        platform: platform
      })
    });
    
    const result = await response.json();
    return {
      valid: result.valid,
      permissions: result.permissions,
      error: result.error
    };
  } catch (error) {
    return {
      valid: false,
      error: 'Network error during validation'
    };
  }
}

// Usage in form submission
const handleSubmit = async (formData) => {
  const validation = await validateRepositoryAccess(
    formData.repoUrl,
    formData.accessToken,
    formData.platform
  );
  
  if (!validation.valid) {
    setError(`Token validation failed: ${validation.error}`);
    return;
  }
  
  // Proceed with wiki generation
  generateWiki(formData);
};

Organization and Enterprise Considerations

GitHub Organizations

GitLab Groups and Projects

GitLab group considerations:
  • Group membership requirements
  • Project-level permissions inheritance
  • Shared runner restrictions
  • Group-level tokens (GitLab Premium+)
{
  "group_access": {
    "group_name": "company-dev-team",
    "member_role": "developer",
    "project_access_level": "read",
    "shared_runners_enabled": false
  }
}

Token Management at Scale

Multi-Repository Management

1

Centralized Token Store

Token management system:
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Dict, List
import keyring

@dataclass
class RepositoryToken:
    platform: str
    token: str
    repositories: List[str]
    expires_at: datetime
    permissions: List[str]
    
class TokenManager:
    def __init__(self):
        self.tokens: Dict[str, RepositoryToken] = {}
    
    def add_token(self, name: str, token: RepositoryToken):
        # Store in secure keyring
        keyring.set_password("deepwiki", name, token.token)
        self.tokens[name] = token
        
    def get_token_for_repo(self, repo_url: str) -> str:
        for token_data in self.tokens.values():
            if any(repo in repo_url for repo in token_data.repositories):
                return keyring.get_password("deepwiki", token_data.token)
        return None
        
    def check_expiring_tokens(self, days: int = 7) -> List[str]:
        expiring = []
        threshold = datetime.now() + timedelta(days=days)
        
        for name, token in self.tokens.items():
            if token.expires_at < threshold:
                expiring.append(name)
                
        return expiring
2

Automated Token Rotation

Rotation workflow:
class TokenRotationService:
    def __init__(self, token_manager: TokenManager):
        self.token_manager = token_manager
        
    async def rotate_github_token(self, old_token_name: str):
        # This would integrate with GitHub API to create new tokens
        # Note: GitHub doesn't provide token creation API
        # This is a conceptual example
        
        old_token = self.token_manager.tokens[old_token_name]
        
        # Generate new token (manual process for GitHub)
        new_token_value = await self._prompt_for_new_token()
        
        # Test new token
        if await self._test_token_access(new_token_value, old_token.repositories):
            # Update stored token
            new_token = RepositoryToken(
                platform=old_token.platform,
                token=new_token_value,
                repositories=old_token.repositories,
                expires_at=datetime.now() + timedelta(days=90),
                permissions=old_token.permissions
            )
            
            self.token_manager.add_token(old_token_name, new_token)
            
            # Schedule old token revocation
            await self._schedule_token_revocation(old_token.token)
            
            return True
        return False

Monitoring and Analytics

Troubleshooting

Common Issues

Advanced Debugging

1

Enable Debug Logging

API server debugging:
import logging

# Configure detailed logging
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('deepwiki-debug.log'),
        logging.StreamHandler()
    ]
)

# Log repository access attempts
repo_logger = logging.getLogger('repository_access')

def log_repository_access(repo_url, token_hash, success, error=None):
    repo_logger.debug({
        'repository': repo_url,
        'token_hash': token_hash,  # Never log actual token
        'success': success,
        'error': str(error) if error else None,
        'timestamp': datetime.now().isoformat()
    })
2

Network Diagnostics

Connection testing:
#!/bin/bash
# Network connectivity test

test_github_connectivity() {
    echo "Testing GitHub API connectivity..."
    
    # Test DNS resolution
    nslookup api.github.com
    
    # Test HTTPS connectivity
    curl -I https://api.github.com/
    
    # Test authentication
    curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/user
}

test_enterprise_connectivity() {
    local enterprise_url=$1
    echo "Testing enterprise connectivity: $enterprise_url"
    
    # Test SSL certificate
    openssl s_client -connect ${enterprise_url}:443 -servername $enterprise_url
    
    # Test API endpoint
    curl -I ${enterprise_url}/api/v3/
}

# Run tests
test_github_connectivity
test_enterprise_connectivity "github.enterprise.com"
3

Token Analysis Tools

Token inspection utility:
import base64
import json
from datetime import datetime

class TokenAnalyzer:
    def __init__(self):
        self.platform_patterns = {
            'github_classic': r'^ghp_[a-zA-Z0-9]{36}$',
            'github_fine_grained': r'^github_pat_[a-zA-Z0-9_]+$',
            'gitlab': r'^glpat-[a-zA-Z0-9]{20}$',
            'bitbucket': r'^[a-zA-Z0-9]+$'
        }
    
    def identify_platform(self, token: str) -> str:
        for platform, pattern in self.platform_patterns.items():
            if re.match(pattern, token):
                return platform
        return 'unknown'
    
    def analyze_github_token(self, token: str) -> dict:
        headers = {'Authorization': f'token {token}'}
        
        # Get token info (doesn't exist in GitHub API)
        # This is conceptual - GitHub doesn't provide token introspection
        user_response = requests.get('https://api.github.com/user', headers=headers)
        
        if user_response.status_code != 200:
            return {'error': 'Invalid token or insufficient permissions'}
            
        user_data = user_response.json()
        
        # Test repository access
        repos_response = requests.get('https://api.github.com/user/repos', headers=headers)
        
        return {
            'platform': 'github',
            'user': user_data.get('login'),
            'scopes': user_response.headers.get('X-OAuth-Scopes', '').split(', '),
            'rate_limit': {
                'limit': user_response.headers.get('X-RateLimit-Limit'),
                'remaining': user_response.headers.get('X-RateLimit-Remaining'),
                'reset': user_response.headers.get('X-RateLimit-Reset')
            },
            'repository_access': repos_response.status_code == 200
        }

# Usage
analyzer = TokenAnalyzer()
result = analyzer.analyze_github_token("ghp_xxxxxxxxxxxxxxxxxxxx")
print(json.dumps(result, indent=2))

Next Steps