ProjectConfig Feature

This feature provides project configuration management including git repository settings and encrypted authentication tokens.

Overview

Each project can have a configuration that includes:

  • Git Repositories: List of repository URLs to include in the project
  • File Exclusions: Patterns to exclude files from processing (e.g., *.log, node_modules/**)
  • Git Token: Encrypted authentication token for repository access

API Endpoints

GET /api/projects/{projectId}/config

Retrieves the project configuration.

Response:

{
  "projectId": 1,
  "gitRepositories": ["https://github.com/org/repo1", "https://github.com/org/repo2"],
  "fileExclusions": ["*.log", "node_modules/**", "bin/**"],
  "hasGitToken": true,
  "createdAt": "2026-02-03T12:00:00Z",
  "updatedAt": "2026-02-03T12:00:00Z"
}

Note: The git token itself is never returned - only whether one has been configured.

PUT /api/projects/{projectId}/config

Updates the project configuration.

Request:

{
  "projectId": 1,
  "gitRepositories": ["https://github.com/org/repo1"],
  "fileExclusions": ["*.log"],
  "gitToken": "ghp_xxxxxxxxxxxx"
}

Git Token Handling:

  • null or omitted: Leave the existing token unchanged
  • "" (empty string): Clear the token
  • Any other value: Encrypt and save the new token

Response:

{
  "success": true,
  "message": "Project configuration updated successfully.",
  "projectId": 1
}

Security

Encryption

Git tokens are encrypted at rest using AES-256 encryption:

  1. A 32-character encryption key must be configured
  2. Each token is encrypted with a unique IV (Initialization Vector)
  3. Both the encrypted token and IV are stored in the database
  4. Tokens are decrypted only when needed for git operations

Configuration

Set the encryption key in your configuration:

Development (User Secrets - Recommended):

dotnet user-secrets set "Encryption:Key" "your-32-character-encryption-key!"

Production (Environment Variable):

export Encryption__Key="your-32-character-encryption-key!"

⚠️ Important: The key must be exactly 32 characters (256 bits) for AES-256 encryption.

⚠️ Never commit encryption keys to source control!

Using Git Credentials in Code

To use the decrypted git token for operations like cloning:

public class MyGitService
{
    private readonly IGitCredentialService _credentials;
 
    public MyGitService(IGitCredentialService credentials)
    {
        _credentials = credentials;
    }
 
    public async Task CloneRepositoryAsync(int projectId, CancellationToken ct)
    {
        // Get the decrypted token
        var token = await _credentials.GetGitTokenAsync(projectId, ct);
        
        // Get configured repositories
        var repos = await _credentials.GetRepositoriesAsync(projectId, ct);
        
        // Get file exclusions
        var exclusions = await _credentials.GetFileExclusionsAsync(projectId, ct);
        
        // Use token with git operations...
    }
}

Database Schema

The ProjectConfigs table stores:

ColumnTypeDescription
IdintPrimary key
ProjectIdintForeign key to Projects (unique)
GitRepositoriesjsonbJSON array of repository URLs
FileExclusionsjsonbJSON array of exclusion patterns
EncryptedGitTokenstringBase64 encrypted token
EncryptionIVstringBase64 IV for decryption
CreatedAtDateTimeCreation timestamp
UpdatedAtDateTimeLast update timestamp

Migration

After adding this feature, run the migration:

dotnet ef database update --project MILTON --startup-project MILTON