# Run untrusted code with Restricted Functions | Modal Docs

- **URL:** https://modal.com/docs/guide/restricted-access
- **Summary:** This guide page documents Restricted Functions, which can be used to safely execute untrusted code in Modal Functions.

Copy page

Run untrusted code with Restricted Functions

This guide page documents Restricted Functions, which can be used to safely execute untrusted code in Modal Functions.

Create a Restricted Function 

To create a Restricted Function, set `restrict_modal_access=True` in the Function definition:

    @app.function(restrict_modal_access=True)
    def run_untrusted_code(code_input: str):
        # This code cannot access Modal resources
        return eval(code_input)

When `restrict_modal_access` is enabled, the Function cannot

*   access Modal resources (Queues, Dicts, etc.)
*   call other Functions
*   access Modal’s internal APIs

Sandboxes offer an alternative interface for untrusted code 

Modal provides two primitives for running untrusted code: Restricted Functions and [Sandboxes](https://modal.com/docs/guide/sandboxes)
. While both can be used for running untrusted code, they provide different interfaces: Sandboxes provide a process interface, while Restricted Functions provide a function-calling interface. Process interfaces are especially useful for stateful, multi-stage communication, while function-calling interfaces are especially useful for stateless, input/output communication.

These differences are summarized in the table below.

| Feature | Restricted Function | Sandbox |
| --- | --- | --- |
| State | Stateless | Stateful |
| Interface | Function-like | Container-like |
| Setup | Simple decorator | Requires explicit creation/termination |
| Use case | Quick, isolated code execution | Interactive development, long-running sessions |

Best Practices 

When running untrusted code, consider these additional security measures:

1.  Use `single_use_containers=True` to ensure each container only handles one request. Containers that get reused could cause information leakage between users.

    @app.function(restrict_modal_access=True, single_use_containers=True)
    def isolated_function(input_data):
        # Each input gets a fresh container
        return process(input_data)

Note: Prior to v1.3.0, single-use containers were configured by setting `max_inputs=1`.

2.  Set appropriate timeouts to prevent long-running operations:

    @app.function(
        restrict_modal_access=True,
        timeout=30,  # 30 second timeout
        single_use_containers=True
    )
    def time_limited_function(input_data):
        return process(input_data)

3.  Consider using `block_network=True` to prevent the container from making outbound network requests:

    @app.function(
        restrict_modal_access=True,
        block_network=True,
        single_use_containers=True
    )
    def network_isolated_function(input_data):
        return process(input_data)

4.  Minimize the App source that’s included in the container

A restricted Modal Function will have read access to its source files in the container, so you’ll want to avoid including anything that would be harmful if exfiltrated by the untrusted process.

If deploying an App from within a [larger package](https://modal.com/docs/guide/project-structure)
, the entire package source may be automatically included by default. A best practice would be to make the untrusted Function part of a standalone App that includes the minimum necessary files to run:

    restricted_app = modal.App("restricted-app", include_source=False)
    
    image = (
        modal.Image.debian_slim()
        .add_local_file("restricted_executor.py", "/root/restricted_executor.py")
    )
    
    @restricted_app.function(
        restrict_modal_access=True,
        block_network=True,
        single_use_containers=True
    )
    def isolated_function(input_data):
        return process(input_data)

Example: Running LLM-generated Code 

Below is a complete example of running code generated by a language model:

    import modal
    
    app = modal.App("restricted-access-example")
    
    
    @app.function(restrict_modal_access=True, single_use_containers=True, timeout=30, block_network=True)
    def run_llm_code(generated_code: str):
        try:
            # Create a restricted environment
            execution_scope = {}
    
            # Execute the generated code
            exec(generated_code, execution_scope)
    
            # Return the result if it exists
            return execution_scope.get("result", None)
        except Exception as e:
            return f"Error executing code: {str(e)}"
    
    
    @app.local_entrypoint()
    def main():
        # Example LLM-generated code
        code = """
    def calculate_fibonacci(n):
        if n <= 1:
            return n
        return calculate_fibonacci(n-1) + calculate_fibonacci(n-2)
    
    result = calculate_fibonacci(10)
        """
    
        result = run_llm_code.remote(code)
        print(f"Result: {result}")

This example locks down the container to ensure that the code is safe to execute by:

*   Restricting Modal access
*   Using a fresh container for each execution
*   Setting a timeout
*   Blocking network access
*   Catching and handling potential errors

Error Handling 

When a Restricted Function attempts to access Modal resources, it will raise an `AuthError`:

    @app.function(restrict_modal_access=True)
    def restricted_function(q: modal.Queue):
        try:
            # This will fail because the Function is restricted
            return q.get()
        except modal.exception.AuthError as e:
            return f"Access denied: {e}"

The error message will indicate that the operation is not permitted due to restricted Modal access.

[Run untrusted code with Restricted Functions](https://modal.com/docs/guide/restricted-access#run-untrusted-code-with-restricted-functions)
[Create a Restricted Function](https://modal.com/docs/guide/restricted-access#create-a-restricted-function)
[Sandboxes offer an alternative interface for untrusted code](https://modal.com/docs/guide/restricted-access#sandboxes-offer-an-alternative-interface-for-untrusted-code)
[Best Practices](https://modal.com/docs/guide/restricted-access#best-practices)
[Example: Running LLM-generated Code](https://modal.com/docs/guide/restricted-access#example-running-llm-generated-code)
[Error Handling](https://modal.com/docs/guide/restricted-access#error-handling)
