Effect primitives: - git-provider: GitProvider, connection states, normalized errors, URL normalization, host compatibility, credential freshness window - git-provisioning: validated Puter commands, migration states, idempotency keys, safe replacement rules, owner-safe guards - git-webhook: supported events, signature verification, delivery states - host-repository: provider-neutral credential-safe clone via GIT_ASKPASS Normalized Convex schema: - gitProviderAccounts, refined gitConnections, gitProviderOrganizations, gitRepositories, gitMigrations, gitWebhookDeliveries - projects: gitRepositoryId + instructions fields - Schema fields optional for backward compatibility, with backfill cron Backend: - Connection health: verify action, hourly reconciliation (covers stale active + reauth-required + undefined-state legacy connections) - Puter provisioning: createPuterUser/Organization/Repository with owner binding, startGithubMigration (durable via scheduler), getMigration - Org ownership: explicit member add with admin role + verification - Webhook HTTP actions: HMAC verification, delivery persistence with idempotency, repository resolution, byte-length payload limit - Automatic Puter webhook creation after repo creation/migration with fail-loud state tracking - Repository sync after connection (Gitea + GitHub) - AgentOS execution resolves gitRepositoryId for real clone URL - Credential gating: state + freshness checks before execution and project creation - listForOrganization for cross-project Work filtering Frontend: - /projects onboarding page with GitHub OAuth (linkSocial) and Puter PAT - Zero-project redirect, repository selection, context editor - Provider-aware settings panel (no serverUrl for Puter) - Project selection via ?project= query param - GitHub scopes: repo + read:org Agent runtime: - Clones user repository with GIT_ASKPASS credential helper (no token in URL, args, or git config), provider-aware username - Removed fixed Zopu source path and .env copy
129 lines
4.5 KiB
Markdown
129 lines
4.5 KiB
Markdown
# Git Provider Setup
|
|
|
|
This document covers manual setup for GitHub OAuth, Puter Git (Gitea), webhooks, and Convex environment variables.
|
|
|
|
> **Never place admin or user tokens in checked-in `.env` files or browser variables.** All secrets must be Convex environment variables set via `npx convex env set`.
|
|
|
|
## GitHub OAuth Application
|
|
|
|
1. Go to GitHub Settings > Developer settings > OAuth Apps > New OAuth App.
|
|
2. Set the application name (e.g., "Zopu").
|
|
3. Set the homepage URL to your `SITE_URL` (e.g., `https://zopu.cheaptricks.puter.wtf`).
|
|
4. Set the callback URL to `<SITE_URL>/api/auth/callback/github`.
|
|
5. Generate a client secret.
|
|
6. Set Convex environment variables:
|
|
```
|
|
npx convex env set GITHUB_CLIENT_ID <your-client-id>
|
|
npx convex env set GITHUB_CLIENT_SECRET <your-client-secret>
|
|
```
|
|
|
|
### Requested scopes
|
|
|
|
Zopu requests `repo` and `read:org`. The `repo` scope grants access to private repositories. `read:org` allows listing organization repositories.
|
|
|
|
## GitHub Webhook (manual setup for OAuth-based version)
|
|
|
|
1. Go to the GitHub repository Settings > Webhooks > Add webhook.
|
|
2. Payload URL: `<CONVEX_SITE_URL>/api/git/webhooks/github`
|
|
3. Content type: `application/json`
|
|
4. Secret: generate a strong random string and set it as:
|
|
```
|
|
npx convex env set GITHUB_WEBHOOK_SECRET <your-webhook-secret>
|
|
```
|
|
5. Select individual events:
|
|
- Push
|
|
- Repository (created, deleted, transferred, renamed, visibility)
|
|
- Delete
|
|
- Create
|
|
- Public
|
|
- Fork
|
|
6. Do not select "Send me everything."
|
|
|
|
## Puter Git (Gitea) Admin Token
|
|
|
|
1. As a Gitea admin, go to Settings > Applications > Generate New Token.
|
|
2. Select scopes: `write:admin`, `write:organization`, `write:repository`.
|
|
3. Set the token:
|
|
```
|
|
npx convex env set PUTER_GIT_ADMIN_TOKEN <your-admin-token>
|
|
```
|
|
|
|
This token is used only for platform administration (user creation, organization creation, repository creation, migration). It is never used for end-user operations.
|
|
|
|
## Puter Git Webhook
|
|
|
|
After a repository is created or migrated, Zopu ensures a webhook is configured automatically. If manual setup is needed:
|
|
|
|
1. Go to the Gitea repository Settings > Webhooks > Add Webhook > Gitea.
|
|
2. Target URL: `<CONVEX_SITE_URL>/api/git/webhooks/puter`
|
|
3. HTTP method: POST
|
|
4. Content-Type: `application/json`
|
|
5. Secret: generate a strong random string and set it as:
|
|
```
|
|
npx convex env set GITEA_WEBHOOK_SECRET <your-webhook-secret>
|
|
```
|
|
6. Trigger on: Push events, Repository events.
|
|
|
|
## Credential Encryption Key
|
|
|
|
Generate a 32-byte encryption key for AES-GCM credential encryption:
|
|
|
|
```bash
|
|
openssl rand -base64 32 | base64 | tr -d '\n' | pbcopy
|
|
```
|
|
|
|
Set it as:
|
|
|
|
```
|
|
npx convex env set GIT_CREDENTIAL_ENCRYPTION_KEY <base64url-encoded-32-bytes>
|
|
```
|
|
|
|
The key must be exactly 32 bytes when base64url-decoded.
|
|
|
|
## Same-Origin Proxy for Better Auth Callbacks
|
|
|
|
Better Auth requires the callback URL to be on the same origin as `SITE_URL`. If your Convex deployment uses a different origin:
|
|
|
|
1. Configure a reverse proxy (e.g., Caddy) to forward `/api/auth/*` to the Convex deployment.
|
|
2. Set `SITE_URL` to the proxy origin.
|
|
3. Set `CONVEX_SITE_URL` to the Convex deployment URL.
|
|
|
|
## Validation Procedures
|
|
|
|
### Verify a Puter PAT connection
|
|
|
|
1. Connect a Puter PAT through the UI.
|
|
2. Verify the connection state shows `active`.
|
|
3. List private repositories to confirm token validity.
|
|
|
|
### Verify GitHub OAuth
|
|
|
|
1. Click "Connect GitHub" in the UI.
|
|
2. Complete the GitHub OAuth flow.
|
|
3. Verify the connection state shows `active`.
|
|
|
|
### Reconnection
|
|
|
|
If a token is expired or revoked:
|
|
|
|
1. The connection state shows `reauth-required`.
|
|
2. Reconnect the provider through the UI.
|
|
3. The old connection state is updated to `active`.
|
|
4. Projects, repositories, Work, and artifacts are not deleted.
|
|
|
|
## Environment Variables Summary
|
|
|
|
| Variable | Required | Description |
|
|
| --- | --- | --- |
|
|
| `SITE_URL` | Yes | Public-facing URL |
|
|
| `CONVEX_SITE_URL` | Yes | Convex deployment URL (may differ from SITE_URL with proxy) |
|
|
| `GIT_CREDENTIAL_ENCRYPTION_KEY` | Yes | Base64url-encoded 32-byte AES-GCM key |
|
|
| `PUTER_GIT_ADMIN_TOKEN` | Yes | Gitea admin token for provisioning |
|
|
| `GITHUB_CLIENT_ID` | For GitHub | OAuth app client ID |
|
|
| `GITHUB_CLIENT_SECRET` | For GitHub | OAuth app client secret |
|
|
| `GITHUB_WEBHOOK_SECRET` | For GitHub webhooks | HMAC verification secret |
|
|
| `GITEA_WEBHOOK_SECRET` | For Puter webhooks | HMAC verification secret |
|
|
| `FLUE_DB_TOKEN` | Yes | Private agent backend token |
|
|
| `FLUE_URL` | Optional | Private agent backend URL |
|
|
| `NATIVE_APP_URL` | Optional | Native app deep-link scheme |
|