# Go and Rego Language Comparison

Go is a statically typed, compiled programming language. It is commonly used in cloud native environments for building services and APIs.

Go is generally well suited to such use cases. However, when it comes to expressing policy code, it can be verbose when expressing large policies that must unpack unstructured or untrusted data safely.

This guide presents a series of examples illustrating how a policy can be expressed in Go, and the corresponding Rego code for comparison.

## Check If a User Is an Admin

Admin status is often encoded in a [JWT](http://jwt.io) (JSON Web Token). This example shows how to extract information from a JWT and make an authorization decision based on it. The example uses an insecure secret to verify the JWT for brevity.

### Go

```
package mainimport (    "fmt"    "github.com/golang-jwt/jwt")func allow(tokenString string) (bool, error) {    token, err := jwt.Parse(        tokenString,        func(token *jwt.Token) (any, error) {            if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {                return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])            }            return []byte("pa$$w0rd"), nil        },    )    if err != nil {        return false, fmt.Errorf("failed to parse token: %v", err)    }    if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {        roles, ok := claims["roles"].([]any)        if !ok {            return false, nil        }        if slices.Contains(roles, "admin") {            return true, nil        }    }    return false, nil}
```

### Rego

```
package exampleclaims := io.jwt.decode(input.token)[1] if {    io.jwt.verify_hs256(input.token, "pa$$w0rd")}default allow := falseallow if "admin" in claims.roles
```

**Note:** Verifying JWTs with a hard-coded secret is insecure and is used here for example only, please refer to the OPA documentation on [Token Verification](/docs/policy-reference/builtins/tokens) for more information on how to securely verify JWTs.

## Grant Access Based on Inherited Permissions

Staff roles are used to define permissions that a given user has within an organization. In this example, we show how permissions can be inherited from other roles based on the organization's staff hierarchy. Rego's [`graph.reachable`](https://www.openpolicyagent.org/docs/policy-reference/#builtin-graph-graphreachable) built-in function not only keeps the policy concise but is also safe from infinite recursion caused by cyclic dependencies in the staff hierarchy.

### Go

```
package mainimport (    "fmt"    "slices")var manages = map[string][]string{    "manager":    {"supervisor", "security"},    "supervisor": {"assistant"},    "security":   {},    "assistant":  {},}var datasetPermissions = map[string][]string{    "manager":    {"salaries"},    "supervisor": {"rotas"},    "security":   {"cctv"},    "assistant":  {"product_prices"},}func reachableRolesForRole(role string) []string {    roles := []string{role}    for _, r := range manages[role] {        roles = append(roles, r)        roles = append(            roles,            reachableRolesForRole(r)...,        )    }    return roles}func allow(role, dataset string) (bool, error) {    inheritableRoles := reachableRolesForRole(role)    for _, r := range inheritableRoles {        if datasets, ok := datasetPermissions[r]; ok {            if slices.Contains(datasets, dataset) {                return true, nil            }        }    }    return false, nil}
```

### Rego

```
package examplemanages := {    "manager": {"supervisor", "security"},    "supervisor": {"assistant"},    "security": set(),    "assistant": set(),}dataset_permissions := {    "manager": {"salaries"},    "supervisor": {"rotas"},    "security": {"cctv"},    "assistant": {"product_prices"},}default allow := falseallow if {    some inherited_role in graph.reachable(      manages, {input.role}    )    input.dataset in dataset_permissions[inherited_role]}
```

## Validate User-Generated Content

Policy is often used to guide users when they make mistakes. Validation of user-generated resources can be complicated and often needs to be implemented in many applications. This example compares code for validating a user-submitted blog post and shows how Rego rules can be defined [incrementally](/docs/policy-language/#incremental-definitions).

### Go

```
package mainimport (    "fmt"    "strings")func validations(input map[string]interface{}) []string {    var messages []string    // ensure that title and content are set    fields := []string{"title", "content"}    for _, field := range fields {        if val, ok := input[field]; !ok || val == "" {            messages = append(messages, fmt.Sprintf("Value missing for field '%s'", field))        }    }    // ensure that title starts with a capital letter    if title, ok := input["title"].(string); ok {        if title != "" && title[0] < 'A' || title[0] > 'Z' {            messages = append(messages, "Title must start with a capital")        }    }    // ensure user identifier is set    user, ok := input["user"].(map[string]interface{})    if !ok {        messages = append(messages, "User email or id must be set")    } else {        _, hasEmail := user["email"]        _, hasId := user["id"]        if !hasEmail && !hasId {            messages = append(messages, "User email or id must be set")        }        if email, ok := user["email"].(string); ok {            // ensure example.com emails are not allowed            if strings.HasSuffix(email, "example.com") {                messages = append(messages, "example.com emails not allowed")            }        }    }    return messages}
```

### Rego

```
package example# ensure title and content are setvalidations contains message if {    some field in {"title", "content"}    object.get(input, field, "") == ""    message := sprintf("Value missing for field '%s'", [field])}# ensure title starts with a capital lettervalidations contains "Title must start with a capital" if {    not regex.match(`^[A-Z]`, input.title)}# ensure user identifier is setvalidations contains "User email or id must be set" if {    not input.user.email    not input.user.id}# ensure example.com emails are not allowedvalidations contains "example.com emails not allowed" if {    endswith(input.user.email, "@example.com")}
```

![](/assets/images/python-82efb64f8698a267f8bfd3b57ceab88a.png)

### Python

[Compare Python](/docs/comparisons/languages/python)

![](/assets/images/java-6c64373d3b7415758078f77fcab4fbc0.png)

### Java

[Compare Java](/docs/comparisons/languages/java)