Overview
Pterodactyl Wings uses two authentication mechanisms:- Bearer Token Authentication - For Panel-to-Wings API communication
- JWT (JSON Web Tokens) - For temporary access to specific resources
Bearer Token Authentication
How It Works
Most Wings API endpoints require a static Bearer token that matches the token configured in the Wingsconfig.yml file. This token is shared between the Panel and Wings during initial setup.
Configuration
The authentication token is stored in/etc/pterodactyl/config.yml:
The
token_id is a unique identifier for the node, while token is the actual authentication credential.Making Authenticated Requests
Include the Bearer token in theAuthorization header:
Authorization Header Format
Authentication Flow
When a request is received, Wings:- Extracts the
Authorizationheader - Splits the header on the first space character
- Verifies the prefix is exactly
Bearer - Compares the token using constant-time comparison to prevent timing attacks
- Allows or denies the request based on the match
Protected Endpoints
The following endpoints require Bearer token authentication: System Management:POST /api/update- Update Wings configurationGET /api/system- Get system informationGET /api/servers- List all serversPOST /api/servers- Create new serverDELETE /api/transfers/:server- Delete transferPOST /api/deauthorize-user- Deauthorize user tokens
- All
/api/servers/:server/*endpoints except WebSocket
Authentication Errors
Missing or malformed Authorization header.Response Headers:
Valid Authorization header format but incorrect token.
JWT Authentication
Overview
JWT (JSON Web Tokens) provide temporary, signed access to specific Wings resources without requiring the static Bearer token. JWTs are used for:- WebSocket connections
- File downloads
- Backup downloads
- File uploads
- Server transfers
JWT Algorithm
Wings uses HMAC-SHA256 (HS256) for JWT signing and verification, with the secret key derived from the Wings authentication token. Implementation Reference (router/tokens/parser.go:20-29):WebSocket JWT
WebSocket connections use JWTs to authenticate users and define permissions.Payload Structure
Example WebSocket JWT Payload
Connecting to WebSocket
The WebSocket endpoint is publicly accessible but requires JWT authentication after connection:- Client connects to WebSocket endpoint (no Bearer token required)
- Wings upgrades the connection
- Client sends
authevent with JWT - Wings validates JWT and permissions
- Connection is authenticated
Token Denylist
Wings maintains a denylist of revoked JWTs to prevent unauthorized access: Implementation Reference (router/tokens/websocket.go:80-111):Revoking WebSocket Access
The Panel can revoke WebSocket access using:servers array to revoke access across all servers.
File Download JWT
File downloads use signed URLs with embedded JWTs.Endpoint
Payload Structure
Example File Download JWT
One-Time Use Enforcement
Theunique_id field ensures each token can only be used once:
Implementation Reference (router/tokens/file.go:23-25):
unique_id is marked as consumed, preventing replay attacks.
Backup Download JWT
Backup downloads follow the same pattern as file downloads.Endpoint
Payload Structure
Example Backup JWT
File Upload JWT
File uploads use JWTs in query parameters with multipart form data.Endpoint
Payload Structure
Upload Request Example
- Maximum file size enforced (default: 100 MB)
- Files checked against egg denylist
- Total upload size validated
- Permissions set to
0644
Transfer JWT
Server transfers between Wings instances use JWTs for authentication.Endpoint
Payload Structure
The receiving Wings instance validates the JWT was issued by the Panel before accepting the transfer.Security Best Practices
Token Storage
- Store the Bearer token securely in
/etc/pterodactyl/config.yml - Restrict file permissions:
chmod 600 /etc/pterodactyl/config.yml - Never commit tokens to version control
- Rotate tokens if compromised
JWT Security
- Set short expiration times (typically 15-60 minutes)
- Use one-time tokens for sensitive operations (downloads, uploads)
- Implement proper token revocation via the denylist
- Validate all JWT claims, especially
expandiat
Network Security
- Always use HTTPS/TLS in production
- Configure
trusted_proxiescorrectly if behind a reverse proxy - Restrict Wings API access to Panel backend only (firewall rules)
- Use VPN or private networks when possible
Constant-Time Comparison
Wings usescrypto/subtle.ConstantTimeCompare for token validation to prevent timing attacks:
