airbytehq / airbytehq/airbyte-python-cdk

Declarative: GitHub App authentication (installation token with JWT)

Abierto
#837 0 comentarios 0 reacciones 1 asignado Reclamado por @aaronsteers Ver en GitHub
manifest-only feature gaps
Lenguaje dominante
Python
Estrellas
26
Forks
53
Merge medio
2 d 6 h
PR fusionados (30 d)
10

Descripción

## 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

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.