airbytehq / airbytehq/airbyte-python-cdk

Declarative: GitHub App authentication (installation token with JWT)

オープン
#837 コメント 0 件 リアクション 0 件 担当者 1 名 @aaronsteers が担当を希望しています GitHub で見る
manifest-only feature gaps
主要言語
Python
スター
26
フォーク
53
平均マージ
2日 6時間
マージ済み PR(30日)
10

説明

## Problem

GitHub Apps provide higher rate limits than Personal Access Tokens (PATs), but implementing GitHub App authentication requires custom Python code. This prevents connectors from being fully declarative (manifest-only).

## Rate Limit Comparison

- **PAT**: 5,000 requests/hour
- **OAuth App**: 5,000 requests/hour (15,000 if owned by Enterprise Cloud org)
- **GitHub App (non-Enterprise)**: 5,000-12,500 requests/hour (scales with repos/users)
- **GitHub App (Enterprise Cloud)**: 15,000 requests/hour (3x PAT limit)

## Current Workaround

Connectors like `source-github` only support PAT and OAuth authentication. See [`source-github/spec.json:16-65`](https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-github/source_github/spec.json#L16-L65) which only exposes OAuth and PAT options.

GitHub App authentication is not supported because it requires a two-step flow:
1. Sign a JWT using App ID + private key
2. Exchange JWT for installation access token via `POST /app/installations/{installation_id}/access_tokens`
3. Cache and refresh the installation token before ~1 hour expiry

## Proposed Solution

**Option 1**: Extend `SessionTokenAuthenticator` to support GitHub App flow
- Use `JwtAuthenticator` for the JWT signing step
- Configure `login_requester` to call the installation token endpoint with JWT header
- Set `expiration_duration` to ~1 hour for token caching

**Option 2**: Create dedicated `GitHubAppAuthenticator` component
- Accepts `app_id`, `installation_id`, and `private_key`
- Handles JWT signing and installation token exchange internally
- Automatically refreshes tokens before expiry

## Example Configuration (Option 1)

```yaml
authenticator:
type: SessionTokenAuthenticator
login_requester:
type: HttpRequester
url_base: "https://api.github.com"
path: "/app/installations/{{ config.installation_id }}/access_tokens"
http_method: "POST"
authenticator:
type: JwtAuthenticator
secret_key: "{{ config.private_key }}"
algorithm: "RS256"
token_duration: 600 # 10 minutes
jwt_payload:
iss: "{{ config.app_id }}"
iat: "{{ now_utc() }}"
exp: "{{ now_utc() + 600 }}"
session_token_path: ["token"]
expiration_duration: "PT1H" # 1 hour
request_authentication:
type: BearerAuthenticator
api_token: "{{ session_token }}"
```

## Example Configuration (Option 2)

```yaml
authenticator:
type: GitHubAppAuthenticator
app_id: "{{ config.app_id }}"
installation_id: "{{ config.installation_id }}"
private_key: "{{ config.private_key }}"
```

## Impact

This would enable connectors like `source-github`, `source-gitlab` (which also supports GitLab Apps), and others to leverage higher rate limits without custom Python code.

## Related

- airbytehq/airbyte-python-cdk#714 - Survey showing 74.3% of certified manifest-only connectors require custom components
- Requested by @aaronsteers in https://airbytehq-team.slack.com/archives/C08BHPUMEPJ/p1762665961303909
- GitHub Docs: [Rate limits for the REST API](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api)

## Code References

- [`source-github/spec.json:16-65`](https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-github/source_github/spec.json#L16-L65) - Current auth options (OAuth and PAT only)
- [`source-github/source.py:118-135`](https://github.com/airbytehq/airbyte/blob/master/airbyte-integrations/connectors/source-github/source_github/source.py#L118-L135) - `get_access_token()` implementation
- Declarative schema already has `JwtAuthenticator` and `SessionTokenAuthenticator` which could potentially be composed for this use case

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。