Skip to main content

Set up Policies

This section describes the installation steps on creating a new Custom System and how you can use Styra, OPA, and Linux-PAM to enforce fine-grained, host-level access controls over SSH and Sudo.

To manage the policies enforced by OPA running on each host:

  1. Go to <das-id>.styra.com.
  2. Create a new Custom System.
  3. Copy the following policy and paste it in your Custom System > Rules dialog > Rules code pane.
  4. Publish the policy.
package rules

import data.dataset

# This file implements three different queries that control
# the PAM module's behavior. The PAM module will query
# 'display', 'pull', and 'authz'
# Note: This does not illustrate authentication, but will be handled later.

################################################
# Query 1: What prompts to show the user
display = {"display_spec": display_spec}
display_spec = [
{
"message": "Welcome to the OPA-PAM demonstration.",
"style": "info",
},
{
"message": "Please enter your secret: ",
"style": "prompt_echo_off",
"key": "secret",
},
{
"message": "Please enter your Jira ticket: ",
"style": "prompt_echo_on",
"key": "jira",
},
]


################################################
# Query 2: What external information to include as part of authz input
pull = {"files": files, "env_vars": env_vars}

# Which files should be loaded into the context?
files = ["/etc/host_identity.json"]

# Which environment variables should be loaded into the context?
env_vars = []


################################################
# Query 3: Authorization decision
authz = {"allow": allow, "errors": errors}

# By default, users are not authorized.
default allow = false

# Allow access to any user that has the "admin" role.
# Hardcoded for now; in reality would be injected as
# additional external data.
roles["admin"] = ["ops"]
roles["dev"] = ["charlie", "dave"]

# Allow admins
allow {
roles["admin"][_] == input.sysinfo.pam_username
}

# Allow developers on frontend hosts
allow {
input.pull_responses.files["/etc/host_identity.json"].host_type == "frontend"
roles["dev"][_] == input.sysinfo.pam_username
}

# Allow if provided Jira ticket owner and username are the same
allow {
j := jira(input.display_responses.jira)
j.owner == input.sysinfo.pam_username
j.labels.server == input.pull_responses.files["/etc/host_identity.json"].host_id
}

# Copy this for now. Should be an HTTP callout
jira("jira-654") = {"owner": "alice", "labels": {"server": "1234"}}
jira("jira-321") = {"owner": "bob", "labels": {"server": "7890"}}

# If the user is not authorized, then include an error message in the response.
errors["Request denied by administrative policy"] {
not allow
}

After you start the hosts, you will see OPA is up and running. OPA uses the defined policy and starts enforcing it.