Policy Recipes
This document provides quick policy patterns for common authorization scenarios. Each recipe includes the policy configuration and explanation of when to use it.
For comprehensive real-world scenarios with complete setup workflows, see the Policy Cookbook. For formal policy evaluation details, see the Algorithm Reference. For the policy language details, see the Language Reference.
Getting Started
Recipe 1: Allow All Users to Read Public Resources
The simplest policy - grant read access to anything under the public path.
name = "public-read"
description = "Allow anyone to read public resources"
engine = "Prefix"
invert = false
deny = false
[[statements]]
action = "read"
object = "hc://domain/<domain-uuid>/public/"
Note: Replace
<domain-uuid>with your actual domain UUID (e.g.,550e8400-e29b-41d4-a716-446655440000).
When to use: Landing pages, public documentation, shared assets.
Recipe 2: User Can Access Their Own Resources
Use macros to let users manage their own profile and settings.
name = "self-service"
description = "Users can access their own resources"
engine = "Fixed"
invert = false
deny = false
[[statements]]
subject = "$current_user()"
object = "hc://domain/<domain-uuid>/users/$current_user()/profile"
Note: Replace
<domain-uuid>with your actual domain UUID.
When to use: User profiles, personal settings, private documents.
Pattern Matching Recipes
The following recipes demonstrate different pattern matching approaches using the Fixed, Prefix, and RegEx engines. For more complex real-world scenarios that combine multiple policies, see the Policy Cookbook.
Recipe 3: Match File Extensions
Allow access to all PDF documents in a directory tree.
name = "pdf-access"
description = "Access to PDF files in reports directory"
engine = "RegEx"
invert = false
deny = false
[[statements]]
action = "read"
object = "hc://domain/[a-f0-9-]{36}/reports/.*\\.pdf$"
Matches: hc://domain/550e8400-e29b-41d4-a716-446655440000/reports/quarterly.pdf, hc://domain/550e8400-e29b-41d4-a716-446655440000/reports/archive/annual.pdf
When to use: Document management systems, file-type-specific permissions.
Recipe 4: Domain-Based Email Matching
Authorize users based on their email domain.
name = "company-email-access"
description = "Allow access to users with company email"
engine = "RegEx"
invert = false
deny = false
[[statements]]
subject = ".*@acme-corp\\.com$"
action = "read"
object = "hc://domain/[a-f0-9-]{36}/internal/.*"
Matches: alice@acme-corp.com, bob@acme-corp.com
Does not match: alice@gmail.com, attacker@fake-acme-corp.com
When to use: Organization-wide access, corporate resource sharing.
Recipe 5: API Version Flexibility
Allow access to any single-digit API version.
name = "api-access"
description = "Access to API v1-v9"
engine = "RegEx"
deny = false
invert = false
statements = [
{ "action" = "read", "object" = "/api/v[0-9]/users/.*" }
]
Matches: /api/v1/users/alice, /api/v2/users/bob
Does not match: /api/v10/users/alice (two digits)
When to use: Multi-version API deployments, backward compatibility scenarios.
Recipe 6: Domain Resource Patterns
Match resources across domain-specific paths.
name = "domain-docs"
description = "Access to documents in any domain"
engine = "RegEx"
invert = false
deny = false
[[statements]]
action = "read"
object = "hc://domain/[a-f0-9-]{36}/documents/.*"
Matches: hc://domain/550e8400-e29b-41d4-a716-446655440000/documents/readme, hc://domain/a1b2c3d4-e5f6-7890-abcd-ef1234567890/documents/archive/old
When to use: Multi-domain systems, shared document repositories.
Recipe 7: Role-Based Patterns
Match any role with admin suffix.
name = "admin-roles"
description = "Access for any admin role"
engine = "RegEx"
invert = false
deny = false
[[statements]]
role = ".*-admin$"
action = "write"
object = "hc://domain/[a-f0-9-]{36}/config/.*"
Matches roles: billing-admin, system-admin, docs-admin
Does not match: admin, admin-viewer
When to use: Role-based access control (RBAC) with naming conventions.
Advanced Patterns
Recipe 8: Deny Access to Sensitive Files
Use deny policies to explicitly block access regardless of other policies.
name = "block-secrets"
description = "Block access to secret files"
engine = "RegEx"
invert = false
deny = true
[[statements]]
object = "hc://domain/[a-f0-9-]{36}/secrets/.*"
[[statements]]
object = "hc://domain/[a-f0-9-]{36}/.*\\.env$"
Important: Deny policies take precedence. If this matches, access is denied even if other policies would allow it.
When to use: Defense-in-depth for critical resources, compliance requirements. See Scenario 2 in the Policy Cookbook for a complete secrets management example.
Recipe 9: Combining Patterns with Macros
Let users access their own tenant's resources with pattern matching.
name = "tenant-self-service"
description = "Users can access their tenant's documents"
engine = "RegEx"
invert = false
deny = false
[[statements]]
subject = "$current_user()"
object = "hc://domain/$requestors_tenant()/documents/.*"
This combines the $requestors_tenant() macro with regex patterns for flexible yet scoped access.
When to use: Multi-tenant SaaS applications, customer data isolation.
Choosing the Right Engine
| Scenario | Recommended Engine | Why |
|---|---|---|
| Exact resource match | Fixed | Fastest, no pattern overhead |
| Hierarchical paths | Prefix | Simple, matches everything under a path |
| Complex patterns, alternation | RegEx | Full regex power for sophisticated matching |
Performance considerations: Use the simplest engine that meets your needs. Fixed and Prefix engines have lower computational overhead than RegEx.
Security note: Complex regex patterns can be computationally expensive. For security-critical policies, prefer Fixed or Prefix engines when possible.
Next Steps
- See the Policy Cookbook for complete real-world scenarios with setup workflows
- Review the Algorithm Reference for formal policy evaluation details
- Explore the Language Reference for complete macro and engine documentation
- See Policy Administration for operational guidance