With HelpKit’s Professional Plan, you can restrict access to your documentation using your own authentication backend. This guide shows how to implement custom authentication using a Node.js example — but it applies to any backend framework.
🧠 Overview
To protect access to your HelpKit site:
- Show users a login screen
- Authenticate the user on your backend
- Generate a signed JWT token
- Redirect the user to your HelpKit site with the
jwt_token
in the URL
🔧 Configuring Custom Backend Auth in the HelpKit Dashboard
To protect your HelpKit knowledge base using your own custom login system, follow these steps inside your HelpKit project dashboard.
1. Go to the “Protected Access” Tab
- Navigate to Settings → Protected Access
- You’ll see various access options like:
- Public
- Password
- Notion Email List
- Custom Backend ← (Select this one!)
- LemonSqueezy
👉 Select: Custom Backend

2. Enter Your Login URL
This is the URL where you handle user authentication in your backend (e.g. the /login page you’ve built). HelpKit will show a button that will redirect to your login page via this link.
Example: http://custom.enterprise.com/login

💡 This should be a fully working URL that renders your login form and handles auth logic.

3. Generate and Copy Your Secret Key
Click the “Generate” button under the Secret Key section.
- Copy this key and add it to your .env file in your backend project as:
HELPKIT_VISITOR_SECRET_KEY=your_generated_secret_key
🛡️ This key is used by your backend to sign JWTs after successful login.
4. (Optional) Auto Redirect Users
Check the “Automatically open login URL” option if you want users to be instantly redirected to your login page instead of seeing the “Sign in” screen with a button.
✅ If enabled:
User visits a protected HelpKit article → auto-redirects to your custom login screen.
🚫 If not enabled, they’ll see a screen saying:
“You are trying to access HelpKit internal knowledge base”
5. Save & Test
- Your HelpKit site is now gated.
- Visit your site (or open an incognito tab) to test.
- After login, your backend should:
- Authenticate the user
- Sign a JWT
- Redirect them to
https://your-helpkit-site.com
/access?jwt_token=...

Done correctly, after having entered the correct user credentials they’ll now have full access to your knowledge base.

🛠️ Step-by-Step Implementation (Node.js Example)
You can use any backend. Here’s how to do it in Node.js using Express:
1. Environment Variables .env
Configuration
HELPKIT_VISITOR_SECRET_KEY=your_visitor_signing_key_here HELPKIT_SITE_URL=https://your-helpkit-site.com/access PORT=4000
2. Install Dependencies
npm install express body-parser jsonwebtoken dotenv ejs
3. Backend Server Code
// app.js require('dotenv').config() const express = require('express') const bodyParser = require('body-parser') const jwt = require('jsonwebtoken') const app = express() const { HELPKIT_VISITOR_SECRET_KEY: SECRET, HELPKIT_SITE_URL: SITE, PORT = 4000 } = process.env if (!SECRET || !SITE) { console.error('❌ Missing HELPKIT config in .env') process.exit(1) } app.set('view engine', 'ejs') app.use(bodyParser.urlencoded({ extended: false })) app.get('/login', (req, res) => { res.render('login', { error: null, returnTo: req.query.returnTo || null, }) }) app.post('/login', (req, res) => { const { username, password } = req.body const returnTo = req.query.returnTo || null // ✅ Replace with real user authentication if (username === 'user' && password === 'demo') { const payload = { username } const token = jwt.sign(payload, SECRET, { expiresIn: '7d' }) let redirectUrl = `${SITE}/?jwt_token=${token}` if (returnTo) redirectUrl += `&returnTo=${encodeURIComponent(returnTo)}` return res.redirect(redirectUrl) } res.render('login', { error: 'Invalid credentials', returnTo }) }) app.get('*', (_, res) => res.redirect('/login')) app.listen(PORT, () => { console.log(`✅ Server listening on port ${PORT}`) })
4. Login Form (EJS)
Use the provided login.ejs template for a styled sign-in screen with TailwindCSS.
🧪 Demo Credentials (for local testing)
Username: user Password: demo
🔐 JWT Token: Payload & Expiration
Your backend signs a JWT token using the secret from HelpKit.
Example payload:
{ username: 'user', email: 'user@example.com', role: 'admin' }
You can include any useful data — e.g. name, role, plan type, etc.
Token expiration:
jwt.sign(payload, SECRET, { expiresIn: '7d' }) // 7 days
You can customize this to be shorter (e.g. '2h') or longer depending on how often you want users to re-authenticate. HelpKit will automatically reject expired tokens.
🔁 Redirection Handling
returnTo
When an unauthenticated user visits a HelpKit page, they’ll be redirected to your login with a ?returnTo=
/article-url query
.
You should:
- Preserve it on form submission
- Append it back when redirecting to HelpKit
// After login `${SITE}/?jwt_token=${token}&returnTo=${encodeURIComponent(returnTo)}`
🌍 Works With Any Backend
The same flow applies to any language:
- Python (Flask/Django)
- Ruby
- Go
- PHP
- Java
- Hono / Bun / Cloudflare Workers
Just ensure your backend:
- Authenticates the user
- Signs a JWT
- Redirects to
/access?jwt_token=...
🔗 Useful Links
If you need help, reach out to us — we’re here to assist!