Skip to main content

Module auth

Module auth 

Source
Expand description

GitHub App authentication types and interfaces.

This module provides the authentication foundation for GitHub Apps, handling the complexities of GitHub’s two-tier authentication model with type safety and production-ready patterns.

§Overview

GitHub Apps use a two-tier authentication system:

  1. App-level JWT tokens - Short-lived (max 10 minutes) tokens for app-level operations
  2. Installation tokens - Scoped tokens for operations within specific installations

This module provides:

§Authentication Flow

┌─────────────────┐
│  GitHub App ID  │
│  + Private Key  │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│   JWT Token     │  ◄── Sign with RS256 (max 10 min expiry)
│ (App-level)     │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Installation   │  ◄── Exchange JWT for installation token
│     Token       │      (scoped to installation permissions)
└─────────────────┘

§Usage Examples

§Working with ID Types

ID types use the newtype pattern to prevent mixing up different identifier types:

use github_bot_sdk::auth::{GitHubAppId, InstallationId, RepositoryId};

// Create IDs - type-safe, cannot be confused
let app_id = GitHubAppId::new(123456);
let installation_id = InstallationId::new(789012);
let repo_id = RepositoryId::new(345678);

// Parse from strings
let app_id: GitHubAppId = "123456".parse().unwrap();
assert_eq!(app_id.as_u64(), 123456);

// Convert to strings for display
println!("App ID: {}", app_id);  // Prints: App ID: 123456

§Token Expiration Checking

Tokens automatically track expiration and provide methods to check validity:

use github_bot_sdk::auth::{JsonWebToken, GitHubAppId};
use chrono::{Utc, Duration};

let app_id = GitHubAppId::new(123);
let expires_at = Utc::now() + Duration::minutes(10);
let jwt = JsonWebToken::new("eyJhbGc...".to_string(), app_id, expires_at);

// Check if token is expired
if jwt.is_expired() {
    println!("Token has expired - need to generate new one");
}

// Check if token expires soon (within specified duration)
if jwt.expires_soon(Duration::minutes(5)) {
    println!("Token expires in less than 5 minutes - should refresh proactively");
}

§Implementing Authentication Provider

The AuthenticationProvider trait is the main interface for authentication:

use github_bot_sdk::auth::{
    AuthenticationProvider, GitHubAppId, InstallationId,
    JsonWebToken, InstallationToken, Installation, Repository
};
use github_bot_sdk::error::AuthError;
use async_trait::async_trait;

struct MyAuthProvider {
    // Your implementation fields
}

#[async_trait]
impl AuthenticationProvider for MyAuthProvider {
    async fn app_token(&self) -> Result<JsonWebToken, AuthError> {
        // Generate JWT for app-level operations
        // - Read private key from secure storage
        // - Sign JWT claims with RS256
        // - Set 10-minute expiration
    }

    async fn installation_token(
        &self,
        installation_id: InstallationId,
    ) -> Result<InstallationToken, AuthError> {
        // Get installation token
        // - Generate app JWT
        // - Exchange for installation token via GitHub API
        // - Cache token until near expiration
    }

    async fn refresh_installation_token(
        &self,
        installation_id: InstallationId,
    ) -> Result<InstallationToken, AuthError> {
        // Force refresh - bypass cache
    }

    async fn list_installations(&self) -> Result<Vec<Installation>, AuthError> {
        // List all installations for this app
    }

    async fn get_installation_repositories(
        &self,
        installation_id: InstallationId,
    ) -> Result<Vec<Repository>, AuthError> {
        // Get repositories accessible to installation
    }
}

§Working with Permissions

Installation tokens include permission information:

use github_bot_sdk::auth::{InstallationPermissions, PermissionLevel};

// Create permissions with struct fields (not HashMap)
let mut permissions = InstallationPermissions {
    issues: PermissionLevel::Write,
    pull_requests: PermissionLevel::Write,
    contents: PermissionLevel::Write,
    metadata: PermissionLevel::Read,
    checks: PermissionLevel::None,
    actions: PermissionLevel::None,
};

// Check permissions via fields
match permissions.contents {
    PermissionLevel::Read => println!("Read-only access to contents"),
    PermissionLevel::Write => println!("Read-write access to contents"),
    PermissionLevel::Admin => println!("Admin access to contents"),
    PermissionLevel::None => println!("No access to contents"),
}

§Secret Management

Implement SecretProvider to integrate with your secret management system:

use github_bot_sdk::auth::{SecretProvider, PrivateKey, GitHubAppId};
use github_bot_sdk::error::SecretError;
use chrono::Duration;
use async_trait::async_trait;

struct MySecretProvider {
    // Your secret storage integration
}

#[async_trait]
impl SecretProvider for MySecretProvider {
    async fn get_private_key(&self) -> Result<PrivateKey, SecretError> {
        // Retrieve private key from Azure Key Vault, AWS Secrets Manager,
        // environment variables, or your preferred secret store
    }

    async fn get_app_id(&self) -> Result<GitHubAppId, SecretError> {
        // Retrieve GitHub App ID
    }

    async fn get_webhook_secret(&self) -> Result<String, SecretError> {
        // Retrieve webhook secret for signature validation
    }

    fn cache_duration(&self) -> Duration {
        // How long to cache secrets (e.g., 1 hour)
        Duration::hours(1)
    }
}

§Security Considerations

This module implements several security best practices:

  • Memory Safety - Token types implement Drop to zero memory
  • No Logging - Debug implementations redact sensitive values
  • Type Safety - Branded types prevent ID confusion at compile time
  • Expiration Tracking - Automatic token expiration detection
  • Constant-Time Comparison - Used where timing attacks are a concern

§Error Handling

Authentication operations can fail for various reasons:

All errors include context for debugging and support retry classification.

§Architecture

This module follows the ports and adapters (hexagonal) architecture:

  • Domain Types - ID types, token types, permission models (in this module)
  • Port Interfaces - Traits for external dependencies (SecretProvider, TokenCache, etc.)
  • Adapters - Your implementations for specific infrastructure (Azure, AWS, etc.)

This design enables:

  • Testability through dependency injection
  • Flexibility to swap infrastructure components
  • Clear separation between domain logic and infrastructure

§See Also

Modules§

cache
Token caching implementation for GitHub App authentication.
jwt
JWT (JSON Web Token) generation for GitHub App authentication.
tokens
GitHub App token management and AuthProvider implementation.

Structs§

Account
Account information for installations.
GitHubAppId
GitHub App identifier assigned during app registration.
Installation
Installation information from GitHub API.
InstallationId
GitHub App installation identifier for specific accounts.
InstallationPermissions
Permissions granted to a GitHub App installation.
InstallationToken
Installation-scoped access token for GitHub API operations.
JsonWebToken
JWT token for GitHub App authentication.
JwtClaims
JWT claims structure for GitHub App authentication.
PrivateKey
Private key for JWT signing.
RateLimitInfo
Rate limit information from GitHub API.
Repository
Repository information from GitHub API.
RepositoryId
Repository identifier used by GitHub API.
User
User information from GitHub API.
UserId
User identifier used by GitHub API.

Enums§

KeyAlgorithm
Key algorithm for JWT signing.
Permission
Specific permissions that can be checked on tokens.
PermissionLevel
Permission level for GitHub resources.
RepositorySelection
Repository selection for an installation.
TargetType
Installation target type (where the app is installed).
UserType
User type classification.

Traits§

AuthenticationProvider
Main interface for GitHub App authentication operations.
GitHubApiClient
Interface for GitHub API client operations.
JwtSigner
Interface for JWT token generation and signing.
SecretProvider
Interface for retrieving GitHub App secrets from secure storage.
TokenCache
Interface for caching authentication tokens securely.