Denied Docs

Policies

Create and manage authorization policies

Policies are the heart of Denied Platform. Each policy defines authorization rules written in Rego, the policy language used by Open Policy Agent (OPA). This guide covers everything you need to know about creating, managing, and deploying policies.

Overview

A policy in Denied consists of:

FieldDescription
NameA unique identifier for the policy (e.g., allow-own-resources)
ReasonA human-readable description of what the policy does
EffectWhether this policy grants access (Allow) or blocks it (Deny)
ContentThe Rego code that implements the authorization logic
EnabledWhether the policy is active and included in the OPA bundle

Creating a Policy

Manual Creation

To create a policy by writing Rego directly:

  1. Go to GovernancePolicies
  2. Click Create Policy
  3. Fill in the policy details:
    • Name: A descriptive, unique name (use lowercase and hyphens)
    • Reason: Explain what this policy does and why
    • Effect: Select Allow or Deny
  4. Write your Rego code in the policy editor
  5. Click Create

AI-Assisted Creation

Denied can generate Rego policies from natural language descriptions:

  1. Go to GovernancePolicies
  2. Click Create Policy
  3. Switch to the AI tab
  4. Describe your authorization requirement in plain English
  5. Click Generate
  6. Review and edit the generated Rego code
  7. Click Create

AI-generated policies are a starting point. Always review the generated code to ensure it matches your exact requirements.

Policy Structure

In Denied Platform, you write policy conditions — the platform handles the OPA wrapper automatically:

# Conditions that must all be true
input.subject.properties.role == "admin"
input.action.name == "read"

Each line is a condition. All conditions must be true for the policy to match (implicit AND).

How It Works

When you save a policy:

  1. You provide the conditions (rule body)
  2. Denied wraps them in proper OPA structure
  3. The bundle is served to your decision node
  4. Your conditions are evaluated against incoming requests

Multiple Policies (OR Logic)

Create separate policies for OR logic — if any policy matches, access is granted:

Policy 1: Admin Access

input.subject.properties.role == "admin"

Policy 2: Owner Access

input.resource.properties.owner == input.subject.properties.user_id

If either policy's conditions match, access is allowed.

Input Object

The input object contains the authorization request:

input.subject.properties    # Who is making the request (their properties)
input.action.name           # What they want to do
input.resource.properties   # What they want to access (its properties)

The exact structure depends on how your application sends requests to the decision node.

Managing Policies

Viewing Policies

Go to GovernancePolicies to see all policies in the current project. Each policy shows:

  • Name — The policy identifier
  • Effect — Allow or Deny badge
  • Enabled — Toggle switch showing status
  • Actions — Edit and delete buttons

Editing Policies

To edit a policy:

  1. Go to GovernancePolicies
  2. Click the Edit button on the policy row
  3. Modify the policy details or Rego code
  4. Click Save

Policy changes take effect after the decision node pulls the updated bundle. This typically happens within seconds but depends on your configuration.

Toggling Policies

Enable or disable policies without deleting them:

  1. Go to GovernancePolicies
  2. Find the policy in the list
  3. Click the toggle switch

Disabled policies:

  • Are not included in the OPA bundle
  • Do not affect authorization decisions
  • Remain in your policy library for reference

This is useful for:

  • Temporarily disabling a policy during troubleshooting
  • Preparing policies before a release
  • Keeping deprecated policies for reference

Deleting Policies

To delete a policy:

  1. Go to GovernancePolicies
  2. Click the Delete button on the policy row
  3. Confirm the deletion

Deleted policies cannot be recovered. Consider disabling instead if you might need the policy later.

Policy Effects

Allow Policies

Policies with the Allow effect grant access when their conditions match:

# This grants access when the subject is verified
input.subject.properties.verified == true

Deny Policies

Policies with the Deny effect block access even if other allow policies would permit it:

# This blocks access to restricted resources for low-clearance users
input.resource.properties.classification == "restricted"
input.subject.properties.clearance < 3

Deny policies take precedence. If any deny rule matches, access is blocked even if allow rules also match.

Policy Templates

Denied provides templates for common authorization patterns. When creating a policy:

  1. Click Create Policy
  2. Select from available templates
  3. Customize the template for your needs

Available templates include:

  • RBAC — Role-based access control
  • ABAC — Attribute-based access control
  • Ownership — Owner-only access
  • Time-based — Access during specific hours

Policy Deployment

How Policies Are Bundled

Denied packages your policies into an OPA-compatible bundle:

  1. All enabled policies are collected
  2. Rego files are generated for each policy
  3. A manifest file is created with metadata
  4. Everything is compressed into a tar.gz bundle

Bundle Serving

The bundle is served at your project's bundle endpoint. Decision nodes pull this bundle periodically to stay updated.

Update Propagation

When you create or modify a policy:

  1. Changes are saved to the database immediately
  2. The bundle is regenerated on the next request
  3. Decision nodes pull the new bundle (typically every 10-30 seconds)
  4. New authorization requests use the updated policies

Best Practices

Naming Conventions

Use descriptive, consistent names:

allow-{action}-{resource}
deny-{condition}
{feature}-{behavior}

Examples:

  • allow-read-own-documents
  • deny-unverified-users
  • admin-full-access

Keep Policies Focused

Each policy should do one thing well:

Good:

# Allow owners to read their resources
input.action.name == "read"
input.resource.properties.owner == input.subject.properties.user_id

Avoid: Complex multi-purpose logic that tries to handle too many scenarios in one policy. Split into separate, focused policies instead.

Test Before Deploying

Always test policies in the Playground before relying on them in production:

  1. Test positive cases (should allow)
  2. Test negative cases (should deny)
  3. Test edge cases (missing fields, unexpected values)

Troubleshooting

Policy not taking effect?

  1. Check the policy is enabled
  2. Verify you're in the correct project
  3. Confirm the decision node has pulled the latest bundle
  4. Test in the Playground to verify the logic

Unexpected denials?

  1. Check for deny policies that might be blocking
  2. Verify the input matches what your policy expects (check .properties paths)
  3. Look for typos in field names
  4. Test with the exact input in the Playground

Syntax errors?

  1. Verify all strings use double quotes ""
  2. Check for missing operators (e.g., == for comparison)
  3. Ensure proper property paths (e.g., input.subject.properties.role)

On this page