Skip to main content

Overview

The Soft-Bee API uses JSON Web Tokens (JWT) for authentication and authorization. JWT configuration controls token generation, validation, and expiration.
The API uses two types of tokens: access tokens for API authentication and reset tokens for password reset flows.

JWT Environment Variables

Secret Key

JWT_KEY
string
required
Secret key used to sign and verify JWT tokens
This key must be kept secret and should be different from your Flask SECRET_KEY. In production, this variable is required.
JWT_KEY=your-jwt-secret-key-here
Default Value: secret-key-default (development only)
Never use the default JWT key in production. Generate a secure random key using a cryptographically secure method.

Algorithm

ALGORITHM
string
default:"HS256"
Algorithm used for signing JWT tokensSupported algorithms:
  • HS256 (HMAC with SHA-256) - Recommended for most use cases
  • HS384 (HMAC with SHA-384)
  • HS512 (HMAC with SHA-512)
  • RS256 (RSA with SHA-256) - Requires public/private key pair
ALGORITHM=HS256
Default Value: HS256

Access Token Expiration

EXPIRES_TOKEN_SESSION
number
default:"1440"
Expiration time for access tokens in minutesDefault: 1440 minutes (24 hours)
EXPIRES_TOKEN_SESSION=1440
Common Values:
  • 15 - 15 minutes (high security)
  • 60 - 1 hour (balanced)
  • 1440 - 24 hours (default, user convenience)
  • 10080 - 7 days (long-lived sessions)
Shorter expiration times are more secure but require users to log in more frequently. Balance security with user experience.

Reset Token Expiration

EXPIRES_TOKEN_EMAIL
number
default:"30"
Expiration time for password reset tokens in minutesDefault: 30 minutes
EXPIRES_TOKEN_EMAIL=30
Common Values:
  • 15 - 15 minutes (high security)
  • 30 - 30 minutes (default, balanced)
  • 60 - 1 hour (user convenience)
Reset tokens should have shorter expiration times than access tokens for security. The default of 30 minutes is recommended.

Configuration in Code

The JWT configuration is loaded from environment variables in config.py:
config.py
class Config:
    # JWT Configuration
    JWT_SECRET_KEY = os.getenv("JWT_KEY", "secret-key-default")
    JWT_ALGORITHM = os.getenv("ALGORITHM", "HS256")
    JWT_ACCESS_TOKEN_EXPIRES = int(os.getenv("EXPIRES_TOKEN_SESSION", 1440))  # 24 hours
    JWT_RESET_TOKEN_EXPIRES = int(os.getenv("EXPIRES_TOKEN_EMAIL", 30))  # 30 minutes

Environment-Specific Examples

# .env.local
JWT_KEY=dev-jwt-secret-key-local
ALGORITHM=HS256
EXPIRES_TOKEN_SESSION=1440
EXPIRES_TOKEN_EMAIL=30

Generating Secure Keys

For production deployments, generate cryptographically secure JWT keys:

Using OpenSSL

# Generate a 256-bit (32-byte) random key
openssl rand -hex 32

Using Python

import secrets

# Generate a secure random key
jwt_key = secrets.token_hex(32)
print(f"JWT_KEY={jwt_key}")

Using Node.js

const crypto = require('crypto');

// Generate a secure random key
const jwtKey = crypto.randomBytes(32).toString('hex');
console.log(`JWT_KEY=${jwtKey}`);
Store generated keys securely. Never commit JWT keys to version control. Use environment variables or secret management systems.

Token Types

Access Tokens (Session Tokens)

Purpose: Used for authenticating API requests Expiration: Controlled by EXPIRES_TOKEN_SESSION (default: 24 hours) Usage:
  • Included in Authorization header as Bearer {token}
  • Used for all authenticated API endpoints
  • Returned upon successful login
Example:
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  https://api.softbee.com/apiaries

Reset Tokens (Email Tokens)

Purpose: Used for password reset flows Expiration: Controlled by EXPIRES_TOKEN_EMAIL (default: 30 minutes) Usage:
  • Sent via email for password reset
  • One-time use only
  • Shorter expiration for security
Example:
Reset link: https://app.softbee.com/reset-password?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Production Validation

In production mode, the application validates that critical JWT configuration is present:
config.py
class ProductionConfig(Config):
    # Validate that JWT_KEY exists in production
    if not os.getenv("JWT_KEY"):
        raise ValueError("JWT_KEY is required in production")
The application will fail to start in production if JWT_KEY is not set. This prevents accidentally using insecure default values.

Security Best Practices

Use strong, random keys - Generate keys using cryptographically secure methods
Different keys per environment - Use unique JWT keys for each environment
Separate from SECRET_KEY - JWT_KEY should be different from Flask’s SECRET_KEY
Shorter expiration in production - Consider shorter token lifetimes for production
Secure key storage - Use environment variables or secret managers, never hardcode
Rotate keys periodically - Implement key rotation for long-running production systems
Use HTTPS only - Always transmit tokens over encrypted connections

Token Expiration Recommendations

Access Tokens

High Security

15-60 minutesBest for: Financial apps, healthcare, sensitive data

Balanced

1-24 hoursBest for: Most web applications (default)

User Convenience

7-30 daysBest for: Mobile apps, trusted devices

Reset Tokens

High Security

10-15 minutesShort window, forces quick action

Balanced

30 minutesRecommended default setting

User Convenience

1-2 hoursMore time for users to reset

Troubleshooting

Cause: The access token has exceeded its expiration time.Solution:
  • Request a new token by logging in again
  • Consider increasing EXPIRES_TOKEN_SESSION for better UX
  • Implement token refresh mechanism
Cause: Token signature verification failed.Solutions:
  • Ensure JWT_KEY is the same across all app instances
  • Check that the token hasn’t been tampered with
  • Verify the algorithm matches (ALGORITHM)
Cause: Missing JWT_KEY in production environment.Solution:
export JWT_KEY=$(openssl rand -hex 32)
Cause: Existing tokens were signed with old key.Solution:
  • All users must log in again to get new tokens
  • This is expected behavior when rotating keys
  • Consider implementing graceful key rotation

Integration Example

Here’s how to use JWT tokens with the API:
1

Login to get token

curl -X POST https://api.softbee.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"password"}'
Response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer"
}
2

Use token in requests

curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  https://api.softbee.com/apiaries
3

Handle expiration

When token expires, the API returns:
{
  "error": "Token has expired",
  "status": 401
}
Client should redirect to login or refresh the token.

Next Steps

Environment Configuration

Configure different environments

Database Configuration

Set up database connections

Build docs developers (and LLMs) love