> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formal.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Rego Built-in Functions

> The 189 OPA built-in functions Formal policies can call, and the ones they can't

## Overview

Formal policies can call 189 standard [OPA built-in functions](https://www.openpolicyagent.org/docs/policy-reference/builtins) (reference for each function's signature). Formal blocks every function that reaches the network or that only makes sense outside a proxy. Formal adds no custom built-ins.

The same list applies everywhere a policy runs: in the Control Plane when you save it, on Connectors, and on the Formal Endpoint.

## Blocked Functions

These standard OPA functions are not available:

| Function | Why it's blocked |
| - | - |
| `http.send` | Makes network calls from the policy engine |
| `net.lookup_ip_addr` | Makes DNS lookups from the policy engine |
| `providers.aws.sign_req` | Signs requests for outbound calls |
| `print`, `trace` | Debug output is not collected |
| `rego.metadata.chain`, `rego.metadata.rule`, `rego.parse_module` | Introspection is not supported |
| `array.flatten`, `strings.render_template`, `strings.split_n` | Not available |
| `uri.is_valid`, `uri.parse` | Not available |
| `io.jwt.verify_eddsa` | Not available. Other `io.jwt.verify_*` functions work. |

Instead of calling `http.send`, load external data with a [Policy Data Loader](/docs/guides/core-concepts/satellites#policy-data-loader-satellite) and read it from `data`. To run your own code during evaluation, use [Hooks](/docs/guides/policies/hooks).

### What Happens if You Call One

The Control Plane compiles every policy before it saves it. A call to a blocked function fails that check, and the policy is not saved:

```text theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
Invalid rego policy: 1 error occurred: formal.rego:3: rego_type_error: undefined function http.send
```

## Allowed Functions

### Operators (17)

`assign` (`:=`), `eq` (`=`), `equal` (`==`), `neq` (`!=`), `lt` (`<`), `lte` (`<=`), `gt` (`>`), `gte` (`>=`), `plus` (`+`), `minus` (`-`), `mul` (`*`), `div` (`/`), `rem` (`%`), `and` (`&`), `or` (`|`), and the `in` membership operator (`internal.member_2`, `internal.member_3`)

### Numbers (8)

`abs`, `ceil`, `floor`, `round`, `numbers.range`, `numbers.range_step`, `format_int`, `to_number`

### Aggregates (8)

`count`, `sum`, `product`, `max`, `min`, `sort`, `all`, `any`

### Arrays (3)

`array.concat`, `array.reverse`, `array.slice`

### Sets (3)

`intersection`, `union`, `set_diff`

### Objects (10)

`object.filter`, `object.get`, `object.keys`, `object.remove`, `object.subset`, `object.union`, `object.union_n`, `json.filter`, `json.remove`, `json.patch`

### Strings (23)

`concat`, `contains`, `endswith`, `indexof`, `indexof_n`, `lower`, `replace`, `split`, `sprintf`, `startswith`, `strings.any_prefix_match`, `strings.any_suffix_match`, `strings.count`, `strings.replace_n`, `strings.reverse`, `substring`, `trim`, `trim_left`, `trim_prefix`, `trim_right`, `trim_space`, `trim_suffix`, `upper`

### Regular Expressions and Globs (11)

`re_match`, `regex.find_all_string_submatch_n`, `regex.find_n`, `regex.globs_match`, `regex.is_valid`, `regex.match`, `regex.replace`, `regex.split`, `regex.template_match`, `glob.match`, `glob.quote_meta`

### Bits (6)

`bits.and`, `bits.lsh`, `bits.negate`, `bits.or`, `bits.rsh`, `bits.xor`

### Types and Casts (14)

`is_array`, `is_boolean`, `is_null`, `is_number`, `is_object`, `is_set`, `is_string`, `type_name`, `cast_array`, `cast_boolean`, `cast_null`, `cast_object`, `cast_set`, `cast_string`

### Encoding (21)

`base64.decode`, `base64.encode`, `base64.is_valid`, `base64url.decode`, `base64url.encode`, `base64url.encode_no_pad`, `hex.decode`, `hex.encode`, `json.is_valid`, `json.marshal`, `json.marshal_with_options`, `json.unmarshal`, `json.match_schema`, `json.verify_schema`, `urlquery.decode`, `urlquery.decode_object`, `urlquery.encode`, `urlquery.encode_object`, `yaml.is_valid`, `yaml.marshal`, `yaml.unmarshal`

### Tokens (16)

`io.jwt.decode`, `io.jwt.decode_verify`, `io.jwt.encode_sign`, `io.jwt.encode_sign_raw`, `io.jwt.verify_es256`, `io.jwt.verify_es384`, `io.jwt.verify_es512`, `io.jwt.verify_hs256`, `io.jwt.verify_hs384`, `io.jwt.verify_hs512`, `io.jwt.verify_ps256`, `io.jwt.verify_ps384`, `io.jwt.verify_ps512`, `io.jwt.verify_rs256`, `io.jwt.verify_rs384`, `io.jwt.verify_rs512`

### Time (10)

`time.add_date`, `time.clock`, `time.date`, `time.diff`, `time.format`, `time.now_ns`, `time.parse_duration_ns`, `time.parse_ns`, `time.parse_rfc3339_ns`, `time.weekday`

### Cryptography (15)

`crypto.hmac.equal`, `crypto.hmac.md5`, `crypto.hmac.sha1`, `crypto.hmac.sha256`, `crypto.hmac.sha512`, `crypto.md5`, `crypto.sha1`, `crypto.sha256`, `crypto.parse_private_keys`, `crypto.x509.parse_and_verify_certificates`, `crypto.x509.parse_and_verify_certificates_with_options`, `crypto.x509.parse_certificate_request`, `crypto.x509.parse_certificates`, `crypto.x509.parse_keypair`, `crypto.x509.parse_rsa_private_key`

### Networks (7)

`net.cidr_contains`, `net.cidr_contains_matches`, `net.cidr_expand`, `net.cidr_intersects`, `net.cidr_is_valid`, `net.cidr_merge`, `net.cidr_overlap`

### Graphs and GraphQL (9)

`graph.reachable`, `graph.reachable_paths`, `walk`, `graphql.is_valid`, `graphql.parse`, `graphql.parse_and_verify`, `graphql.parse_query`, `graphql.parse_schema`, `graphql.schema_is_valid`

### Other (8)

`uuid.parse`, `uuid.rfc4122`, `semver.compare`, `semver.is_valid`, `units.parse`, `units.parse_bytes`, `rand.intn`, `opa.runtime`

## Read Deployment Settings with `opa.runtime`

`opa.runtime()` returns an object with a single `env` key. It holds only the environment variables whose names start with `FORMAL_POLICY_ENV_`, read from the Connector or Endpoint that evaluates the policy. Other variables, such as credentials, are never exposed.

Set a variable on the Connector:

```bash theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
FORMAL_POLICY_ENV_REGION=eu-west-1
```

Read it in a policy:

```rego theme={"languages":{"custom":["/languages/cel.json","/languages/rego.json"]}}
package formal.v2

import future.keywords.if

region := opa.runtime().env.FORMAL_POLICY_ENV_REGION

session := {
  "action": "block",
  "type": "block_with_custom_message",
  "message": "Use the EU connector for this resource"
} if {
  region != "eu-west-1"
  input.resource.environment == "eu"
}
```

If the variable isn't set, `region` is undefined and the rule doesn't match.

## Next Steps

<CardGroup cols={2}>
  <Card title="Evaluation" icon="microscope" href="/docs/guides/policies/evaluation">
    Inputs available at each policy stage
  </Card>

  <Card title="Operations" icon="wrench" href="/docs/guides/policies/operations">
    Validate, test, and troubleshoot policies
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.