OAuth flow
Redirect the user to GitHub
Send the user to
GET /api/auth/github. The server immediately redirects to GitHub’s OAuth authorization page with the required scopes.GitHub redirects back with a code
After the user grants access, GitHub redirects to
/api/auth/github/callback with a code query parameter. This is handled automatically — you don’t need to call this endpoint yourself.Shipyard exchanges the code and upserts the user
The callback handler exchanges the
code for a GitHub access token, fetches the user’s profile (and email if the primary email is hidden), then creates or updates the user record. It issues a signed JWT and redirects to:Using the JWT token
Include the token in theAuthorization header on all protected API requests:
401 and you must restart the OAuth flow to get a fresh token.
WebSocket authentication
Real-time build logs are delivered over Socket.io, which uses a separate authentication path. Pass the JWT in theauth.token field when opening the connection:
GitHub OAuth scopes
Shipyard requests three scopes when redirecting to GitHub:| Scope | Purpose |
|---|---|
read:user | Fetch your username, avatar, and email |
repo | Clone private repositories and register webhooks via the GitHub API |
read:org | List your organization memberships and their repositories |
Authentication errors
| Scenario | Behavior |
|---|---|
Missing Authorization header | 401 Not Authenticated |
| Malformed or expired JWT | 401 Token expired or invalid |
| Invalid Socket.io token | Connection rejected with Authentication error |
The GitHub access token used to clone repos and call the GitHub API is stored server-side and refreshed each time you sign in. Your client application only ever sees the Shipyard JWT.