-
Notifications
You must be signed in to change notification settings - Fork 0
Host API Security
ServerFabric-Host is the control-plane entry point for instance management.
Because of that, its HTTP API should be treated as a sensitive internal service, not a general public web API.
ServerFabric-Host now supports multiple layers of protection:
- bearer-token authentication
- signed request authentication
- replay protection using nonces
- timestamp window validation
- temporary IP bans for repeated failed authentication
- per-route-group rate limiting
- trusted CIDR handling for internal infrastructure
- audit logging
- rotating compressed audit logs
The recommended deployment model is:
- bind the host to localhost, LAN, VPN, or another private/internal interface
- do not expose the host directly to the public internet unless you know exactly what you are doing
- firewall access so only the proxy or trusted infrastructure can reach it
- use trusted CIDRs for internal container/proxy networks
- use signed requests once the proxy has been migrated
The host supports multiple authentication modes.
Only bearer token authentication is accepted.
This is the legacy/simple mode.
Signed requests are accepted.
If signed headers are not present, bearer token auth is still accepted.
This is the recommended migration mode.
Only signed requests are accepted.
Bearer token auth is ignored.
This is the strongest mode currently supported.
Recommended rollout order:
- start with
TOKEN_ONLY - switch to
TOKEN_OR_SIGNED - update the proxy so it sends valid signed requests
- verify audit logs show successful signed auth
- switch to
SIGNED_ONLY
Bearer mode uses:
Authorization: Bearer <token>
This is still supported for compatibility and transition, but it is weaker than signed requests because it does not provide replay protection or tamper detection.
Signed request mode adds these headers:
X-SFabric-KeyIdX-SFabric-TimestampX-SFabric-NonceX-SFabric-Body-SHA256X-SFabric-Signature
Identifies which configured key/secret is being used.
Example:
X-SFabric-KeyId: proxy-main
Unix epoch time in seconds.
Example:
X-SFabric-Timestamp: 1776972012
A unique per-request random nonce, usually a UUID.
SHA-256 hash of the raw request body in lowercase hex.
The HMAC-SHA256 signature of the canonical request string, also in lowercase hex.
The signed request canonical string is:
METHOD
PATH
TIMESTAMP
NONCE
BODY_SHA256
Joined with newline characters.
Example:
POST
/server/create
1776972012
2b56d7d5-12d0-4a2e-a9e7-5dbe2bdf8a4e
3fd5...abcd
The proxy signs this canonical string using HMAC-SHA256 and the configured shared secret.
The host rebuilds the same canonical string and verifies the signature.
Replay protection uses two checks:
Requests must be recent enough to fall within the configured clock skew window.
If the request is too old or too far in the future, it is rejected.
Each (keyId, nonce) pair is remembered for a short TTL.
If the same nonce is seen again during that TTL, the request is rejected as a replay.
Trusted CIDRs are intended for internal infrastructure such as:
- localhost
- proxy host IPs
- Docker/Pterodactyl bridge networks
- VPN/private subnets
Trusted CIDRs:
- are still fully authenticated
- are still fully audited
- are not auto-banned
- are not rate-limited in the current implementation
This is useful for internal orchestration traffic that may be noisy but should not trip protection rules.
Trusted CIDRs do not bypass authentication.
They only bypass the firewall-style protections.
The host tracks repeated failed authentication attempts per IP.
If an IP exceeds the configured threshold inside the configured time window, it is temporarily blocked.
This is meant to slow down brute-force or abuse attempts.
Trusted CIDRs are excluded from auto-ban behavior.
Requests are rate-limited by route group.
Current route groups are:
READCONTROLDANGEROUS
/status/templates/version
/server/start/server/stop/server/restart/server/command/server/runtime/server/logs/server/stats
/server/create/server/delete/server/kill
Trusted CIDRs bypass rate limiting in the current implementation.
The host writes an audit log with entries that include:
- timestamp
- request ID
- source IP
- HTTP method
- path
- event
- detail
This allows you to answer:
- who called the host
- from where
- for what route
- whether authentication passed
- what action happened
- what the result was
- how long it took
The audit log supports rotation and compression.
Current behavior:
- active log file remains
host-audit.log - when the active file exceeds the size limit, it is rotated
- rotated logs are compressed as
.gz - archive names are date-based, for example:
2026-04-22-1.log.gz
2026-04-22-2.log.gz
This keeps logging useful without allowing the log file to grow forever.
Examples include:
request.beginauth.okauth.failedauth.failed.trustedsigned_auth.oksigned_auth.failedsecurity.trustedrequest.okrequest.blockedip.banned
Route-specific events also exist, such as:
instance.create.requestinstance.start.requestinstance.stats.request
Signed request mode depends on time.
If the proxy and host clocks are badly out of sync, valid signed requests may fail with timestamp-related errors.
Make sure your systems have reasonably correct time.
The host now uses structured JSON API errors.
Example:
{
"ok": false,
"error": "not_running",
"message": "Instance is offline. Live stats are unavailable.",
"requestId": "..."
}This makes it easier for the proxy and tools to handle errors cleanly.
securityTrustedCidrs=127.0.0.1/32,172.20.0.0/16,10.0.0.0/8
securityAuthMode=TOKEN_OR_SIGNED
securitySignedKeyId=proxy-main
securitySignedSecret=CHANGE_ME_TO_A_LONG_RANDOM_SECRET
securityClockSkewSeconds=30
securityNonceTtlSeconds=300A good current setup is:
- private bind or private network only
- trusted CIDRs configured for internal traffic
-
TOKEN_OR_SIGNEDduring migration - then
SIGNED_ONLY - audit logging enabled
- rotating compressed logs kept under retention