Worker
The Worker kit is the hosted auth and Git API boundary for web clients. It owns OAuth redirects, secure credential storage, sessions, and REST access to repositories.
Service
Related
Cloudflare Worker Service
@git-pont/worker (kits/worker) is a deployable Cloudflare Worker that turns
@git-pont/core into a hosted service. It handles multi-platform authentication
server-side, persists connections so returning users do not reconnect, and
exposes a normalized REST API a web app can call.
The first consumer is gitKanban: a user logs in with GitHub OAuth, picks a repository, and the worker serves repository data. With a valid session cookie, a returning user is recognized without logging in again.
Relationship to the core kit: the worker consumes @git-pont/core. The
core kit (auth + proxy) is usable standalone; the worker adds the stateful
concerns (OAuth callback handling, sessions, persistence, per-user profile).
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /auth/github/start | Redirect the browser to GitHub's consent screen (sets a short-lived state cookie). |
| GET | /auth/github/callback | Exchange the code, persist/reuse the connection, create a session, redirect to the app. |
| GET | /session | Current session and connections. The returning-user check. |
| POST | /logout | Destroy the session and clear the cookie. |
| GET | /repositories | List repositories for the session's connection. |
| GET | /repos/:owner/:repo | Repository metadata (also records a recent repo). |
| GET | /repos/:owner/:repo/branches | List branches. |
| GET | /repos/:owner/:repo/contents/<path>?ref=branch | Directory listing or single file (UTF-8 text when decodable, plus base64). |
| GET | /me/profile | Per-user preferences (color mode, recent repos, app preferences). |
| PATCH | /me/profile | Shallow-merge preference updates. |
Sessions — cookie or bearer, one server-side record
On a successful OAuth callback the worker mints an opaque, unguessable session
id and stores it server-side (KV). The id is returned as a Secure; HttpOnly; SameSite=Lax cookie — the primary path for a web app calling with
credentials: "include". The same id may also be sent as
Authorization: Bearer <sessionId> for native or cross-origin callers. Both
resolve to the same session record; provider access and refresh tokens never
leave the worker in either path.
Session lifetime is configurable (SESSION_TTL_SECONDS, default 30 days). While
the cookie is valid, /session returns the connection without re-authenticating
— this is the "don't reconnect" behavior.
Storage — Cloudflare KV
Three KV namespaces, all keyed so a user only ever sees their own data:
SESSIONS—session:<id>→{ userId, connectionIds, expiresAt }.CONNECTIONS—conn:<userId>:<connId>(metadata, no secrets) andcred:<userId>:<connId>(credentials encrypted at rest with AES-GCM using theGITPONT_ENC_KEYsecret).PROFILES—profile:<userId>→ color mode, recent repos, app preferences.
The stores implement the core ConnectionStore / CredentialStore interfaces,
scoped per user, so the facade never observes cross-user data. KV was chosen for
simplicity; because storage sits behind interfaces, D1 (for relational queries)
or a Durable Object (for strictly serialized GitLab token refresh) can be
swapped in later without touching the facade.
Configuration
Vars (wrangler.toml): ALLOWED_ORIGINS, APP_LOGIN_REDIRECT,
OAUTH_REDIRECT_BASE, GITHUB_SCOPES, SESSION_TTL_SECONDS.
Secrets (wrangler secret put / .dev.vars): GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET, GITPONT_ENC_KEY (base64-encoded 32-byte key).
CORS is locked to ALLOWED_ORIGINS with credentials enabled.
gitKanban integration
- Send the user to
GET /auth/github/start(full-page navigation). - After consent GitHub returns to
/auth/github/callback; the worker sets the session cookie and redirects toAPP_LOGIN_REDIRECT. - Call the API with
credentials: "include". On load, callGET /session; ifauthenticatedis true, skip the login prompt. - Store UI preferences via
PATCH /me/profile.
Follow-ups
- GitLab / Forgejo-Gitea / Bitbucket login and proxying (GitLab's ~2h tokens introduce a Durable-Object serialized refresh).
- Write endpoints (
commit,pulls,submit) once the app needs writes. - An optional thin client SDK for calling the worker.
Security
git-pont handles repository credentials and can write to user repositories. Security rules should be strict from the first commit.
Secrets
Tokens must only live in a CredentialStore.
Do not store tokens in:
- app config JSON
GitConnectionGitRepositoryReference- remote URLs
- logs
- thrown error messages
- test snapshots
Logging
Logs may include:
- provider kind
- host
- repository namespace/name
- HTTP status code
- normalized error code
Logs must not include:
- access tokens
- refresh tokens
- authorization headers
- raw credential helper scripts containing token values
- full request bodies for write operations unless redacted
URL Safety
Reject repository paths containing:
..- absolute local filesystem paths
- empty path segments after normalization where a file path is required
- NUL or control characters
Commit Safety
Updating an existing file must include provider-specific version protection:
- GitHub:
sha - GitLab:
last_commit_id - Forgejo/Gitea: file SHA (required by the API)
If no expected version is available, updating or deleting an existing file requires the explicit caller option allowBlindOverwrite: Bool on GitFileChange / GitFileDeleteRequest. Default must be false; without it and without a version, throw .conflict rather than write.
Deleting a file must go through the explicit delete API. Committing empty content is never a delete.
Refresh Safety
Token refresh must be serialized per connection (GitLab rotates refresh tokens; a duplicate concurrent refresh invalidates the surviving token). The refreshed credential must be persisted to CredentialStore before dependent requests proceed. See Authentication → Token Refresh.
Browser Auth
OAuth flows should:
- use PKCE when supported
- use secure random state
- validate state on callback
- avoid client secrets in native apps unless there is a backend
- store refresh tokens only in
CredentialStore
Keychain
GitPontKeychain should:
- use generic password items
- use a service name configurable by the consuming app
- use stable account IDs such as
git-pont:{connectionID} - prefer
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnlyfor local app storage
Git CLI
GitPontGitCLI must avoid token leakage:
- tokens must be passed through environment variables
- token values must not appear in command arguments (variable names in the helper script are fine)
- set
GIT_TERMINAL_PROMPT=0 - do not mutate global git config
- do not write credential helpers to disk in v1
Network
The package should not disable TLS verification.
Self-hosted instances with invalid certificates are not supported in v1. If this is added later, it must be an explicit app-level trust decision.