-
Notifications
You must be signed in to change notification settings - Fork 3
Access Control (ACL)
Most systems and components associated with VideoTXL can make use of a common access control system. The system allows controlling access based on attributes like instance owner and master, as well as displayname-based whitelisting. The system also supports bridges to allow controlling access via other state (like a lock control), or to delegate access checks to other third party access control systems.
Access control prefabs and components are located in two main locations.
Contains the main AccessControl prefab and several base classes to allow parts of the ACL to be extended.
- AccessControl: The main prefab
- AccessControlUserSource.cs: A base class for implementing new kinds of user whitelists
Contains additional scripts and prefabs that extend the capabilities of the core ACL.
User Sources (Whitelists)
- Static Whitelist
- Remote Whitelist
- Dynamic Whitelist
Dynamic Whitelist Controls
- Access Grant
- Access Keypad
Bridges
- Forwarding ACL Handler
The main object represents an access control configuration. The main options available are:
Access options:
- Allow Instance Owner
- Allow Master
- Restrict Master if Owner Present
- Only allows master to have access if the instance owner is not present in the world.
- Allow Whitelist
- Enables checking the built-in whitelist or any added whitelist sources.
- Allow Everyone
- Usually for testing, allows all players to have access without needing to change the rest of the configuration.
Other options:
- Enforce
- When disabled, all access checks pass
Whitelist: An internal whitelist containing a list of VRChat display names.
Whitelist Sources: A list of other user source objects, which could include other static whitelists, remote whitelists, or dynamic whitelists.
What's the difference between "Allow Everyone" and "Enforce"?
The "Allow Everyone" option can still be overridden by access handlers (see further down). When "Enforce" is disabled, no checks, including access handlers, are run at all. The check will always pass.
Whitelist sources give more flexibility than the single build-in whitelist in the access control object. More than one source can be used at a time.
Static whitelists are similar to the built-in whitelist of the main ACL. They contain a list of VRChat display names that is checked when access is requested.
A major QOL improvement with static whitelists is names can be bulk-added by pasting a newline-separated list into the box. The pasted names can either fully replace the existing list, or they can be added, which will also ignore any duplicate entries in the list. This makes updating the list from something like a data export very quick.
Multiple static whitelists can be used together to further organize names, and a static whitelist can be added to multiple access control objects.
Remote whitelists use VRChat's string downloading API to download and parse a text file containing display names. The whitelist needs to be provided the URL to download from, and it can be set to download on world start and at a regular interval to refresh the list.
Remote whitelists can be programmatically requested to update. The optional access control field on the object is used to control this access. It does not indicate which access control object is using the data in the remote whitelist.
Remote whitelists can be pre-populated with a list of display names, similar to the build-in whitelist in the main access control object. This list is replaced by the downloaded data when it's successfully pulled.
The object is setup to be able to parse multiple formats of display names. There may be more options available than listed here, if the documentation falls behind.
The remote text file should be a list of VRChat display names separated by a single newline. For exmampe:
username1
username2
username3
JSON parsing will be supported soon.
Dynamic whitelists allow players to be added to the whitelist at runtime, and the list will be persisted and synced, such that players will still retain access even if they leave the instance and rejoin. The package comes with two controls for adding players, although it's possible to write your own controls to manage a dynamic whitelist as well.
The Access Grant prefab is a control with 3 buttons: Request Access, Grant, and Deny.
A player who does not currently have access can press the "Request Access" button, causing their name to appear in the included text area. This will appear for all players in the world. Any other player who already has access controlled by the "Grant ACL" field will be able to use the "Grant" and "Deny" buttons. Pressing grant will add the player's name to the dynamic whitelist. Deny will clear their name from the control.
The Access Grant control is a secure way to allow other "admins" in the instance to give access to other players. The same Access Control object used in the "Grant ACL" field should also be set on the Sync Player List component, which is part of the dynamic whitelist prefab.
The keypad is a general-purpose keypad that can be used for code-based triggers, but it has built-in support for also controlling dynamic whitelists. One or more dynamic whitelists can be added to an access keypad prefab, each with its own associated code. When the code is entered by a player, they will be added to the synced dynamic whitelist.
The Access Keypad is less secure, because there is no existing authority that can verify the request. It also depends on the code itself not leaking to the wider public. When using an access keypad, there should be NO access control object set on the Sync Player List that's part of the dynamic whitelist prefab. Player clients need to be able to take ownership of the list to be able to sync the change.
The access keypad can also be used as a generic trigger. There is a separate list where scripts and event names can be listed with a corresponding code. These triggers are local and are not access checked.
It's possible to register additional handlers with an access control object that will be checked before any other states or lists are checked. Each handler has the ability to return one of three states:
- ALLOW: Indicates the player should have access. No other sources are checked.
- DENY: Indicates the player should not have access. No other sources. are checked.
- PASS: Indicates the next access handler should be checked. If there are no more handlers, access will be determined by the normal access control setup.ac
The package comes with one access handler, the Forwarding ACL Handler. This allows a separate access control object to be checked first, acting as a way to support multiple access control rule sets at the same time.
Other uses for access handlers might be:
- Controlling access by checking a separate state, such as a system's "lock" state if it has one.
- Delegating the access lookup to a third party access control system
-
- If you have a world with an existing access control system in place, this will allow VideoTXL components to utilize that system.
Your access handler needs to call the _RegisterAccessHandler
method on access control object it's being attached to. If any state in your handler changes, or external state that you're using to determine access changes, you should call the _Validate
method on the access control object, which will signal any listening scripts that access of the local player may have changed.
To use the access control system in your own code, add a reference to the main access control object. The main API mthods of interest are:
-
_LocalHasAccess()
: Checks if the local player has access according to the configuration -
_HasAccess(VRCPlayerAPI player)
: Checks if the given player has access -
_Enforce(bool state)
: Whether the ACL should be enforced -
_AddUserSource(AccesssControlUserSource source)
: Adds a new whitelist source to the access control configuration
Additionally, if you're using more than static lists, it will be important to register a validation handler.
acl._Register(AccessControl.EVENT_VALIDATE, this, nameof(_MyValidateHandler))
This will cause your _MyValidateHandler
method to be called whenever access state might have changed, allowing you to re-check access if necessary.