Script Capabilities Preview [Client Beta]

Hello everyone!

Today we would like to announce a preview release of “Script Capabilities,” a new feature designed to give you finer control over actions that scripts can perform in your experience.

What Are Script Capabilities?

The system works by transforming an instance and its children inside the Data Model into a sandboxed container. With this new container you can:

  1. limit access to instances outside the container,
  2. configure access to Luau and engine APIs,
  3. limit in what context the scripts are allowed to run.

This unlocks some cool functionality, including:

  • Improve Security of Untrusted Code: You can now limit what models taken from the toolbox can do. More broadly, you can limit the capabilities of any user-generated content inside your experiences, even those that do contain scripts.
  • Reduce Attack Vectors with In-Experience Scripting: Ensure better security for experiences that allow players to write and/or run their own code, which are often executed in a restricted environment, adding additional guardrails. For example, if your experience is a Luau teaching app that allows players to input scripts in experience, then you can add an extra layer of security when executing that code within that same experience.
  • Build More Secure Libraries: Share libraries which restrict what they can do themselves. For example, a library providing more math methods can be restricted to the smallest set of capabilities it needs so that other developers using that library don’t have to validate the whole source code to make sure it doesn’t include additional actions beyond those.

Ready to Try Script Capabilities?

Enable the Beta Feature

In order to be able to configure instance properties associated with this feature, a Workspace setting has to be switched from Default to Experimental.

This setting exists to ensure that the feature is not used by accident while it is still in the Client Beta stage.

Once the Beta stage is completed and the details of the feature have been finalized, this step will no longer be required.

Note that with this beta release it is possible to use the Sandboxed instances in a published experience today! However, we might still make changes to the implementation which might not be backwards-compatible. We will announce those changes as updates in this topic.

Enable Any Container

Once the Workspace property is enabled, you will see new options on Folder, Model, Script instances and any classes derived from those:

Any of those classes can become what we call a sandboxed container.

Enabling the checkbox limits the actions that the scripts inside that container can perform and what instances they are allowed to access based on the set of values inside the Capabilities list.

Customize the Capabilities of Instances in the Container

Finally you can select the capabilities you wish to be available inside the container.

By default, scripts inside will not be allowed to run and you have to enable RunClientScript or RunServerScript capabilities.

Additionally, access to any instance outside the container will be prevented. Unless otherwise required, we recommend keeping this default isolation mode and building packages that communicate through bindable events and functions. Access to all instances can be restored by selecting AccessOutsideWrite capability, but this weakens the isolation guarantees.

Finally, capabilities for Luau and Engine APIs can be selected. If the script attempts to access something for which it doesn’t have a capability, an error message will be reported, including the information on missing capability name.

Not everything is available though! Some APIs have not been assigned a capability yet and some of the higher risk ones are not planned to be made available in a sandboxed environment (especially access to properties affecting the whole experience). For these APIs, you will see an error message mentioning an Unassigned capability. You will not find this capability in the list, but we know that a few popular APIs are still missing, so please leave a message here if you want to use the system but cannot access something specific.

As an example, you can insert a Model into an experience and only provide access to limited capabilities:

Even if the script does something malicious like fetching more scripts by asset id, it will error on an attempt to execute that:

It doesn’t matter how obfuscated the script is, even if it doesn’t look like there’s a require, DataStore access or something else in there, it will be prohibited.

For the full description of the features along with the details on each capability and system restrictions, visit our documentation page: Script Capabilities | Documentation - Roblox Creator Hub

API Dump Changes

For those of you who’ve built tooling around or simply watch our API Dump, you can see these changes in JSON related to capabilities. More than one capability might be required to access an API.

Details

APIv1

"Members": [
   {
      "Capabilities": {
         "Read": [
            "Animation"
         ]
      },
      "Security": {
         "Read": "None",
         "Write": "None"
      },

APIv2

"members": [
   {
      "name": "AccessoryType",
      "readSecurity": "None",
      "writeSecurity": "None",
      "threadSafety": "ReadSafe",
      "capabilities": [
         "Avatar"
      ]

Important Notes

  • This is a beta feature, so some adjustments may occur based on your feedback.
  • We’ll be actively monitoring the use of Script Capabilities and making improvements as needed.
  • Please report any issues you find or suggestions you have as comments to this post!
271 Likes

This topic was automatically opened after 10 minutes.

Great feature! :heart:

83 Likes

This is really cool and is great for preventing malicious assets! Great job, can’t wait to see how this feature evolves.

20 Likes

I’m really happy that this is becoming a thing! I have been wanting this for my game for ages.

I do have some potential features and I am wondering if they are being considered. Our game is heavily sandbox based, meaning players can do whatever they want! However, I have been wanting to add modding support so users can add their own content to the game. This requires me to effectively sandbox our game, which this now allows me to do. To my understanding, I don’t think this allows me to provide access to my own environmental functions or API, which I would REALLY love to see.

Nonetheless, this is a major stepping stone and I am so excited to see where this goes. Thanks a lot!

Edit:
I wanted to try to create my own little API, but it seems we can’t even use BindableEvents in the sandbox. This is really unfortunate. I’m not sure if there’s any other way I can do stuff like this.

Edit 2:
I believe I took an entirely incorrect approach to how this works. I found out exactly how to do everything I desired in this reply!

image

Instead of sandboxing the Server Script, I sandboxed the Folder that contains the “Main” ModuleScript. The ModuleScript receives a Mod table that is created by an unsandboxed Server Script, which has functions that runs unsandboxed code. In the screenshot I showed above I create a part using only the RunServerScript capability. This is incredible technology!

20 Likes

For Rojo we’ve implemented the SecurityCapabilities type as an opaque 64-bit integer for now since we had no idea what the bit fields were on it. That’s changed with this beta. Is the underlying serialization stable or should we treat this as an opaque integer still? I know this is asking a lot but we’d like to support this cleanly for Lune and Rojo users, as you can imagine.

Additionally, there’s currently no API to set this from Luau. While I totally understand why this is this case (it’d be stupid if a plugin could just give scripts whatever capabilities it wants), it will impact Rojo’s ability to actually support this feature. Have any design considerations been made towards this, or should I reach out to someone to discuss it?

This seems to not include ModuleScript, despite the suggestion that libraries limit their own capabilities… Is this a mistake? As a reminder, ModuleScript doesn’t inherit from Script, for reasons known only to Roblox. :slight_smile:

26 Likes

We as a society should bring Script Builders back into popularity with this

25 Likes

This is some sick stuff!! Keep going roblox team

6 Likes

time to implement mods in my game

7 Likes

Hopefully no more virus free models running rampant in our games!

2 Likes

Is this the end of exploits?. i hope so

5 Likes

Amazing feature. Just what is needed, wonderful !

1 Like

I’m stoaked! Great update guys!

While it seems like the end of exploiting, it looks like it’s geared to the instance its self. Wave and Celery and synapse z and all those other exploits create their own script instances, typically in the game root (I.E game.Parent), meaning it doesn’t have any limitations typically. Exploit scripts also run on the client, meaning, well, it won’t actually stop exploiting. It’s one step closer, but it won’t stop them.

Other than that, amazing update! It stops malicious scripts in models, which is a plus.

4 Likes

Wow, this is probably the most powerful feature we’ve had access to in years. I love this, I’m all in for this and yeah feel free to get rid of setfenv

3 Likes

Will we also have an option to make an isolated container that can’t have any direct access from the outside? E.g. different scripts won’t be able to access any instances in a said container?

And would it be possible in the future to disable the ability of changing any of the container’s and it’s children properties (both through scripting and maybe manually)?

2 Likes

Oh this is such an awesome feature!

Honestly, can we also have something like private variables / object properties or private scripts?

Would be cool to have safety features like C-like languages have where you can restrict a variable from being edited by something else to prevent accidentally overwriting things you didn’t meant to.

I had this idea of restricting a model + descendants’ properties to only being editable by the scripts that are inside the same model.

This prevents accidentally changing a part’s CFrame, color or accidentally deleting a weld often caused by external scripts.

1 Like

This doesn’t really have much to do with traditional exploiting really. This is more targeting backdoor scripts and virus toolbox models, as well as provide a safer way for “Lua Sandbox” type games to allow for user-created scripts. Exploits will, unfortunately, still be around for many years to come and hopefully they develop more tools to help combat them as well.

8 Likes

An amazing addition! Can’t wait to have a play around with this and see what I can do with it!

2 Likes

This is a very nice update. I will probably make a LUAU sandbox game once it’s out of beta. And I can see this preventing malicious assets.

Though like @Dekkonot mentioned. Where is the ModuleScript support?

Screenshot 2024-10-25 160119

Screenshot 2024-10-25 160131

3 Likes

Finally!! I get to find out what capabilities are for!

2 Likes