Security Overview
Nexgent is designed with security as a core principle. As a self-hosted trading engine handling real funds, security is critical at every layer.
⚠️
This documentation covers the security architecture. For environment variable configuration, see Configuration > Environment Variables.
Security Principles
| Principle | Implementation |
|---|---|
| Non-custodial | Private keys never leave your infrastructure |
| Defense in depth | Multiple security layers (auth, validation) |
| Least privilege | Scoped API keys, role-based access |
| Secure defaults | Sensible defaults, explicit opt-in for risky features |
Authentication
Nexgent supports two authentication methods:
JWT Authentication (Dashboard)
For user sessions via the dashboard:
User → Login → Backend validates credentials
↓
Returns access token (15m) + refresh token (24h)
↓
Frontend stores tokens
↓
Requests include: Authorization: Bearer <access_token>Features:
- Short-lived access tokens (15 minutes)
- Refresh token rotation (single-use)
- Token blacklisting on logout
- "Remember me" for extended sessions (30 days)
API Key Authentication (Integrations)
For programmatic access:
Client → Request with X-API-Key: nex_xxxxx
↓
Backend validates key hash
↓
Checks scopes for endpoint
↓
Processes requestFeatures:
- SHA-256 hashed storage (raw key shown once)
- Granular scoped permissions
- Revocable at any time
Authorization
Resource Ownership
All resources are scoped to the authenticated user:
// Every query includes user ID filter
const agents = await prisma.agent.findMany({
where: { userId: req.user.id },
});Users can only access:
- Their own agents
- Their own wallets
- Their own transactions
- Their own API keys
API Key Scopes
| Scope | Permissions |
|---|---|
full_access | Full API access (grants all permissions) |
signals | Read & write trading signals |
agents | Read agent data & configuration |
positions | Read open positions |
balances | Read agent balances |
transactions | Read transaction history |
history | Read historical swaps |
Use Restricted mode in the UI to select specific scopes, or Full Access for complete API access.
Password Security
Requirements
- Minimum 8 characters
- Maximum 128 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Hashing
- Algorithm: bcrypt
- Salt rounds: 12 (configurable)
- Timing-safe comparison: Prevents timing attacks
// Password hashing
const hash = await bcrypt.hash(password, 12);
// Verification (constant-time)
const valid = await bcrypt.compare(password, hash);Token Security
Access Tokens
- Lifetime: 15 minutes
- Storage: Client memory (not localStorage)
- Blacklisting: Immediate invalidation on logout
Refresh Tokens
- Lifetime: 24 hours (30 days with "remember me")
- Rotation: Single-use (consumed on refresh)
- Storage: Redis with TTL
// Token rotation prevents replay attacks
async consumeRefreshToken(jti: string): Promise<string | null> {
// Atomic get-and-delete
const luaScript = `
local value = redis.call("GET", KEYS[1])
if value then
redis.call("DEL", KEYS[1])
return value
end
return nil
`;
return await client.eval(luaScript, 1, key);
}Secret Management
Required Secrets
| Secret | Purpose | Min Length |
|---|---|---|
JWT_SECRET | Sign JWT tokens | 32 chars |
NEXTAUTH_SECRET | Encrypt NextAuth sessions | 32 chars |
WALLET_N | Solana private keys | N/A |
Generation
# Generate NEXTAUTH_SECRET (frontend)
pnpm generate-secret
# Generate JWT_SECRET (backend)
pnpm generate-secret:backendStorage
- Never commit secrets to version control
- Use
.envfiles (gitignored) - Use secrets manager in production (Railway, AWS Secrets, etc.)
Input Validation
All inputs are validated using Zod schemas:
// Shared validation schema
const CreateAgentSchema = z.object({
name: z.string().min(1).max(100),
walletAddress: z.string().min(32).max(44),
tradingMode: z.enum(['live', 'simulation']),
});
// Validation in handler
const parsed = CreateAgentSchema.safeParse(req.body);
if (!parsed.success) {
return res.status(400).json({ error: parsed.error });
}Security Checklist
Before Deployment
- Generate unique
JWT_SECRET(not example value) - Generate unique
NEXTAUTH_SECRET - Configure
CORS_ORIGINfor production domain - Set
NODE_ENV=production - Use HTTPS (TLS termination at load balancer)
- Configure firewall rules
- Review wallet private key handling
Ongoing
- Review access logs
- Rotate secrets periodically
- Keep dependencies updated
- Monitor for security advisories
Security Pages
- Wallet Security - Private key handling
- API Security - Authentication and authorization
- Network Security - Infrastructure protection
- Vulnerability Reporting - Report security issues