- Updated: March 22, 2026
- 8 min read
Integrating GitHub OAuth into the OpenClaw Full‑Stack Template
Integrating GitHub OAuth into the OpenClaw Full‑Stack Template enables secure, single‑sign‑on authentication for your web application, allowing developers to leverage GitHub’s trusted identity platform with minimal code.
Introduction
Modern SaaS products and developer tools expect frictionless login experiences. GitHub OAuth is a proven solution that provides developers with a reliable, scalable authentication mechanism while keeping user data safe. In this tutorial we walk you through the complete process of adding GitHub OAuth to the OpenClaw Full‑Stack Template, from setting up the template to deploying a production‑ready version.
Whether you are a solo founder, a technical co‑founder, or a full‑stack engineer, this step‑by‑step guide will give you a working authentication flow in under an hour.
Brief History of OpenClaw (Clawd.bot → Moltbot → OpenClaw)
OpenClaw didn’t appear overnight. Its lineage traces back to Clawd.bot, a simple Discord bot built in 2019 to automate community moderation. As the team’s ambitions grew, the bot evolved into Moltbot, a multi‑platform assistant that added AI‑driven responses and a low‑code workflow engine.
By early 2023, the developers recognized a market need for a full‑stack, AI‑ready starter kit. They rewrote the codebase, introduced a modular architecture, and rebranded the project as OpenClaw. Today, OpenClaw is a production‑grade template that ships with a web app editor, workflow automation studio, and out‑of‑the‑box integrations for AI services like ChatGPT, ElevenLabs, and Chroma DB.
Understanding this evolution helps you appreciate why OpenClaw is built for extensibility—adding a new OAuth provider is as simple as dropping a configuration file and wiring a few routes.
Prerequisites
- Node.js ≥ 18.x and npm ≥ 9.x installed locally.
- A GitHub account with permission to create OAuth Apps.
- Basic familiarity with Express.js and React (the stack used by OpenClaw).
- Access to a terminal/command prompt and a code editor (VS Code recommended).
- Optional but recommended: a free OpenClaw hosting environment for quick testing.
Setting up the OpenClaw Full‑Stack Template
First, clone the official repository and install dependencies:
git clone https://github.com/ubos-tech/openclaw-fullstack-template.git
cd openclaw-fullstack-template
npm ciThe template ships with two primary folders:
server/– Express.js API, authentication middleware, and database adapters.client/– React front‑end built with Vite, pre‑configured for Tailwind CSS.
Run the development environment to verify the baseline works:
# In one terminal
npm run dev:server
# In another terminal
npm run dev:client
Open http://localhost:3000 in your browser. You should see the default OpenClaw landing page with a “Login” button that currently redirects to a placeholder route.
Creating a GitHub OAuth App
Follow these steps on GitHub:
- Navigate to GitHub Developer Settings.
- Click New OAuth App.
- Fill in the form:
- Application name: OpenClaw Demo
- Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/api/auth/github/callback
- Submit the form. GitHub will generate a Client ID and Client Secret. Keep the secret safe; you’ll need it in the next step.
For production, replace the localhost URLs with your domain (e.g., https://app.yourdomain.com and https://app.yourdomain.com/api/auth/github/callback).
Configuring GitHub OAuth in OpenClaw
OpenClaw uses dotenv for environment variables. Create a .env file in the server/ directory (if it doesn’t exist) and add the following entries:
# .env (server side)
GITHUB_CLIENT_ID=YOUR_CLIENT_ID_HERE
GITHUB_CLIENT_SECRET=YOUR_CLIENT_SECRET_HERE
SESSION_SECRET=super_secret_session_key
BASE_URL=http://localhost:3000
Next, install the passport-github2 strategy, which OpenClaw already lists as an optional dependency:
npm install passport-github2Update the authentication middleware
Open server/src/auth/passport.js (create it if missing) and add the following configuration:
const passport = require('passport');
const GitHubStrategy = require('passport-github2').Strategy;
const User = require('../models/User'); // Adjust path to your User model
passport.use(
new GitHubStrategy(
{
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL: `${process.env.BASE_URL}/api/auth/github/callback`,
},
async (accessToken, refreshToken, profile, done) => {
try {
// Find or create a user record based on GitHub ID
let user = await User.findOne({ githubId: profile.id });
if (!user) {
user = await User.create({
githubId: profile.id,
username: profile.username,
avatarUrl: profile._json.avatar_url,
email: profile.emails?.[0]?.value || null,
});
}
return done(null, user);
} catch (err) {
return done(err, null);
}
}
)
);
// Serialize user into session
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findById(id);
done(null, user);
} catch (err) {
done(err, null);
}
});
module.exports = passport;
Then, wire the routes in server/src/routes/auth.js:
const express = require('express');
const router = express.Router();
const passport = require('../auth/passport');
// Initiate GitHub login
router.get('/github', passport.authenticate('github', { scope: ['user:email'] }));
// GitHub callback
router.get(
'/github/callback',
passport.authenticate('github', { failureRedirect: '/' }),
(req, res) => {
// Successful authentication, redirect to dashboard
res.redirect('/dashboard');
}
);
// Logout endpoint
router.get('/logout', (req, res) => {
req.logout(() => {
res.redirect('/');
});
});
module.exports = router;
Finally, register the auth router in server/src/index.js (or wherever the Express app is created):
const express = require('express');
const session = require('express-session');
const passport = require('./auth/passport');
const authRoutes = require('./routes/auth');
const app = express();
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
})
);
app.use(passport.initialize());
app.use(passport.session());
// Body parsers
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Auth routes
app.use('/api/auth', authRoutes);
// ... other routes and error handling ...
module.exports = app;Update the front‑end login button
In client/src/components/NavBar.jsx replace the placeholder link with the GitHub endpoint:
<button
className="bg-gray-800 text-white px-4 py-2 rounded hover:bg-gray-700"
onClick={() => window.location.href = '/api/auth/github'}
>
Sign in with GitHub
</button>The client now redirects users to the server‑side OAuth flow.
Testing the Integration
1. Start both servers (if not already running):
npm run dev:server
npm run dev:client
2. Open http://localhost:3000 and click Sign in with GitHub. You’ll be redirected to GitHub’s consent screen.
3. After authorizing, GitHub redirects back to /api/auth/github/callback. If everything is configured correctly, you’ll land on /dashboard and see your GitHub avatar and username displayed.
4. Verify session persistence by refreshing the page; the user should remain logged in. Open the browser’s dev tools → Application → Cookies to see the session cookie.
Common pitfalls
- Callback URL mismatch: Ensure the URL in GitHub matches the
BASE_URLenvironment variable. - Missing session secret: Without
SESSION_SECRET, Express cannot sign cookies. - Scope issues: If you need the user’s email, include
scope: ['user:email']as shown above.
Deploying to Production
When you’re ready to go live, follow these steps:
- Update environment variables with your production domain (e.g.,
BASE_URL=https://app.yourdomain.com) and the new GitHub OAuth callback URL. - Build the client for production:
cd client npm run build - Serve static assets from the Express server (add to
server/src/index.js):app.use(express.static(path.join(__dirname, '../../client/dist'))); app.get('*', (req, res) => { res.sendFile(path.resolve(__dirname, '../../client/dist/index.html')); }); - Choose a hosting provider. UBOS offers a managed environment that can host the full‑stack template with a single click. Follow the OpenClaw hosting guide to spin up a production instance.
- Configure HTTPS (most providers auto‑provision Let’s Encrypt certificates). Ensure your
BASE_URLuseshttps://. - Monitor logs for authentication errors. The server logs any OAuth failures with stack traces that help you debug quickly.
After deployment, test the flow again using the live URL. The experience should be identical to the local development version, but now secured with TLS and ready for real users.
Conclusion and Next Steps
You have successfully integrated GitHub OAuth into the OpenClaw Full‑Stack Template, giving your application a robust authentication layer that scales from a single developer to enterprise teams. This foundation opens the door to many advanced scenarios:
- Role‑based access control (RBAC) – map GitHub organization membership to internal permissions.
- Multi‑provider login – add Google, Microsoft, or custom SSO alongside GitHub.
- Audit logging – store login events in the OpenClaw database for compliance.
- AI‑driven personalization – use the user’s GitHub profile to tailor AI marketing agents from the AI marketing agents suite.
The OpenClaw ecosystem continues to evolve, and its modular architecture ensures that adding new features never becomes a roadblock. Keep an eye on the official UBOS platform overview for upcoming integrations, and consider joining the UBOS partner program if you plan to build and sell extensions.
Happy coding, and enjoy the power of secure, GitHub‑backed authentication in your OpenClaw projects!
Andrii Bidochko
CTO UBOS
Andrii Bidochko is an AI entrepreneur and researcher focused on AI agents, reinforcement learning, and autonomous systems. He writes about the technologies shaping the future of machine intelligence, from frontier models and agent architectures to real-world AI applications.