Skip to main content

Command Palette

Search for a command to run...

The Power of Custom Profiles

Updated
6 min read
The Power of Custom Profiles

My nono.sh sandbox setup for Mistral Vibe worked for basic use, but using the CLI with numerous parameters became cumbersome as my needs evolved. This article explores how introducing custom profiles improves sandbox maintenance as my workspaces evolve.

As per my last article, my sandbox setup for Mistral Vibe worked for basic use with limited permissions. However, as I began using agents and other tools to review, write, and execute scripts, the limitations of that approach became clear. A simple alias is no longer sufficient, and CLI options have become cumbersome, with not all features available in sub-commands or options.

This article explores how using profiles improves and simplifies sandbox environments.

Guess Who?

As sandbox requirements grow, the number of --param value attributes increases, making them harder to maintain, track, or reuse—even with aliases.

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/5321a1cc-dd27-458e-9201-ea7e444c3ca4.png align="middle")

Nono.sh features are built on direct flags, policies, and configurations, which are merged to feed the sandbox engine. To leverage this, it provides profiling: you can configure features and policies, making everything available via an alias.

Most well-known code assistants - Claude Code and Codex - already have predefined profiles. For example:
nono run --profile claude-code -- claude
nono run --profile codex -- codex

However, if you use a different code assistant, no predefined profile is available, leaving you stranded.

Meet Your Profiles

Again, AlwaysFurther demonstrates its commitment to a full-fledged ecosystem. They have built a well-defined flow for creating, tweaking, and validating profiles.

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/a5ff4378-02f7-43f1-a6d5-9791475df322.png align="middle")

Let's define some ground rules. Custom user-created profiles should be stored in ~/.config/nono/profiles as JSON or JSONC files. If the folder does not exist, you must create it.

The profile contains the following structure:

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/4fa8ad3b-b377-4928-978f-497652458a06.png align="middle")

The profile structure allows you to configure permissions for the working directory where the sandbox is created. Include or exclude group policies. Enable or revoke file system access.
Depending on whether you focus on folders or files, different configurations apply.

For more demanding environments, you can tweak Unix socket permissions and access, as well as constrain the system at the network level.
To clarify: the term "allow" implies both read and write capabilities.

But if you want to have a shortcut, invoking nono profile init creates the new profile with a very simple structure.

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/8cee7ce5-9cf7-4487-b505-1c961a98cd2b.png align="middle")

(About the last line on the previous image, we will dive into that later in this article)

As an experiment, add one configuration. Normally, I start by hardening the system.
If you use a .env file, add it to the $.filesystem.deny.
Then you can use nono profile validate.

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/c2794fd1-2710-475e-848f-73c04b910726.png align="middle")

At this point, you have all the tools to create a profile that meets your needs. Now you can run your tailored sandbox with nono run --profile <name>.

Now that you're comfortable with the basics, you can explore deeper.
You can stand on the shoulders of others. For example, if you're using an existing profile, but your workspace has specific nuances, use the inheritance ability by setting $.extends.

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/ca65129a-1dcb-4368-9232-2bf1460e8eb9.png align="middle")

For myself, with Mistral Vibe, I did not extend from any existing profile. I've tried it, and it was a very hardened environment beyond my needs; therefore, I was not able to run it successfully.

Side Questing

When you need to improve and tweak your profile beyond basic use, you might want to make your life easier while at it.
There is a JSON schema file for the profile document that you should use with your code editor.

Run nono profile schema -o schema.json on your terminal. This creates a local file with schema rules so you can import it into your IDE to validate and autocomplete while you tweak the profile.

Another superpower of [nono.sh] - previously addressed in another article—is its ability to track access with meaningful details.
While using profiles, it tracks what went wrong, what was accessed, and what failed, then proposes changes to the profile.

![](https://cdn.hashnode.com/uploads/covers/67db38cc65e4929300956363/e1759402-53f2-4947-aee1-453ed1a26145.png align="middle")

If you get annoyed by this, you can run your sandbox with --suppress-save-prompt /my/path or add a list of files/folders to $.filesystem.suppress_save_prompt field.

As of version 0.57.0, there is no broad way to disable these suggestions. However, you can use the suppression option, which automatically updates the profile. The next time the sandbox restricts access, the suggestion will not appear again.

Balance

Creating my own profile has allowed me to tweak my sandbox without keeping a command train behind an alias.
After each session, I can learn, at the file system level, what was accessed and whether to grant or block it, streamlining sandbox usage.

Having at my disposal the proper conditions for seamless sandbox use, for example, while working on a Python project. There are built-in group policies and profiles that allow my sandbox to properly interoperate with Python ecosystems and runtimes out of the box.
The best part is that if I have specific needs, as shown in this article, I can reuse configurations, build on them, and tailor the best experience for my sandboxes—and that is a great selling point.
Even though I am not currently using all that power, these capabilities make it easy for developers and teams to share configurations, reuse them, and tweak specifics at the project level.

One inauspicious limitation is the lack of support for wildcard or glob patterns like **/.env. This would greatly benefit multidisciplinary projects, such as monorepos.
In addition, the sandbox is not compatible with compound permissions schemes. Such allowing \(HOME/project and denying the folder \)HOME/project/module or file $HOME/project/protected.txt - because the latter are objects within the former grant and create a conflict, and the sandbox does not run.

The Verdict

Bottom line, I personally enjoy using a sandbox as the last barrier between these emerging tools and my data and machine.
As I use, learn, and integrate them to help me deliver better results, I am still concerned about those whimsical moments where they get "hungry" for access and data.
For a while, I believed that I needed my OS to hold that barrier; if the OS did not do that, I was glad to find a third-party solution.

As I go on this journey, I'm learning to tweak these environments to keep me safe while taking the most advantage of these tools.
I want to intelligently constrain them so they work effectively while giving me an edge, without compromising security. I feel confident on this path.

Furthermore, I haven’t found my sweet spot with nono.sh yet, but I’m confident I will.