6 min read

Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.

Access control and confidentiality

Note

The following content covers various concepts and tactics to improve security and mitigate cheating in your Roblox games. It's highly recommended that all developers read through these to ensure that your games are secure and fair for all users. Check the sidebar for additional security topics.

Understanding what information and assets are visible to clients is critical for maintaining both the security and confidentiality of your game. Developers often underestimate how much is visible to exploiters and replicated to clients. Exploiters have the ability to access "restricted" places within your universe if they can join a single place. They can view any content replicated to their client, regardless of whether or not it's visible or currently in use. Additionally, exploiters can decompile any replicated local scripts and ModuleScripts, even if they are never executed on the client.

Client-side teleportation within universes

Once inside a universe, clients can teleport to any place within that universe, potentially bypassing any intended access restrictions or progression gates. This can also lead to the unintended leak of unreleased content, for example from a development or staging game. It is important to understand that:

Many developers attempt to prevent access by kicking unauthorized users from a subplace. This may work for blocking gameplay, but it does not prevent content from replicating to the client, since replication begins as soon as the player joins and before server-side kick logic can execute.

Use secure teleports

The most effective way to prevent unauthorized access via teleportation is to set Access Control for Places to Secure within universe only in the Creator Dashboard. This restricts all non-start places to server-initiated teleports only, blocking client-initiated teleports at the platform level before the player ever joins the subplace. Because the player never joins, no content replicates to them.

Note

Enabling Secure within universe only is the recommended setting for any game with restricted subplaces, progression-gated areas, or test places that players should not have access to.

For configuration steps and migration guidance for existing games that use client-initiated teleports, see Teleport between places.

Defense-in-depth for restricted places

For universes that cannot use secure teleports, or as additional layers of protection alongside them, combine the following measures:

Replication

Replication describes how state transfers over the network between instances of the engine. Roblox's replication model is generally simplified in a few key ways:

Replication containers are top-level instances (parented under the DataModel) that replicate to clients. If an instance ever becomes a descendant of a replication container over its lifetime, you should expect much of its state to replicate to all clients. You can read more about common replication containers in the Data model guide. When in doubt, you can always check how an instance or property replicates in a test environment such as Play Solo. You can read more about testing modes in Studio testing modes.

Security implications of replication

Any content that replicates to a client can be extracted and data-mined by an exploiter. As a general rule, avoid publishing or shipping any confidential content to the live production environment unless you are immediately prepared for it to be seen by users. Even if there is logic that gates the release or access of the content in-game until a later date (or some other condition), assume that exploiters will find a way to discover and leak your content as soon as it is published.

Avoid overly descriptive or predictable names for sensitive instances, including but not limited to: scripts, remotes, and models. Having a predictable DataModel hierarchy makes it easier to develop exploits.

Script decompilation

Any LocalScript, Script with RunContext::Client, or ModuleScript can be decompiled by an exploiter once replicated to their client, even if such scripts are disabled, never required, or never run on the client. Server-only Scripts and ModuleScripts stored in ServerStorage or ServerScriptService cannot be decompiled as they never replicate to clients.

Writing a ModuleScript that includes server-only and client-only code in the same script is ill-advised since server-sided logic will be exposed in decompilation and can be more easily dissected for bugs that can be exploited.

local module = {}

local Remote = script:WaitForChild("RemoteEvent")

-- Here's an example of a paradigm to avoid
-- Keep server code in Script instances or in ServerStorage/ServerScriptStorage!

if game:GetService("RunService"):IsServer() then
  function module:DoServerThing(password)
    if password == "SecretPassword" then
      print("sensitive server code")
    end
  end

  Remote.OnServerEvent:Connect(function(player, password)
    module:DoServerThing(password)
  end)
else
  function module:DoServerThing(password)
    Remote:FireServer(password)
  end
end

return module
local table1 = {};
local RemoteEvent = script:WaitForChild("RemoteEvent");
if game:GetService("RunService"):IsServer() then
  function table1.DoServerThing(_, p2) -- Line: 9
    if p2 == "SecretPassword" then
      print("sensitive server code");
    end
  end
  RemoteEvent.OnServerEvent:Connect(function(player: Player, p3) -- Line: 15
    --[[
      Upvalues:
        [1] = table1
    --]]
    table1:DoServerThing(p3);
  end);
  return table1;
end
function table1.DoServerThing(_, p1) -- Line: 19
  --[[
    Upvalues:
      [1] = RemoteEvent
  --]]
  RemoteEvent:FireServer(p1);
end
return table1;

As shown above, decompilation reveals server-side logic including hardcoded passwords, business rules, and implementation details that exploiters can analyze for vulnerabilities.

Impact of confidentiality breaches

Confidentiality breaches can have significant consequences, such as: