Protect your script
Built-in whitelist
How SantiAuth embeds the whitelist into your script, and what that means for security.
On this page
Not a loader — a whitelist inside your file
SantiAuth does not download your source at runtime. Every script you obfuscate in the dashboard gets the whitelist embedded — the backend builds one file:
┌──────────────────── file the player runs ────────────────────┐
│ SA_INIT_SCRIPT function (optional, not obfuscated) │
│ ┌──────────────────── obfuscated ──────────────────────────┐ │
│ │ local SantiAuth = <client> │ │
│ │ SantiAuth.script_id = "<id>" -- injected for you │ │
│ │ SantiAuth.run_whitelist() -- kicks without a key │ │
│ │ -- your script │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘Because of that:
- Your source never travels over the network. The server only answers with a signed activation; it never sends code.
- No key, no code.
run_whitelist()kicks the player before the first line of your script runs. SantiAuthis a local variable of the chunk — it can't be replaced throughgetgenv().SA_*variables are written into your script's own environment, so other scripts in the executor can't see them.
Where the key comes from
The whitelist looks for a key in this order:
- The key passed to
check_key(key). script_keyin your script's environment.getgenv().script_key.
The usual way is to set it right before the loadstring:
script_key = "PASTE-YOUR-KEY-HERE"
loadstring(game:HttpGet("https://api.santiauth.com/api/loader/v4/script/<script-id>"))()What happens on execution
1Requests your script
2Public stub (no grant yet)
3Stub sends
script_key42-minute grant, then the protected file
5Validates the key, opens a signed session
6Encrypted, signed activation
7Sets
SA_*and runs your code8Heartbeat every 20 seconds
- 1
Executor → SantiAuth API
Requests your script
- 2
SantiAuth API → Executor
Public stub (no grant yet)
- 3
Executor → SantiAuth API
Stub sends
script_key - 4
SantiAuth API → Executor
2-minute grant, then the protected file
- 5
Executor → SantiAuth API
Validates the key, opens a signed session
- 6
SantiAuth API → Executor
Encrypted, signed activation
- 7
Executor
Sets
SA_*and runs your code - 8
Executor → SantiAuth API
Heartbeat every 20 seconds
- Download — the loader URL never hands out the protected file without a valid key. Without a download grant it returns a small public stub: it runs your SA_INIT_SCRIPT (if any), checks
script_key, gets a 2-minute grant and only then downloads the real file. A missing or bad key kicks right here, before anything of your script is downloaded. - Validate — the key is checked over HTTPS: exists, not banned, not expired, HWID matches (or is bound for the first time), and the script belongs to the key's owner.
- Start — the client opens a one-time session signed with a per-session secret, and sends an integrity report about the executor.
- Activate — the server replies with an encrypted, signed activation. A hooked
requestcan't forge it. - Run —
SA_*variables are set and your code runs. - Heartbeat — every 20 seconds the session is re-checked. A revoked or expired key ends it.
Updating the client
When SantiAuth ships a new client version, scripts you obfuscated earlier still contain the old copy. Press Re-obfuscate on the script in Obfuscation to rebuild it with the current client — the loader URL stays the same.