Install
$ agentstack add skill-auth0-agent-skills-auth0-express ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Auth0 Express Integration
Add authentication to Express.js web applications using express-openid-connect.
Prerequisites
- Express.js application
- Auth0 account and application configured
- If you don't have Auth0 set up yet, use the
auth0-quickstartskill first
When NOT to Use
- Single Page Applications - Use
auth0-react,auth0-vue, orauth0-angularfor client-side auth - Next.js applications - Use
auth0-nextjsskill which handles both client and server - Mobile applications - Use
auth0-react-nativefor React Native/Expo - Stateless APIs - Use JWT validation middleware instead of session-based auth
- Microservices - Use JWT validation for service-to-service auth
Quick Start Workflow
1. Install SDK
npm install express-openid-connect dotenv
2. Configure Environment
For automated setup with Auth0 CLI, see [Setup Guide](references/setup.md) for complete scripts.
For manual setup:
Create .env:
SECRET=
BASE_URL=http://localhost:3000
CLIENT_ID=your-client-id
CLIENT_SECRET=your-client-secret
ISSUER_BASE_URL=https://your-tenant.auth0.com
AUDIENCE=https://your-api-identifier # only required if calling external APIs (Step 3a)
Generate secret: openssl rand -hex 32
3. Configure Auth Middleware
Update your Express app (app.js or index.js):
require('dotenv').config();
const express = require('express');
const { auth, requiresAuth } = require('express-openid-connect');
const app = express();
// Configure Auth0 middleware
app.use(auth({
authRequired: false, // Don't require auth for all routes
auth0Logout: true, // Enable logout endpoint
secret: process.env.SECRET,
baseURL: process.env.BASE_URL,
clientID: process.env.CLIENT_ID,
issuerBaseURL: process.env.ISSUER_BASE_URL,
clientSecret: process.env.CLIENT_SECRET
}));
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
> Calling external APIs? If you need an access token for a downstream API, you must add authorizationParams — see Step 3a below.
This automatically creates:
/login- Login endpoint/logout- Logout endpoint/callback- OAuth callback
3a. Configure Middleware for API Access (when calling external APIs)
When you need an access token for an external API, audience must go inside authorizationParams — putting it at the top level is silently ignored and no access token is issued.
// SDK auto-loads SECRET, BASE_URL, CLIENT_ID, ISSUER_BASE_URL, CLIENT_SECRET from env vars
app.use(auth({
authRequired: false,
auth0Logout: true,
authorizationParams: { // ← required for access tokens
response_type: 'code', // ← required: authorization code flow
audience: process.env.AUDIENCE, // ← API identifier (never top-level)
scope: 'openid profile email'
}
}));
Then access the token in your route:
app.get('/api-call', requiresAuth(), async (req, res) => {
const { access_token } = req.oidc.accessToken; // object, not a string
const response = await fetch('https://your-api.com/data', {
headers: { Authorization: `Bearer ${access_token}` }
});
res.json(await response.json());
});
4. Add Routes
// Public route
app.get('/', (req, res) => {
res.send(req.oidc.isAuthenticated() ? 'Logged in' : 'Logged out');
});
// Protected route
app.get('/profile', requiresAuth(), (req, res) => {
res.send(`
Profile
Name: ${req.oidc.user.name}
Email: ${req.oidc.user.email}
${JSON.stringify(req.oidc.user, null, 2)}
Logout
`);
});
// Login/logout links
app.get('/', (req, res) => {
res.send(`
${req.oidc.isAuthenticated() ? `
Welcome, ${req.oidc.user.name}!
Profile
Logout
` : `
Login
`}
`);
});
5. Test Authentication
Start your server:
node app.js
Visit http://localhost:3000 and test the login flow.
Detailed Documentation
- [Setup Guide](references/setup.md) - Automated setup scripts, environment configuration, Auth0 CLI usage
- [Integration Guide](references/integration.md) - Protected routes, sessions, API integration, error handling
- [API Reference](references/api.md) - Complete middleware API, configuration options, request properties
Common Mistakes
| Mistake | Fix | |---------|-----| | Forgot to add callback URL in Auth0 Dashboard | Add /callback path to Allowed Callback URLs (e.g., http://localhost:3000/callback) | | Missing or weak SECRET | Generate secure secret with openssl rand -hex 32 and store in .env as SECRET | | Setting authRequired: true globally | Set to false and use requiresAuth() middleware on specific routes | | App created as SPA type in Auth0 | Must be Regular Web Application type for server-side auth | | Session secret exposed in code | Always use environment variables, never hardcode secrets | | Wrong baseURL for production | Update BASE_URL to match your production domain | | Not handling logout returnTo | Add your domain to Allowed Logout URLs in Auth0 Dashboard | | audience as a top-level config key | Move audience inside authorizationParams with response_type: 'code' and scope — top-level audience is silently ignored, no access token is issued | | req.oidc.accessToken used as a string | It is an object — destructure with const { access_token } = req.oidc.accessToken |
Related Skills
auth0-quickstart- Basic Auth0 setupauth0-migration- Migrate from another auth providerauth0-mfa- Add Multi-Factor Authenticationauth0-cli- Manage Auth0 resources from the terminal
Quick Reference
Middleware Options:
authRequired- Require auth for all routes (default: false)auth0Logout- Enable /logout endpoint (default: false)secret- Session secret (required)baseURL- Application URL (required)clientID- Auth0 client ID (required)issuerBaseURL- Auth0 tenant URL (required)
Request Properties:
req.oidc.isAuthenticated()- Check if user is logged inreq.oidc.user- User profile objectreq.oidc.accessToken- Access token object ({ access_token, token_type, expires_in });expires_inis seconds remaining. Destructure withconst { access_token } = req.oidc.accessToken. Also exposesisExpired()andrefresh()methods. Only populated whenauthorizationParamswithaudience+response_type: 'code'is configuredreq.oidc.idToken- ID tokenreq.oidc.refreshToken- Refresh token
Common Use Cases:
- Protected routes → Use
requiresAuth()middleware (see Step 4) - Check auth status →
req.oidc.isAuthenticated() - Get user info →
req.oidc.user - Call APIs → [Integration Guide](references/integration.md#calling-apis)
References
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: auth0
- Source: auth0/agent-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.