🔐

Permissions

Val Town lets you run code incredibly easily. It could be your code, but it can also be other people’s code. This article provides a summary of how permissions work in Val Town.

📖
For a more in-depth reference to how and why the permissions system works, see the announcement blog post: Restricted Library Mode

The basics

To have a working understanding of the permissions system, there are only two rules that you need to remember:

  1. If you want to use another person’s function with access to your own secrets, pass those secrets as arguments.
  1. If you want to use another person’s function with access to the other person’s secrets, call it via an API.
💡
The api function used above is a shortcut for making a plain old HTTP request. There’s more about this later on in this article. For more about the types of endpoints exposed, see
Give your val an HTTP endpoint
Give your val an HTTP endpoint

Exposing your vals to the internet

Public vals are great because they can be called from anywhere, anytime, instantly. They can also be called by anyone.

Since anyone can call your public endpoints, if they interact with some data that should only be changed by yourself, you will need to make sure that those endpoints check for some kind of secret that only you know.

Here’s an example of a val exposed using the

, secured with a secret that only I know.

If I called it without supplying the secret, I’ll be denied access:

By supplying the secret in a header, I’m allowed access:

The rest of this article will focus on various common combinations of public and private vals that you’re likely to come across and how those interact with the permissions system.

Public code referencing private data

It is safe for a a public val to reference one of your private vals or one of your secrets. Private vals and secrets are like environment variables in this way — others can see that they’re being used, but not their values.

For example, I created a private val, example3. You won’t be able to see or reference example3 but I can use it in example4 which is public.

You can infer that the value of example3 is "Stevie" because of how it’s used here. This is why you have to be careful about publishing vals that reference private data. Typically you will reference private data in a way that makes it impossible for others to infer what it is, like you would with an environment variable credentials. Below I am passing my secrets to an Upstash Redis store. You can see that I’m using these secrets and the output of this computation, but you can’t get those values, nor can you rerun this script with my secrets.

Using another’s vals as a library

Using another’s val is like using a library from npm. The code runs entirely in your sandbox and they don’t get any access to your evaluation logs. In this way it is safe to pass other’s code your private data and secrets.

There is still one exploit to be wary of, that you likewise need to be wary of when using any package on npm, and that is that the library author could maliciously rewrite the function to do something nefarious with your private data, like send it to themselves. Package ecosystems have built up a number of ways to combat this threat, such a version pinning, package scanning, and reporting.

We will soon be rolling out version pinning to help alleviate this issue, but we can confidently say that this exploit has yet to be abused in Val Town. However if you would like to be as protected as possible, we recommend forking any function you want to run onto your account to effectively pin that version.

To further protect your private data, we restrict anyone else’s vals to access your private state. Any call to @me.secrets.foo would fail unless you are the author of the val that is making this call. The appropriate pattern to get secrets from other users on Val Town is to input them as arguments to your function, as in @patrickjm.gpt3 used above.

Using another’s vals as an API

Sometimes you don’t want a library — you want an API. For example, you may want to call someone’s function and it relies upon using their own private data, such as one of their API keys. For example instead of passing my own OpenAI key to @patrickjm.gpt3, I want to rely on his API key, which generously provides a small amount of free usage. You can do this by using the Val Town Run API, which turns any public val into a callable REST API. We also have a couple of helper functions to make this easier, but it’s important to know that under the hood, it’s just a normal HTTP API call.

api()

The recommend way to do this is to use our build-in api function. It’s magical in a couple of ways:

  1. It allows you to specify the name of the val you want to call without quoting it.
  2. It gives you proper TypeScript help for the args of the val you’re calling
  3. It is slightly faster than using the Run API directly because it doesn’t go out to the public internet and back to our server

The api method can be approximated by this runValAPI function, which simply calls a public val via the Run API.