Security
The Security global provides three server-side capabilities for module authors: permission checks, rate limiting, and an audit log. Use it instead of rolling your own ACL or raw GetPlayerGroup calls.
Permission Levels
Shiva uses a numeric rank model:
| Name | Rank |
|---|---|
user | 0 |
mod | 10 |
admin | 50 |
superadmin | 100 |
A player passes a permission check if their rank is greater than or equal to the required level.
Checking Permissions
-- Check a group name against a required level
local allowed = Security.hasPermission('admin', 'mod') -- true (50 >= 10)
-- Check the in-game player's group (reads GetPlayerGroup(source))
local allowed = Security.playerHasPermission(source, 'admin')In an Event Handler
AddEventHandler('net:mymodule:doAdminThing', function()
local source = source
if not Security.playerHasPermission(source, 'admin') then
return
end
-- ...
end)In a Command Handler
commands:register('ban', {
permission = 'admin', -- ICommands checks this automatically
handler = function(source, args)
-- only reached if source is admin or higher
end,
})TIP
When using ICommands, permission is checked automatically — you don't need to call Security.playerHasPermission manually inside the handler. Use Security directly for raw event handlers or custom logic.
Rate Limiting
Protect sensitive events from being spammed with a token-bucket rate limiter keyed by any string.
local allowed, reason = Security.rateLimit(key, windowSecs, maxRequests)
if not allowed then
Log.warn('mymodule', 'Rate limit hit', { key = key, reason = reason })
return
endThe key is typically a combination of the player source and event name:
AddEventHandler('net:mymodule:purchaseItem', function(itemId)
local source = source
local key = source .. ':purchaseItem'
local allowed, reason = Security.rateLimit(key, 5, 3)
-- max 3 requests per 5 seconds per player
if not allowed then return end
-- process purchase
end)Rate limit buckets are in-memory and reset when the resource restarts.
Audit Log
Record security-relevant actions for server owner review.
Security.audit(source, action, context)Security.audit(source, 'ban:issued', {
target = targetSource,
reason = 'cheating',
expires = os.time() + (7 * 24 * 60 * 60),
})Security.audit emits an EventBus event (security:audit) and writes a structured log entry via Log.info. The shiva-api relay can forward audit events to an external log store if configured.
API Reference
| Method | Description |
|---|---|
Security.hasPermission(groupName, required) | Returns true if groupName rank ≥ required rank |
Security.playerHasPermission(source, required) | Checks the in-game player's group via GetPlayerGroup |
Security.rateLimit(key, windowSecs, maxRequests) | Returns allowed (bool), reason (string) |
Security.audit(source, action, context) | Emits audit event and logs the action |
Server-only
Security is a server-side global. It is not available in client scripts.