Git-Bug: Impersonating Authors During Bridge Push
Rationale
In discussions surrounding the use of Git-Bug as a conversion tool for bridged repositories, a specific challenge arises: the need to attribute actions to the user performing the conversion rather than the original authors. This is particularly relevant in scenarios where git-bug might otherwise prevent the export of issues due to missing author credentials. The current design of git-bug prioritizes strict attribution, ensuring that actions are correctly attributed to their original authors. While this is a commendable approach for maintaining accuracy and integrity, it can hinder the tool's utility in certain conversion workflows. The core issue lies in the fact that git-bug is designed to prevent one user from pretending that another user filed a bug when they did not. While this is generally a desirable behavior for maintaining the integrity of issue tracking, it introduces complications when using git-bug as a conversion tool for bridged repositories. Imagine a scenario where you're migrating issues from one platform to another using git-bug. If some of the original authors of those issues are no longer active or their credentials are not available, git-bug will refuse to export those issues, effectively halting the conversion process. This is because git-bug is designed to strictly adhere to the principle of attributing actions to their original authors. To address this, there is a need for a mechanism that allows users to bypass this strict attribution requirement when necessary, enabling them to push issues under their own identity instead of the original authors. This mechanism should be implemented in a way that is both transparent and opt-in, ensuring that users are fully aware of the implications of impersonating authors.
Consider the example of lazygl2srht, a tool used for converting repositories. In such tools, all tickets often appear as reported by the user running the tool. While this might seem like a deviation from strict attribution, it doesn't necessarily detract from the usefulness of the resulting issue tracker. The key is to provide users with the option to make this trade-off, allowing them to prioritize functionality over strict attribution when appropriate.
Overview
This plan proposes the introduction of a new --wilfully-impersonate-authors flag for all git bug bridge push commands. This option enables the pushing of bugs, comments, and other items under the identity of the current user, effectively replacing the requirement for the original author's credentials. By introducing this flag, we aim to provide users with the flexibility to convert repositories even when the original author information is incomplete or unavailable.
Current Architecture Analysis
Key Findings
- Strict Author Authentication: Each bridge implementation (GitHub, GitLab, JIRA) strictly requires original authors' API tokens for export operations.
- Authentication Flow:
getClientForIdentity()methods fail withErrMissingIdentityTokenwhen original author credentials are missing. - Export Process: Operations are skipped when original author tokens are unavailable rather than allowing substitution.
- Current User Resolution:
GetUserIdentity()provides the current user's identity from git config.
Current Export Flow
git bug bridge push [NAME]
↓
commands/bridge/bridge_push.runBridgePush()
↓
bridge.DefaultBridge() or bridge.LoadBridge()
↓
bridge.ExportAll()
↓
[specific-bridge].ExportAll()
↓
[specific-bridge].exportBug()
↓
getClientForIdentity(author.Id()) → fails if no token
Implementation Plan
Phase 1: CLI Interface Enhancement
File: commands/bridge/bridge_push.go
- Add
--wilfully-impersonate-authorsboolean flag to the Cobra command. - Pass this flag through the bridge export chain.
- Update
runBridgePush()to accept and forward the impersonation flag.
cmd.Flags().Bool("wilfully-impersonate-authors", false,
"Push all operations under current user's identity, replacing original authors")
Phase 2: Core Bridge Interface Updates
File: bridge/core/interfaces.go
- Extend
Exporterinterface with impersonation support:
type Exporter interface {
Init(ctx context.Context, repo *cache.RepoCache, conf Configuration) error
ExportAll(ctx context.Context, repo *cache.RepoCache, since time.Time) (<-chan ExportResult, error)
// New method for impersonated export
ExportAllWithImpersonation(ctx context.Context, repo *cache.RepoCache, since time.Time, impersonate bool) (<-chan ExportResult, error)
}
File: bridge/core/bridge.go
- Update
Bridge.ExportAll()to accept impersonation parameter. - Add new method
ExportAllWithImpersonation()that forwards the flag to exporters.
Phase 3: Bridge Implementation Updates
Files:
bridge/github/export.gobridge/gitlab/export.gobridge/jira/export.go
For each bridge implementation:
3.1 Add Impersonation State
type githubExporter struct {
// ... existing fields ...
impersonateAuthors bool
}
3.2 Update Client Resolution Logic
Modify getClientForIdentity() methods:
func (ge *githubExporter) getClientForIdentity(userId entity.Id) (*rateLimitHandlerClient, error) {
if ge.impersonateAuthors {
// Return current user's client instead of failing
return ge.getCurrentUserClient()
}
client, ok := ge.identityClient[userId]
if ok {
return client, nil
}
return nil, ErrMissingIdentityToken
}
3.3 Add Current User Client Resolution
func (ge *githubExporter) getCurrentUserClient() (*rateLimitHandlerClient, error) {
// Get current user identity
currentUserIdentity, err := ge.repo.GetUserIdentity()
if err != nil {
return nil, fmt.Errorf("failed to get current user identity: %w", err)
}
// Try to get current user's client
if client, ok := ge.identityClient[currentUserIdentity.Id()]; ok {
return client, nil
}
// Fallback to default client
if ge.defaultClient != nil {
return ge.defaultClient, nil
}
return nil, fmt.Errorf("no credentials available for current user")
}
3.4 Add New Export Method
func (ge *githubExporter) ExportAllWithImpersonation(ctx context.Context, repo *cache.RepoCache, since time.Time, impersonate bool) (<-chan core.ExportResult, error) {
ge.impersonateAuthors = impersonate
return ge.ExportAll(ctx, repo, since)
}
Phase 4: Metadata and Future Tainting Support
Current Metadata Structure
- Operations are marked with remote IDs using
markOperationAsExported() - Metadata keys:
github-id,github-url,gitlab-id, etc.
Future Enhancement Note
When database schema changes are possible, add tainted=true metadata to impersonated operations:
// Future implementation when schema changes are allowed
if ge.impersonateAuthors {
metadata["tainted"] = "true"
metadata["original-author"] = originalAuthor.Id().String()
}
This would allow git bug bridge pull to treat these as read-only and never overwrite originals.
Phase 5: Error Handling and Edge Cases
Credential Validation
- Verify current user has valid credentials for the target platform.
- Provide clear error messages when credentials are missing.
- Graceful degradation when impersonation is requested but not possible.
Backward Compatibility
- Maintain existing behavior when flag is not used.
- Ensure all existing tests continue to pass.
- Preserve current authentication flow as default.
Implementation Sequence
- CLI flag addition in
bridge_push.go - Core interface updates in
interfaces.goandbridge.go - GitHub bridge implementation (as reference implementation)
- GitLab bridge implementation
- JIRA bridge implementation
- Testing and validation
Key Technical Challenges
1. Client Resolution
- Ensuring current user has valid credentials for the target platform
- Handling cases where current user has no platform-specific credentials
- Fallback strategies for different authentication scenarios
2. Error Handling
- Graceful degradation when impersonation is requested but current user lacks credentials
- Clear error messages for users about missing credentials
- Maintaining operation integrity during partial failures
3. Metadata Consistency
- Maintaining existing metadata structure while enabling impersonation
- Preserving original author information in local storage
- Ensuring remote platform audit trails remain accurate
4. Backward Compatibility
- Ensuring existing functionality unchanged when flag is not used
- Maintaining current security model as default behavior
- Preserving existing API contracts
Security Considerations
1. Intentional Obfuscation
- The
--wilfully-impersonate-authorsflag name makes the implications clear - Users must explicitly opt into this behavior
- Flag name serves as a warning about the implications
2. Audit Trail Integrity
- Remote platforms will still show the current user as the author
- Platform-level audit integrity is maintained
- Local git-bug storage preserves original author information
3. Local Traceability
- Original author information is preserved in git-bug's local storage
- Operations can be traced back to original authors locally
- Future "tainting" mechanism will provide additional safeguards
Testing Strategy
1. Unit Tests
- Client resolution with impersonation enabled/disabled
- Current user identity resolution
- Error handling for missing credentials
2. Integration Tests
- End-to-end bridge export with impersonation
- Mixed author scenarios (some with credentials, some without)
- Platform-specific behavior validation
3. Edge Case Testing
- Missing current user credentials
- Invalid current user identity
- Bridge configuration issues
4. Backward Compatibility Tests
- Ensure existing functionality unchanged
- Verify default behavior preserved
- Validate existing test suite continues to pass
Files to be Modified
Core Files
commands/bridge/bridge_push.go- CLI flag and command handlingbridge/core/interfaces.go- Exporter interface extensionbridge/core/bridge.go- Bridge orchestration updates
Bridge Implementation Files
bridge/github/export.go- GitHub bridge impersonation supportbridge/gitlab/export.go- GitLab bridge impersonation supportbridge/jira/export.go- JIRA bridge impersonation support
Test Files
- Various test files across bridge implementations
- Integration test updates for new functionality
Documentation Updates
1. Manual Pages
- Update
git-bug-bridge-push.1man page - Document the new flag and its implications
2. User Documentation
- Update bridge usage documentation
- Add examples and use cases
- Document security implications
3. Developer Documentation
- Update bridge development guide
- Document impersonation architecture
- Provide implementation examples
Rollout Plan
Phase 1: Core Implementation
- Implement basic functionality
- Add comprehensive test coverage
- Ensure backward compatibility
Phase 2: Documentation
- Update all documentation
- Add usage examples
- Document security considerations
Phase 3: Release
- Include in next release
- Monitor for issues
- Gather user feedback
Future Enhancements
1. Tainting Mechanism
When database schema changes are possible:
- Add
tainted=truemetadata to impersonated operations - Implement read-only handling in
git bug bridge pull - Provide visual indicators in UI components
2. Selective Impersonation
- Allow impersonation of specific operations only
- Provide fine-grained control over which operations to impersonate
- Add configuration options for default behavior
3. Audit Logging
- Enhanced logging for impersonated operations
- Audit trail for compliance requirements
- Integration with external audit systems
Conclusion
This plan provides a comprehensive approach to implementing author impersonation while maintaining the integrity and security of the existing bridge system. The intentionally obnoxious flag name serves as a clear warning about the implications of this functionality.
The implementation prioritizes:
- Security: Maintaining audit trail integrity
- Compatibility: Preserving existing behavior
- Clarity: Making implications obvious through naming
- Flexibility: Supporting future enhancements like tainting
The modular approach allows for incremental implementation and testing while minimizing risk to existing functionality.
For more information on Git internals and concepts, visit the Git documentation.