Welcome to the Sandbox project! In this tutorial series, we will build a secure environment where code can run safely without harming your computer.
We start at the very top: the Sandbox Settings Orchestrator.
Imagine the "Settings" app on your smartphone. When you want to turn on "Airplane Mode," you don't need to know how to program the radio antenna or disconnect the cellular modem manually. You just flip a simple switch in the UI.
The Sandbox Settings Orchestrator is that interface for our project.
We have a complex security system with many moving parts:
We need one central place to visualize this state and let the user change it easily.
The Orchestrator (SandboxSettings.tsx) is a high-level component that:
Instead of managing dozens of checkboxes, the Orchestrator simplifies the world into three distinct "Modes":
The interface isn't static. If your system is missing a security tool (like bubblewrap), the Orchestrator notices this via the Environment Health Diagnostics and automatically inserts a "Dependencies" tab to help you fix it.
Before looking at code, let's look at the flow of data. The Orchestrator sits between the User and the low-level Sandbox Data Adapter.
Let's look at how SandboxSettings.tsx is built. We will look at simplified versions of the code to understand the logic.
The database stores raw boolean flags (enabled, autoAllow), but the UI needs a friendly string. This function translates raw data into a UI state.
// Inside SandboxSettings component
const getCurrentMode = () => {
if (!currentEnabled) {
return "disabled";
}
if (currentAutoAllow) {
return "auto-allow";
}
return "regular";
};
We prepare the options for the dropdown menu. We use a helper variable currentIndicator to visually mark which option is currently active.
const options = [
{
label: currentMode === "auto-allow"
? `Sandbox, with auto-allow ${currentIndicator}`
: "Sandbox, with auto-allow",
value: "auto-allow"
},
// ... similar blocks for "regular" and "disabled"
];
When the user picks a new mode, the Orchestrator acts as a translator. It converts the simple string (e.g., "disabled") into the specific instructions for the Sandbox Data Adapter.
const handleSelect = async (value: SandboxMode) => {
switch (value) {
case "disabled":
await SandboxManager.setSandboxSettings({
enabled: false,
autoAllowBashIfSandboxed: false
});
onComplete("Sandbox disabled");
break;
// ... other cases
}
};
SandboxManager does the heavy lifting of saving to disk. The UI simply tells it what to do.
This is where the "Orchestrator" really shines. It looks at the depCheck (Dependency Check) result to decide what tabs to render.
// If we have critical errors, ONLY show the Dependencies tab
const tabs = hasErrors
? [
<Tab key="deps" title="Dependencies">
<SandboxDependenciesTab depCheck={depCheck} />
</Tab>
]
: [
modeTab,
overridesTab,
configTab
];
hasErrors), the Orchestrator forces the user to focus on the "Dependencies" tab by hiding the others. This prevents users from trying to configure a broken sandbox.We have built the Control Center.
The Sandbox Settings Orchestrator doesn't enforce security rules itself. Instead, it provides a friendly face for the user to manage complex configurations. It intelligently adapts the UI based on whether the system is healthy or broken.
But how do we know if the system is healthy? How do we know if the user has the right tools installed?
For that, we need to inspect the system.
Next Step: Let's look at how we scan the computer for security tools in the Security Configuration Inspector.
Generated by Code IQ