SentryAC / Docs

SentryAC documentation

Everything you need to install SentryAC on a FiveM server, tune it for your community and hook it into your own resources.

Getting started

Introduction

SentryAC is an anti-cheat resource for FiveM. It runs as a normal resource on your server and has two halves:

  • The client side watches for things like injected menus, Lua executors and impossible player states.
  • The server side confirms what the client reports, checks events and entity spawns, and decides what to do.

Nothing is acted on from the client alone. A detection only leads to a kick or ban once the server has checked it, which keeps false bans from lag or desync to a minimum.

Requirements

  • A FiveM server running a recent recommended artifact.
  • OneSync enabled. Entity, vehicle and player-state checks rely on it.
  • A SentryAC licence from the dashboard.
  • No database is needed. Bans are stored by SentryAC and synced to your dashboard.

SentryAC works alongside common frameworks such as ESX and QBCore, and on standalone servers.

Installation

  1. Download the resource. Sign in to the dashboard, open Downloads and grab the latest sentryac.zip.
  2. Add it to your resources. Extract it so the folder sits at resources/[security]/sentryac. Don't rename the folder.
  3. Start it first. Add it to server.cfg above your framework and every other resource, so it's running before anything else loads.
    # Start SentryAC before everything else
    ensure sentryac
    
    ensure oxmysql
    ensure es_extended
    # ...the rest of your resources
  4. Add your licence key (see Licence key), then restart the server.

Heads up: if another resource starts before SentryAC, it can register events before they're protected. Keeping ensure sentryac at the top avoids that.

Licence key

Your key lives in server.cfg, not in the resource, so updates never overwrite it. Copy it from Dashboard → Servers → Licence.

set sentryac_licence "SAC-XXXX-XXXX-XXXX-XXXX"

Each licence is tied to one server IP. If you move hosts, update the IP in the dashboard before starting the new server.

Tip: keep the key out of public repositories. If you share your server.cfg, move the line into a separate file and load it with exec.

Checking it works

When the server starts you should see this in the console:

[SentryAC] v1.0.0 loaded
[SentryAC] Licence valid · eu-rp-01
[SentryAC] 18 detections active · protection running

You can check at any time by running sentry status in the server console. Your server should also show as online in the dashboard within a minute.

Updating

Download the new version from the dashboard and replace every file in the sentryac folder except config.lua, then restart. If a release adds new config options, the changelog lists them; anything you don't add falls back to its default.

Configuration

Config overview

All settings are in sentryac/config.lua. Run sentry reload after editing to apply changes without restarting the server.

Config = {}

Config.Locale = "en"        -- language for kick and ban messages
Config.Debug  = false       -- extra console output while you tune detections

Config.Detections    = { ... }  -- see Detections
Config.Bans          = { ... }  -- see Actions & bans
Config.AllowedEvents = { ... }  -- see Event protection
Config.EventLimits   = { ... }
Config.Entities      = { ... }  -- see Entities & vehicles
Config.Webhooks      = { ... }  -- see Discord webhooks

Detections

Each detection has its own entry in Config.Detections. Anything you leave out uses its default from the detection list.

Config.Detections = {
    Godmode       = { action = "ban",  tolerance = 2 },
    Noclip        = { action = "ban" },
    Teleport      = { action = "kick", maxDistance = 250.0 },
    Speed         = { action = "flag", tolerance = 1.25 },
    ExplosionSpam = { action = "kick", limit = 5, window = 10 },
    WeaponSpawn   = { enabled = false },
}

Shared options

OptionTypeDefaultWhat it does
enabledbooleantrueTurns the check on or off.
actionstringvaries"flag", "block", "kick" or "ban". See Actions.
tolerancenumbervariesHow many times the check must trip, or how far over the limit a value must be, before acting.
durationstringConfig.Bans.defaultBan length for this detection only, for example "7d" or "perm".

Tuning a new check: set its action to "flag" for a few days first. It logs to your dashboard without touching players, so you can see what it would have caught.

Actions & bans

ActionWhat happens
flagLogged to the dashboard and warnings webhook. The player isn't affected.
blockThe action is stopped (the entity is deleted, the event is dropped) and logged.
kickThe player is dropped with a message and can rejoin.
banThe player is kicked and can't rejoin until the ban expires or is lifted.
Config.Bans = {
    default     = "perm",   -- "30m", "12h", "7d", "perm"
    identifiers = { "license", "discord", "fivem" },  -- matched on rejoin
    appealUrl   = "https://discord.gg/your-server",   -- shown on the ban screen
}

Bans are matched against every identifier in identifiers, so changing one account isn't enough to get back in. Every ban gets an ID such as SAC-4F2K9 that players can quote in an appeal.

Event protection

Server events are the most common way servers get abused: a menu fires giveMoney a thousand times and the economy is gone. SentryAC handles this in two ways.

Allowed events

List the events clients are allowed to trigger. Anything else coming from a client is dropped and flagged as Unlisted event.

Config.AllowedEvents = {
    "garage:requestCar",
    "shop:buyItem",
    "phone:sendMessage",
}

Rate limits

Limits are counts per window in seconds. default applies to every allowed event that doesn't have its own line.

Config.EventLimits = {
    default          = { count = 20, window = 1 },
    ["shop:buyItem"] = { count = 3,  window = 5, action = "kick" },
}

Not sure what to list? Turn on Config.Debug and play normally for a while. Every unlisted event is printed to the console with the resource that registered it.

Entities & vehicles

Config.Entities = {
    maxPerMinute = 30,      -- props, peds and vehicles a player can spawn
    action       = "block",

    blacklistedModels = {
        "rhino", "hydra", "lazer",            -- vehicles
        "prop_windmill_01", "prop_ld_ferris_wheel",  -- props used for griefing
    },
}

Models can be written as names or hashes. Entities created by your own server scripts are never counted, only ones requested by clients.

Discord webhooks

Create a webhook in each Discord channel you want logs in (Channel settings → Integrations → Webhooks) and paste the URLs here.

Config.Webhooks = {
    bans     = "https://discord.com/api/webhooks/...",  -- kicks and bans
    warnings = "https://discord.com/api/webhooks/...",  -- flags and blocks
    admin    = "",                                       -- staff commands, optional
}

Each message includes the player's name, server ID, identifiers, the detection, the ban ID and a link to the full log in your dashboard. Leave a URL empty to turn that channel off.

Permissions

SentryAC uses FiveM's built-in ACE permissions. Add these to server.cfg:

# Staff can use sentry commands
add_ace group.admin sentryac.admin allow

# Skip detections entirely (use sparingly)
add_ace group.owner sentryac.bypass allow

add_principal identifier.discord:123456789012345678 group.admin

Be careful with bypass: anyone with sentryac.bypass isn't checked at all. Give it to as few people as possible, and never to a whole staff group.

Reference

Detection list

Every check, the key you use for it in Config.Detections, and what it does out of the box.

DetectionConfig keyDefaultNotes
GodmodeGodmodebanHealth or armour that doesn't drop when it should.
NoclipNoclipbanMoving through the map without collision.
TeleportTeleportkickPosition jumps over maxDistance metres.
SpeedSpeedflagOn foot or in vehicles, compared with the model's top speed.
Super jumpSuperJumpkickJump height beyond what the game allows.
InvisibilityInvisiblebanPlayer ped hidden while not in a script-allowed state.
SpectateSpectatekickSpectating without the admin permission.
Weapon spawnWeaponSpawnbanWeapons that weren't given by the server.
Infinite ammoInfiniteAmmokickFiring without ammo going down.
AimbotAimbotflagAim snapping further in one frame than a mouse or pad can. Starts in shadow mode.
Silent aimSilentAimflagHits landing well away from where the player is aiming. Starts in shadow mode.
TriggerbotTriggerbotflagShots fired consistently faster than human reaction time. Starts in shadow mode.
Damage modifierDamageModifierkickHits doing more damage than the weapon can. Starts in shadow mode.
Weapon rangeWeaponRangeflagHits from further away than the weapon reaches. Starts in shadow mode.
Shooting through wallsWallShotflagHits with no line of sight. Starts in shadow mode.
Explosion spamExplosionSpamkickMore than limit explosions in window seconds.
Entity spamEntitySpamblockUses Config.Entities.maxPerMinute.
Blacklisted modelBlacklistedModelblockAnything in blacklistedModels.
Lua executorExecutorbanKnown executors and injected Lua runtimes.
Resource injectionResourceInjectionbanClient resources your server didn't start.
NUI devtoolsNuiDevtoolskickOpening devtools on your NUI pages.
Missed heartbeatHeartbeatkickThe player's game stops checking in, which usually means SentryAC was stopped on their side.
Unlisted eventUnlistedEventblockClient events not in Config.AllowedEvents.
Event floodEventFloodkickGoing over Config.EventLimits.
Bad event argumentsBadArgumentsblockAllowed events sent with the wrong types, NaN or oversized payloads.
Decoy eventHoneypotbanTriggering an event in Config.Honeypots, which no legitimate script uses.
Dump attemptDumpAttemptbanTrying to read SentryAC-protected client files.

Commands

Commands work in the server console and in game for anyone with sentryac.admin.

CommandWhat it does
sentry statusVersion, licence state and active detections.
sentry reloadReloads config.lua without a restart.
sentry check <id>Shows recent flags for a player.
sentry ban <id> <length> <reason>Bans a player manually, for example sentry ban 12 7d Exploiting.
sentry unban <banId>Lifts a ban by its ID, such as SAC-4F2K9.
sentry pause <id> <minutes>Stops checking one player for a while, useful during admin scenes.

Server exports

Use these from your own server scripts.

BanPlayer

-- source, reason, duration (optional, uses Config.Bans.default)
local banId = exports.sentryac:BanPlayer(source, "Duping items", "7d")

FlagPlayer

Logs a detection from your own code, with any details you want in the dashboard. It follows the action set for that name, or "flag" if there isn't one.

exports.sentryac:FlagPlayer(source, "ShopExploit", {
    item   = itemName,
    amount = amount,
})

IsBypassed

if exports.sentryac:IsBypassed(source) then
    return -- staff with sentryac.bypass
end

PauseCheck

Pauses one check for one player before your script does something that would trip it. Capped by the longest pause set on the Exemptions page.

-- source, detection key, seconds
exports.sentryac:PauseCheck(source, "Teleport", 5)
SetEntityCoords(GetPlayerPed(source), x, y, z)

Protecting your own events

Allowed events are still worth checking. Here's a shop event that refuses amounts nobody could buy legitimately:

RegisterNetEvent("shop:buyItem", function(item, amount)
    local src = source

    if type(amount) ~= "number" or amount < 1 or amount > 50 then
        exports.sentryac:FlagPlayer(src, "ShopExploit", { item = item, amount = amount })
        return
    end

    -- normal purchase logic
end)

Server events

Listen for these to plug SentryAC into your own logging or staff tools.

AddEventHandler("sentryac:onDetection", function(src, detection, action, details)
    print(("[AC] %s tripped %s -> %s"):format(GetPlayerName(src), detection, action))
end)

AddEventHandler("sentryac:onBan", function(src, banId, reason, duration)
    -- e.g. post to your own staff channel
end)
EventArguments
sentryac:onDetectionsrc, detection, action, details
sentryac:onBansrc, banId, reason, duration
sentryac:onUnbanbanId, staffName

Help

Dashboard

  • Logs: every flag, block, kick and ban, filterable by player, detection and date.
  • Bans: search by name, identifier or ban ID, and lift or shorten bans.
  • Appeals: each ban links to the evidence that caused it, so you can review it before replying.
  • Team: invite staff and choose who can view logs, ban or change settings.
  • Servers: licence keys, server IPs and downloads.

Troubleshooting

"Licence invalid" on start

Check the key in server.cfg has no extra spaces, and that the server IP in the dashboard matches the machine you're running on.

Legit players getting flagged

Switch that detection to "flag", raise its tolerance, and look at the logs to see what's triggering it. If it still looks wrong, send the log ID to support and we'll look at it.

A script stopped working after install

Its events probably aren't in Config.AllowedEvents. Turn on Config.Debug, use the script, and add the events printed in the console.

Running another anti-cheat

Two anti-cheats watching the same things will fight each other. Turn off the overlapping checks in one of them, or remove the other one.

Changelog

v1.0.0Initial release

  • First public release with 18 detections.
  • Dashboard with logs, bans, appeals and team access.
  • Discord webhooks for bans and warnings.
Still stuck?

Ask in our Discord. Include your server name and any log IDs.

Get help on Discord