GitHub OAuth Setup for FDS Agent

This guide explains how to set up GitHub OAuth authentication for FDS Agent to enable automatic deployment of builds to GitHub repositories.

Overview

The FDS Agent now supports GitHub OAuth authentication, allowing users to:

  1. Authorize the agent to access their GitHub repositories
  2. Select a specific repository for deployment
  3. Generate a JWT token for secure API access
  4. Use the token to automatically deploy builds to GitHub

Setup Instructions

1. Create a GitHub OAuth App

  1. Go to GitHub Settings > Developer settings > OAuth Apps: https://github.com/settings/developers
  2. Click "New OAuth App"
  3. Fill in the application details:
    • Application name: FDS Agent (or your preferred name)
    • Homepage URL: Your FDS Agent URL (e.g., https://your-domain.com)
    • Authorization callback URL: https://your-domain.com/auth/github/callback
    • Application description: (Optional) Frontend Deployment Service
  4. Click "Register application"
  5. On the next page, note down the Client ID
  6. Click "Generate a new client secret" and note down the Client Secret

Important: Keep your Client Secret secure and never commit it to version control.

2. Configure Environment Variables

Set the following environment variables in your FDS Agent deployment:

# Required
GITHUB_APP_CLIENT_ID=your_client_id_here
GITHUB_APP_CLIENT_SECRET=your_client_secret_here

# Optional
JWT_SECRET=your_random_secret_for_jwt_signing  # Defaults to "change-me-in-production"
BASE_URL=https://your-domain.com              # Defaults to http://localhost:4000

For Docker/Kubernetes Deployment:

Update your deployment YAML file (e.g., staging.yml, production.yml):

env:
  - name: GITHUB_APP_CLIENT_ID
    value: 'your_client_id'
  - name: GITHUB_APP_CLIENT_SECRET
    valueFrom:
      secretKeyRef:
        name: github-oauth-secret
        key: client_secret
  - name: JWT_SECRET
    valueFrom:
      secretKeyRef:
        name: jwt-secret
        key: secret
  - name: BASE_URL
    value: 'https://your-domain.com'

Create Kubernetes secrets:

kubectl create secret generic github-oauth-secret \
  --from-literal=client_secret='your_client_secret' \
  -n your-namespace

kubectl create secret generic jwt-secret \
  --from-literal=secret='your_random_jwt_secret' \
  -n your-namespace

3. Install Dependencies

cd /path/to/fds-agent
npm install

This will install the new jsonwebtoken dependency.

4. Restart the Agent

# If running locally
node agent.js

# If using Docker
docker-compose restart fds-agent

# If using Kubernetes
kubectl rollout restart deployment/base-layouts-production -n your-namespace

User Flow

For End Users:

  1. Navigate to the Auth Page:

    • Go to https://your-fds-agent-url/auth/index.html
  2. Authorize with GitHub:

    • Click "Sign in with GitHub"
    • Authorize the application on GitHub
    • You'll be redirected back to the success page
  3. Generate JWT Token:

    • Choose an owner (personal account or organization)
    • Select an existing repository or create a new one under that owner
    • Branch uses the repository's default branch automatically
    • Specify the deployment path (defaults to "dist")
    • Click "Generate JWT Token"
  4. Use the Token:

    • Copy the generated JWT token
    • Use it in your /process API calls:
POST /process
{
  "projectName": "my-project",
  "target": "www",
  "githubJwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "recipe": { ... }
}

branch, license, and gqlSchemaMinVersion are filled by the agent automatically (branch from build-info, license always FREE).

API Endpoints

Authentication Flow

1. Start OAuth Flow

GET /auth/github/start

Response:

{
  "redirectUrl": "https://github.com/login/oauth/authorize?client_id=...",
  "state": "random_state_token"
}

2. OAuth Callback (handled automatically)

GET /auth/github/callback?code=xxx&state=xxx

Redirects to /auth/success.html?session=xxx

3. Get Session Data

GET /auth/session/:sessionId

Response:

{
  "user": {
    "login": "username",
    "id": 12345,
    "name": "User Name"
  },
  "orgs": [
    { "login": "org-name", "id": 67890 }
  ],
  "repos": [
    {
      "full_name": "username/repo",
      "default_branch": "main",
      "permissions": { "admin": true, "push": true },
      "owner": { "login": "username", "type": "User" }
    }
  ]
}

4. Create Repository (optional)

POST /auth/create-repo
Content-Type: application/json

{
  "sessionToken": "session_token_from_callback",
  "owner": "org-or-user-login",
  "name": "new-repo-name",
  "private": false
}

Response:

{
  "repo": {
    "full_name": "org-or-user-login/new-repo-name",
    "default_branch": "main",
    "owner": { "login": "org-or-user-login", "type": "Organization" },
    "permissions": { "admin": true, "push": true },
    "private": false
  },
  "sessionToken": "updated_session_token_with_new_repo"
}

5. Generate JWT Token

POST /auth/generate-jwt
Content-Type: application/json

{
  "sessionToken": "session_token_from_callback",
  "repo": "username/repository",
  "branch": "main",
  "path": "dist"
}

Response:

{
  "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "payload": {
    "repo": "username/repository",
    "branch": "main",
    "path": "dist",
    "user": "username",
    "iat": 1234567890
  },
  "note": "Use this JWT in the 'githubJwt' field when calling /process endpoint. The GitHub OAuth access token is encrypted inside the JWT data field."
}

Security Considerations

  1. JWT Secret: Always use a strong, random JWT secret in production. Generate one using:

    openssl rand -base64 32
    
  2. HTTPS: Always use HTTPS in production to protect OAuth tokens in transit.

  3. Session Storage: Session details (including the GitHub OAuth access token) are encrypted into the JWT; the server does not persist session data in memory.

  4. Token Expiration: JWT tokens expire after 30 days by default. Users will need to regenerate tokens after expiration.

  5. Permissions: The OAuth flow requests the repo and workflow scopes. The repo scope gives full repository access, and the workflow scope allows creating/updating GitHub Actions workflow files. Users should only authorize repositories they want the agent to access.

Troubleshooting

Error: "GitHub App not configured"

Error: "Session not found or expired"

Error: "You don't have access to this repository"

OAuth Callback URL Mismatch

Testing

Local Testing

  1. For local testing, use a tool like ngrok to expose your local server:

    ngrok http 4000
    
  2. Use the ngrok URL in your GitHub OAuth App settings:

    • Homepage URL: https://your-ngrok-url.ngrok.io
    • Callback URL: https://your-ngrok-url.ngrok.io/auth/github/callback
  3. Set environment variables:

    export GITHUB_APP_CLIENT_ID=your_client_id
    export GITHUB_APP_CLIENT_SECRET=your_client_secret
    export BASE_URL=https://your-ngrok-url.ngrok.io
    node agent.js
    
  4. Navigate to https://your-ngrok-url.ngrok.io/auth/index.html

Migration from Manual Token Configuration

Environment GitHub tokens are no longer used for publishing. OAuth-issued access tokens are now encrypted inside the generated JWT and are required for git push operations. Ensure users complete the OAuth flow and use the generated JWT from /auth/generate-jwt in /process calls.

Support

For issues or questions: