# Functions

_Evervault Functions are secure serverless runtimes that decrypt Evervault data at runtime so you can run custom logic safely._

Evervault Functions are secure serverless functions which allow you to process data encrypted by Evervault products. When you pass encrypted data to a function, it's automatically decrypted. You can then process this data by running custom logic written in Node.js or Python as you usually would, but without ever handling it in plaintext on your infrastructure.

## Deploying a function

The quickest way to deploy your first function is to create a starter template by connecting your GitHub account.

1. Sign in to the Evervault Dashboard
2. Create or open an app and navigate to the **Functions** tab
3. Click **Create Function**
4. Select **Choose template**
5. Authenticate with GitHub
6. Select a starter template and deploy your function

> **Using the CLI**
>
> You can also use the [Evervault CLI](/sdks/cli) to deploy a function directly
>   from your machine.

### Redeploying a function

Evervault listens for webhooks from GitHub to determine when to redeploy functions. If function code is in the root directory, all changes in that repository redeploy the function. If function code is in a subdirectory, only changes within that subdirectory trigger a redeploy.

## Running a function

Functions can be invoked using our [SDKs](/sdks), or using our [REST API](/api). Any encrypted data within the payload sent to the function is decrypted before being passed to the function handler.

### Client-side execution

API keys are sensitive and shouldn't be used client-side. When invoking functions from frontend applications, we recommend using a run token. Run tokens are single use, time bound tokens for invoking a function with a given payload. Run tokens last five minutes and must be used with the same payload that was used to create the run token.

Run tokens should be created in your backend using our [API](/api) and handed off to your client.

```javascript
await fetch("https://api.evervault.com/functions/:function-name/runs", {
  method: "POST",
  headers: {
    Authorization: "RunToken <RUN_TOKEN>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    payload: { message: "ev:tk9d:wjfiw..." },
  }),
});
```

### Responses

The response from a function run will contain a status field. The status field will be either `success` or `failure`, depending on whether the function completed successfully or not. Any payload returned from the function will be inside of the `result` field of the response object.

```json
{
  "id": "func_run_bd9e16a08f18",
  "status": "success",
  "result": {
    "message": "Hello from a Function!"
  }
}
```

#### Error handling

If there is a failure in the course of a function run, the response will contain an error object with a `message` and `stack` field. The `message` field will contain a human readable error message, and the `stack` field will contain a stack trace of the error.

```json
{
  "id": "func_run_6de494a86a7d",
  "status": "failure",
  "error": {
    "message": "Oh no! Something went wrong",
    "stack": "Error: Oh no! Something went wrong\n    at exports.handler (/runtime/app/index.js:26:15)\n    at /runtime/index.js:65:26\n    at new Promise (<anonymous>)\n    at /runtime/index.js:52:16"
  }
}
```

> **FunctionNotReady**
>
> Functions that have been idle for extended periods of time may return
>   `FunctionNotReady HTTP 409` errors. This can be resolved by retrying the
>   request.

## Encryption within a function

An `encrypt` function can be accessed through the context parameter. This allows you to encrypt data in your response using your app’s keys.

## Configuration

Evervault Functions are configured using a `function.toml` configuration file which can be committed to source control. Simply provide a `function.toml` file in the root of your repository and Evervault automatically includes it at build time.

```toml
[function]
# Customize your function's timeout by providing a positive integer value.
# The timeout is defined in seconds.
# Timeouts of greater than 55 seconds are only permitted for asynchronous function runs.
# Default: 30
# Maximum: 900
timeout = 45

# Customize your function's entry point by specifying the handler in the form `<FILE>.<FUNCTION>`
handler = "main.myFunc"

# The name of your function
name = "your-function-name"

# The language of your function
# Node: node@18, node@20
# Python: python@3.9, python@3.10, python@3.11
language = "node@18"
```

### Dependencies

When you deploy a function to Evervault, we locate your `package.json` (for Node.js) and `requirements.txt` file (for Python) and install any non-development dependencies.

When using Node.js, if a `node_modules` folder is included then dependency installation is skipped; this can be used to include private dependencies.

If there are any issues with your dependencies, for example if you have missed one in your `package.json`, an `InitializationError` is thrown.

Python runtime images (`python@3.9`, `python@3.10`, `python@3.11`) include the `gpg` command line tool, so your function can shell out to it for operations that Python's PGP libraries don't support natively.

### Environment variables

You configure environment variables for functions in the [Evervault Dashboard](https://app.evervault.com) or with the [CLI](/sdks/cli). To use environment variables to store secrets, there're some specific steps you need to take.

#### Encrypted secrets

> Mark all sensitive values (API keys, access tokens, credentials, etc.) as secrets when adding them as environment variables.

You can set an environment variable as a secret when you create it (either in the Dashboard or with the CLI). This encrypts the value at creation time using your app's keys.

Secrets are stored and displayed in their encrypted form in every context except the function handler. At startup, the function runtime decrypts secrets and injects them as environment variables that you can access with `process.env` in Node.js or `os.environ` in Python.

| Context | Value visibility |
| --- | --- |
| Evervault Dashboard | Encrypted |
| CLI `Get` Command | Encrypted |
| Function handler (runtime) | Plaintext |

#### Storing partner API keys

If your function calls a third-party, store its API key, credentials, or any other sensitive data as an environment variable and make sure to [set it as a secret](#encrypted-secrets). This ensures the key is never visible in plaintext in the Dashboard or logs, and is only decrypted inside the function.

### Networking

#### Limiting access to your function

By default, functions respond to requests invoked from any client with a valid Evervault API key or run token. You can limit access to your functions by adding IP addresses to the allowlist in the [Dashboard](https://app.evervault.com). This only allows your functions to be invoked when requests are made from IPs in that list.

#### Limiting egress from your function

By default, functions can send requests to any third-party endpoint. You can add domain names to the allowlist in the [Dashboard](https://app.evervault.com) to limit network access to the hostnames you specify.

### Limitations

Evervault Functions have a maximum memory consumption of `1024MB`, 2 available CPU cores, and 512MB of ephemeral filesystem storage. If you require more memory or CPU cores, check out [Evervault Enclaves](/enclaves) — the easiest way to build, deploy, and scale Secure Enclaves.

> Don't use ephemeral storage for sensitive data. It's possible for ephemeral data to be available to future function invocations, which increases the risk of an accidental data leak.

There are two ways to pass data into functions, and each one has its own limit on the amount you can include. When you run a function with our SDKs or REST API, the payload used for invocation should be kept below 1MB. Separately, after the function is running, you can pull data into it (e.g., downloading and processing files, making an API call to retrieve some information). Data pulled into functions this way should be kept below 1GB.

Rate limits are set at 100 RPM for [Sandbox apps](/developers/sandbox) and 6000 RPM in production. If you need higher rate limits, contact [support@evervault.com](mailto:support@evervault.com).

### Execution time

Evervault Functions have a default execution time of 30 seconds. This can be increased to a maximum of 55 seconds (for synchronous invocations) by setting the `timeout` in the [function.toml](#configuration).

#### Asynchronous functions

Asynchronous function runs up to 15 minutes are also permitted. To execute a function in async mode, you must set the [async argument](/api#createFunctionRun-request-async) on your request payload to `true`.

```javascript
fetch("https://api.evervault.com/functions/hello-function/runs", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Basic <credentials>",
  },
  body: JSON.stringify({
    async: true,
    payload: {
      name: "ev:Tk9D:oVPHsPvwFHNk73DU:AglNWOgZekolcrxdxSpZJOusBgE+C9eWSapGIZkgTsUj:JKeSkdhVE9SCXqQINID4oBRCE/VhTb56VWGqyObP:$",
    },
  }),
});
```

## Observability

Logs for all function runs can be viewed inside of the [Evervault Dashboard](https://app.evervault.com). You can learn more about observability in our [observability guide](/developers/observability).

- [Relay](/relay): Encrypt or decrypt data in transit—between your app and your own APIs, or any third-party APIs.
- [Card Collection](/cards/card-collection): Learn how to use Card Collection to collect cardholder data.

