Attribute-based access control (ABAC) evaluates policies against attributes of the user, the resource, and the request context. This quickstart walks through setting up ABAC with Rego policies.

## Prerequisites

- An Authdog account with at least one tenant and environment
- Familiarity with basic Rego syntax (Open Policy Agent's language)

## When to use ABAC

ABAC shines when access decisions depend on data that doesn't fit cleanly into roles:

- "Managers can approve expenses under $5,000 in their own department"
- "Users can edit resources they own"
- "Access is allowed only during business hours from approved IP ranges"
- "Documents marked 'confidential' are visible only to users with clearance level 3+"

## 1. Enable ABAC for the environment

**Console:** Authorization → Model → select ABAC

The environment now evaluates Rego policies instead of checking role assignments.

## 2. Create your first policy

Policies are written in Rego and evaluated at the edge. The policy receives `input` with the user, resource, action, and context.

**Console:** Authorization → Policies → Create Policy

**Example policy — department-scoped approval:**

```rego
package authdog.authz

default allow = false

allow {
  input.action == "approve"
  input.user.department == input.resource.department
  input.resource.amount < 5000
}
```

**API:**

```bash
curl -X POST https://api.authdog.com/v1/tenants/{tenantId}/environments/{envId}/abac-policies \
  -H "Authorization: Bearer $AUTHDOG_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Department approval policy",
    "slug": "dept-approval",
    "regoSource": "package authdog.authz\n\ndefault allow = false\n\nallow {\n  input.action == \"approve\"\n  input.user.department == input.resource.department\n  input.resource.amount < 5000\n}",
    "enabled": true
  }'
```

## 3. Validate the policy

Before enabling a policy, validate its syntax.

**API:**

```bash
curl -X POST https://api.authdog.com/v1/tenants/{tenantId}/environments/{envId}/abac-policies/validate \
  -H "Authorization: Bearer $AUTHDOG_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "regoSource": "package authdog.authz\n\ndefault allow = false\n\nallow { input.action == \"read\" }",
    "slug": "read-policy"
  }'
# → {"valid": true}
```

## 4. Understand the input schema

Every policy receives an `input` object with:

```json
{
  "user": {
    "id": "user_abc123",
    "email": "jane@example.com",
    "department": "engineering",
    "clearanceLevel": 2,
    "roles": ["editor"],
    "groups": ["engineering-team"],
    "metadata": { ... }
  },
  "resource": {
    "type": "expense",
    "id": "exp_456",
    "department": "engineering",
    "amount": 3500,
    "owner": "user_abc123",
    "metadata": { ... }
  },
  "action": "approve",
  "context": {
    "ip": "192.168.1.100",
    "timestamp": "2026-11-09T14:30:00Z",
    "userAgent": "Mozilla/5.0 ...",
    "environment": "production"
  }
}
```

Your application supplies `resource`, `action`, and any custom `context` fields when making a check request.

## 5. Check authorization in your app

**SDK (Node.js):**

```ts
import { Authdog } from "@authdog/node"

const authdog = new Authdog({ apiSecret: process.env.AUTHDOG_API_SECRET })

app.post("/expenses/:id/approve", requireAuth, async (req, res) => {
  const expense = await getExpense(req.params.id)
  
  const allowed = await authdog.abac.check({
    userId: req.user.id,
    action: "approve",
    resource: {
      type: "expense",
      id: expense.id,
      department: expense.department,
      amount: expense.amount,
    },
    context: {
      ip: req.ip,
    },
  })
  
  if (!allowed) {
    return res.status(403).json({ error: "Not authorized to approve this expense" })
  }
  
  await approveExpense(expense.id)
  res.json({ approved: true })
})
```

**REST API via AuthZEN:**

```bash
curl -X POST https://api.authdog.com/access/v1/evaluation \
  -H "Authorization: Bearer $AUTHDOG_ENV_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": {"type": "user", "id": "user_abc123"},
    "action": {"name": "approve"},
    "resource": {
      "type": "expense",
      "id": "exp_456",
      "properties": {
        "department": "engineering",
        "amount": 3500
      }
    }
  }'
# → {"decision": true}
```

## Example policies

**Owner can edit:**

```rego
package authdog.authz

default allow = false

allow {
  input.action == "edit"
  input.resource.owner == input.user.id
}
```

**Business hours only:**

```rego
package authdog.authz

default allow = false

allow {
  hour := time.clock(time.parse_rfc3339_ns(input.context.timestamp))[0]
  hour >= 9
  hour < 17
}
```

**Clearance level check:**

```rego
package authdog.authz

default allow = false

allow {
  input.action == "view"
  input.resource.classification == "confidential"
  input.user.clearanceLevel >= 3
}
```

**IP allowlist:**

```rego
package authdog.authz

default allow = false

allowed_networks = {"10.0.0.0/8", "192.168.0.0/16"}

allow {
  some network
  allowed_networks[network]
  net.cidr_contains(network, input.context.ip)
}
```

## 6. List and manage policies

**List policies:**

```bash
curl https://api.authdog.com/v1/tenants/{tenantId}/environments/{envId}/abac-policies \
  -H "Authorization: Bearer $AUTHDOG_API_SECRET"
```

**Delete a policy:**

```bash
curl -X DELETE https://api.authdog.com/v1/tenants/{tenantId}/environments/{envId}/abac-policies/{policyId} \
  -H "Authorization: Bearer $AUTHDOG_API_SECRET"
```

## CLI usage

CLI support for ABAC commands is coming soon. For now, use the generic API command:

```bash
# List policies
authdog api GET /v1/tenants/{tenantId}/environments/{envId}/abac-policies

# Create a policy
authdog api POST /v1/tenants/{tenantId}/environments/{envId}/abac-policies \
  --data '{"name":"Owner edit","slug":"owner-edit","regoSource":"package authdog.authz\n\ndefault allow = false\n\nallow { input.action == \"edit\"; input.resource.owner == input.user.id }","enabled":true}'

# Validate a policy
authdog api POST /v1/tenants/{tenantId}/environments/{envId}/abac-policies/validate \
  --data '{"regoSource":"package authdog.authz\n\ndefault allow = false","slug":"test"}'
```

## Next steps

- [Authorization concepts](/docs/concepts/authorization) — compare ABAC with RBAC and FGA
- [Rego language reference](https://www.openpolicyagent.org/docs/latest/policy-language/) — full Rego documentation
- [AuthZEN API](/docs/authzen) — vendor-neutral decision endpoint
