Skip to content

Permissions

There are three privacy settings for a Val:

  • Discoverable and visible to everyone on the Val Town website
  • Anyone can view the code and import it into their own vals
  • HTTP endpoints are accessible to anyone
  • Only visible to people who have the direct link
  • Won’t appear in search results or public listings
  • Anyone with the link can view the code and import it
  • HTTP endpoints are accessible to anyone who knows the URL
  • Only visible to you
  • Only your vals can import the code
  • HTTP endpoints are accessible to anyone who knows the URL

HTTP endpoints are accessible to anyone who knows the URL, regardless of the val’s privacy setting. If your endpoint handles sensitive data, you should add authentication.

Since anyone can call your 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 an HTTP endpoint within a val, using the concepts described in the HTTP Triggers documentation, secured with an environment variable that only I know:

user/secretEndpointRun in Val Town ↗
export const secretEndpoint = (req: Request) => {
const secretHeader = req.headers.get("Authorization");
if (secretHeader !== Deno.env.get("SECRET")) {
return new Response("Unauthorized", { status: 401 });
}
return new Response("My deepest darkest secret");
};

If I called it without supplying the environment variable, I’d be denied access:

Without authenticationRun in Val Town ↗
const response = await fetch("https://user-secretEndpoint.web.val.run");
console.log(response);
Logs
Response {
body: ReadableStream { locked: false },
bodyUsed: false,
headers: Headers { /* omitted */ },
ok: false,
redirected: false,
status: 401,
statusText: "Unauthorized",
url: "http://localhost:3001/v1/fetch?url=https%3A%2F%2Fuser-secretEndpoint.web.val.run"
}

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

With authenticationRun in Val Town ↗
const response = await fetch("https://user-secretEndpoint.web.val.run", {
headers: { Authorization: "SECRET_123" },
});
console.log(response);
Logs
Response {
body: ReadableStream { locked: false },
bodyUsed: false,
headers: Headers { /* omitted */ },
ok: true,
redirected: false,
status: 200,
statusText: "OK",
url: "http://localhost:3001/v1/fetch?url=https%3A%2F%2Fuser-secretEndpoint.web.val.run"
}

sign & possibly encrypt the conveyed data using standard authentication methods.