Expand description
§GitHub Bot SDK
A comprehensive Rust SDK for building GitHub Apps and bots with strong type safety, built-in security, and production-ready patterns.
§Features
- GitHub App Authentication - RS256 JWT signing and automated installation token management
- 🌐 API Client - Type-safe GitHub REST API operations with automatic rate limiting
- Webhook Security - HMAC-SHA256 signature validation with constant-time comparison
- Event Processing - Structured webhook event parsing and routing
- Production Ready - Exponential backoff, retry logic, and comprehensive error handling
- Rust First - Zero-cost abstractions leveraging Rust’s type system for correctness
§Quick Start
Add to your Cargo.toml:
[dependencies]
github-bot-sdk = "0.1.0"
tokio = { version = "1.0", features = ["full"] }§Core Concepts
§Authentication
GitHub Apps use a two-tier authentication model:
- App-level JWT - Short-lived tokens (max 10 minutes) for app-level operations
- Installation Tokens - Scoped tokens for operations on behalf of installations
This SDK handles both automatically through the AuthenticationProvider trait.
§API Client
The GitHubClient provides typed access to GitHub’s REST API with:
- Automatic token injection and refresh
- Built-in rate limit detection and handling
- Exponential backoff retry for transient failures
- Pagination support for list operations
§Webhook Processing
Validate and process GitHub webhooks securely:
- HMAC-SHA256 signature verification via
SignatureValidator - Structured event parsing with
eventsmodule - Type-safe event routing and handling
§Usage Examples
§Basic GitHub Client Usage
use github_bot_sdk::{
auth::{GitHubAppId, InstallationId, AuthenticationProvider},
client::{GitHubClient, ClientConfig},
error::ApiError,
};
// Build GitHub client with authentication
let client = GitHubClient::builder(auth_provider)
.config(ClientConfig::default()
.with_user_agent("my-bot/1.0")
.with_timeout(std::time::Duration::from_secs(30)))
.build()?;
// Get app information
let app = client.get_app().await?;
println!("Authenticated as: {}", app.name);
// Get installation information
let installation_id = InstallationId::new(12345);
let installation = client.get_installation(installation_id).await?;
println!("Installation ID: {}", installation.id.as_u64());§Repository Operations
let installation_id = InstallationId::new(12345);
let installation = client.get_installation(installation_id).await?;
// Get installation details
println!("Installation ID: {}", installation.id.as_u64());
println!("Account: {}", installation.account.login);§Issue and Pull Request Operations
let installation_id = InstallationId::new(12345);
// Get installation to work with issues and pull requests
let installation = client.get_installation(installation_id).await?;
println!("Working with installation: {}", installation.id.as_u64());
// See client module documentation for repository, issue, and PR operations§Webhook Signature Validation
use github_bot_sdk::{
webhook::SignatureValidator,
auth::SecretProvider,
error::ValidationError,
};
use std::sync::Arc;
let validator = SignatureValidator::new(secret_provider);
// Validate incoming webhook
let payload = b"{\"action\":\"opened\",\"issue\":{...}}";
let signature = "sha256=5c4a8d..."; // From X-Hub-Signature-256 header
if validator.validate(payload, signature).await? {
println!("✓ Valid webhook - processing event");
// Parse and process the event
} else {
println!("✗ Invalid signature - rejecting webhook");
}§Working with Tokens
use github_bot_sdk::auth::{JsonWebToken, GitHubAppId};
use chrono::{Utc, Duration};
let app_id = GitHubAppId::new(123456);
let expires_at = Utc::now() + Duration::minutes(10);
let jwt = JsonWebToken::new("eyJ0...".to_string(), app_id, expires_at);
// Check expiration
if jwt.is_expired() {
println!("Token has expired");
}
// Check if token expires soon (within 5 minutes)
if jwt.expires_soon(Duration::minutes(5)) {
println!("Token expires soon - should refresh");
}§Module Organization
auth- Authentication types, traits, and token managementclient- GitHub API client and operation implementationserror- Error types for all operationsevents- Webhook event parsing and processingwebhook- Webhook signature validation and security
§Architecture
This SDK follows hexagonal architecture principles:
- Core Domain - Authentication, events, and API operations (in this crate)
- Abstraction Layer - Traits for external dependencies (
SecretProvider,JwtSigner, etc.) - Infrastructure - Your implementations for secret management, key storage, etc.
This design ensures:
- Testability through dependency injection
- Flexibility to integrate with your infrastructure
- Type safety at compile time
- Clear separation of concerns
§Security
Security is built into the SDK’s design:
- No Token Logging - Sensitive types implement custom
Debugthat redacts secrets - Memory Safety - Token types zero memory on drop
- Constant-Time Comparison - Webhook signatures use timing-attack resistant comparison
- HTTPS Only - All GitHub API communication uses TLS
- Type Safety - Branded types prevent mixing up different ID types
§Error Handling
All operations return Result<T, E> with rich error types:
ApiError- GitHub API errors, rate limits, network failuresAuthError- Authentication and token errorsValidationError- Input validation and webhook signature errorsEventError- Event parsing and processing errors
Errors include context for debugging and implement retry classification to distinguish transient failures from permanent errors.
§Rate Limiting
The SDK automatically handles GitHub’s rate limits:
- Detects rate limit headers in responses
- Automatically backs off when approaching limits
- Respects
Retry-Afterheaders on 429 responses - Configurable safety margin to avoid hitting limits
§Testing
The SDK is designed for testability:
- Mock implementations for all traits
wiremockintegration for HTTP mocking- Comprehensive test coverage
- Doc tests for all examples
§Specifications
For detailed architectural specifications, see docs/specs/.
§Examples
See the repository examples for complete, runnable examples demonstrating common use cases.
Re-exports§
pub use error::ApiError;pub use error::AuthError;pub use error::CacheError;pub use error::EventError;pub use error::SecretError;pub use error::SigningError;pub use error::ValidationError;pub use auth::AuthenticationProvider;pub use auth::GitHubApiClient;pub use auth::GitHubAppId;pub use auth::Installation;pub use auth::InstallationId;pub use auth::InstallationPermissions;pub use auth::InstallationToken;pub use auth::JsonWebToken;pub use auth::JwtClaims;pub use auth::JwtSigner;pub use auth::KeyAlgorithm;pub use auth::Permission;pub use auth::PermissionLevel;pub use auth::PrivateKey;pub use auth::RateLimitInfo;pub use auth::Repository;pub use auth::RepositoryId;pub use auth::RepositorySelection;pub use auth::SecretProvider;pub use auth::TokenCache;pub use auth::User;pub use auth::UserId;pub use auth::UserType;pub use client::ClientConfig;pub use client::ClientConfigBuilder;pub use client::GitHubClient;pub use client::GitHubClientBuilder;pub use webhook::SignatureValidator;