This cookbook provides comprehensive real-world scenarios for using Housecarl's policy engine to solve authorization challenges. Each scenario demonstrates how to structure domains, policies, and resources to achieve different access control patterns with complete setup workflows.
For quick policy patterns and recipes, see the Policy Recipes. For a formal understanding of the algorithm, see the Algorithm Reference. For the policy language details, see the Language Reference.
Before diving into scenarios, understand these key concepts:
hc://<tenant-uuid>/<domain-name>/path/to/resourceFixed: Exact string matching (fastest, use for exact matches)Prefix: String prefix matching (ideal for hierarchical resources)Regex: Regular expression matching (most flexible, higher computational cost)All scenarios in this cookbook can be tested offline using housectl authz can-i-local. This command evaluates authorization requests against local policy files without requiring a running housecarl server.
Basic Usage:
# Test a request against local policies
housectl authz can-i-local \
--request request.json \
--tenant <tenant-uuid> \
./policies/
# With domain specified
housectl authz can-i-local \
--request request.json \
--tenant <tenant-uuid> \
--domain <domain-name-or-uuid> \
./policies/
Policy File Format: Policies are written in TOML format (see examples below)
Request File Format: JSON file with a context object containing subject, action, object
A standard CRUD (Create, Read, Update, Delete) application where users can manage their own resources, and administrators have full access.
Tenant ID: 550e8400-e29b-41d4-a716-446655440000
Tenant Name: myapp-tenant
Domain: app-domain
Resources: hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/users/{user_id}
hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/posts/{post_id}
hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/comments/{comment_id}
# Create tenant (returns tenant UUID)
housectl admin create-tenant "myapp-tenant" "My CRUD Application"
# Example output: Tenant created with ID: 550e8400-e29b-41d4-a716-446655440000
# Login as admin
housectl config login --url http://localhost:1234 --username admin --tenant myapp-tenant
# Create domain
housectl domain create --name app-domain
# Example output: Domain created with ID: 7c9e6679-7425-40de-944b-e07fc1f90ae7
Policies are written in TOML format. Create a directory for your policies and save each policy as a separate .toml file.
Policy 1: Admin Full Access (admin-full-access.toml)
Administrators can perform any action on any resource.
name = "admin-full-access"
description = "Administrators have full access to all resources"
invert = false
deny = false
engine = "Regex"
statements = [
{ "subject" = "admin", "action" = ".*", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/.*" }
]
Policy 2: User Self-Management (user-self-management.toml)
Users can read and update their own user records.
name = "user-self-management"
description = "Users can manage their own user records"
invert = false
deny = false
engine = "Fixed"
statements = [
{ "subject" = "$current_user()", "action" = "read", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/users/$current_user()" },
{ "subject" = "$current_user()", "action" = "update", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/users/$current_user()" }
]
Policy 3: Post Ownership (post-ownership.toml)
Users can create posts and manage (update/delete) their own posts. Anyone can read posts.
name = "post-ownership"
description = "Users manage their own posts, everyone can read"
invert = false
deny = false
engine = "Regex"
statements = [
{ "action" = "read", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/posts/.*" },
{ "subject" = "$current_user()", "owner" = "$current_user()", "action" = "(update|delete)", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/posts/.*" },
{ "subject" = "$current_user()", "action" = "create", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/posts" }
]
Policy 4: Comment Management (comment-management.toml)
Users can create comments and delete their own comments.
name = "comment-management"
description = "Users can create and delete their own comments"
invert = false
deny = false
engine = "Fixed"
statements = [
{ "action" = "read", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/comments" },
{ "subject" = "$current_user()", "action" = "create", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/comments" },
{ "subject" = "$current_user()", "owner" = "$current_user()", "action" = "delete", "object" = "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/comments" }
]
If deploying to a running housecarl server, save the policies to a directory and upload them:
# Create policies directory
mkdir -p ./scenario1-policies
# Save each policy from above to ./scenario1-policies/*.toml
# Upload policies to server
housectl domain put-policies --domain app-domain --policies ./scenario1-policies/
Test your policies offline using housectl authz can-i-local. Create JSON request files for each test case:
Test Case 1: Admin deletes post (admin-delete-post.json)
{
"context": {
"subject": "admin",
"action": "delete",
"object": "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/posts/123"
}
}
Test Case 2: Alice reads own profile (alice-read-own-profile.json)
{
"context": {
"subject": "alice",
"action": "read",
"object": "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/users/alice"
}
}
Test Case 3: Alice tries to update Bob's profile (alice-update-bob.json)
{
"context": {
"subject": "alice",
"action": "update",
"object": "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/users/bob"
}
}
Test Case 4: Alice deletes own post (alice-delete-own-post.json)
{
"context": {
"subject": "alice",
"owner": "alice",
"action": "delete",
"object": "hc://550e8400-e29b-41d4-a716-446655440000/app-domain/myapp/posts/456"
}
}
Run the tests:
# Test admin access (should succeed - returns allowed: true)
housectl authz can-i-local \
--request admin-delete-post.json \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
./scenario1-policies/
# Test user reading own profile (should succeed)
housectl authz can-i-local \
--request alice-read-own-profile.json \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
./scenario1-policies/
# Test user updating another user (should fail - returns allowed: false)
housectl authz can-i-local \
--request alice-update-bob.json \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
./scenario1-policies/
# Test user deleting own post (should succeed)
housectl authz can-i-local \
--request alice-delete-own-post.json \
--tenant 550e8400-e29b-41d4-a716-446655440000 \
./scenario1-policies/
Expected Results:
A CRUD application where a dedicated team manages secrets and configuration, while the application has read-only access to those secrets. This models a separation of concerns where operators manage sensitive data and applications consume it.
Note: This scenario follows the same pattern as Scenario 1. All policies should be written in TOML format and can be tested locally with housectl authz can-i-local.
Tenant ID: 660e8400-e29b-41d4-a716-446655440001
Tenant Name: platform-tenant
Domains:
- secrets-domain (superior)
- app-domain (inherits from secrets-domain)
Resources:
- hc://660e8400-e29b-41d4-a716-446655440001/secrets-domain/platform/secrets/{secret_name} (managed by ops-team)
- hc://660e8400-e29b-41d4-a716-446655440001/secrets-domain/platform/config/{config_name} (managed by ops-team)
- hc://660e8400-e29b-41d4-a716-446655440001/app-domain/platform/app/data/{resource_id} (managed by app)
# Create tenant
housectl admin create-tenant "platform-tenant" "Platform with shared resources"
# Login
housectl config login --url http://localhost:1234 --username admin --tenant platform-tenant
# Create secrets domain (superior)
housectl domain create --tenant platform-tenant --name secrets-domain
# Create app domain (inherits from secrets-domain)
housectl domain create --tenant platform-tenant --name app-domain --superior-domains secrets-domain
Policy 1: Ops Team Full Access to Secrets The operations team can create, read, update, and delete secrets and configuration.
{
"name": "ops-team-secrets-management",
"description": "Ops team has full access to secrets and config",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "(create|read|update|delete)",
"object": "hc://platform/secrets/.*"
}
},
{
"rules": {
"subject": "ops-team",
"action": "(create|read|update|delete)",
"object": "hc://platform/config/.*"
}
}
]
}
Policy 2: Application Read-Only Access to Secrets The application service accounts can only read secrets and configuration.
{
"name": "app-readonly-secrets",
"description": "Applications have read-only access to secrets",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "svc:crud-app",
"action": "read",
"object": "hc://platform/secrets/.*"
}
},
{
"rules": {
"subject": "svc:crud-app",
"action": "read",
"object": "hc://platform/config/.*"
}
}
]
}
Policy 3: Deny Application Write to Secrets Explicitly prevent applications from modifying secrets (defense in depth).
{
"name": "deny-app-write-secrets",
"description": "Prevent applications from writing secrets",
"invert": false,
"deny": true,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "svc:.*",
"action": "(create|update|delete)",
"object": "hc://platform/secrets/.*"
}
}
]
}
Policy 4: Application Data Management The application can fully manage its own data resources.
{
"name": "app-data-management",
"description": "Application manages its own data",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "svc:crud-app",
"action": "(create|read|update|delete)",
"object": "hc://platform/app/data/.*"
}
}
]
}
Policy 5: User Read Access to App Data End users can read application data based on ownership.
{
"name": "user-read-app-data",
"description": "Users can read their own app data",
"invert": false,
"deny": false,
"engine": "Fixed",
"statements": [
{
"rules": {
"subject": "$current_user()",
"owner": "$current_user()",
"action": "read",
"object": "hc://platform/app/data"
}
}
]
}
# Apply secrets domain policies
cat > secrets-policies.json <<EOF
[
{
"name": "ops-team-secrets-management",
"description": "Ops team has full access to secrets and config",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "(create|read|update|delete)",
"object": "hc://platform/secrets/.*"
}
},
{
"rules": {
"subject": "ops-team",
"action": "(create|read|update|delete)",
"object": "hc://platform/config/.*"
}
}
]
},
{
"name": "app-readonly-secrets",
"description": "Applications have read-only access to secrets",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "svc:crud-app",
"action": "read",
"object": "hc://platform/secrets/.*"
}
},
{
"rules": {
"subject": "svc:crud-app",
"action": "read",
"object": "hc://platform/config/.*"
}
}
]
},
{
"name": "deny-app-write-secrets",
"description": "Prevent applications from writing secrets",
"invert": false,
"deny": true,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "svc:.*",
"action": "(create|update|delete)",
"object": "hc://platform/secrets/.*"
}
}
]
}
]
EOF
housectl domain put-policies --tenant platform-tenant --domain secrets-domain --policies secrets-policies.json
# Apply app domain policies
cat > app-policies.json <<EOF
[
{
"name": "app-data-management",
"description": "Application manages its own data",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "svc:crud-app",
"action": "(create|read|update|delete)",
"object": "hc://platform/app/data/.*"
}
}
]
},
{
"name": "user-read-app-data",
"description": "Users can read their own app data",
"invert": false,
"deny": false,
"engine": "Fixed",
"statements": [
{
"rules": {
"subject": "$current_user()",
"owner": "$current_user()",
"action": "read",
"object": "hc://platform/app/data"
}
}
]
}
]
EOF
housectl domain put-policies --tenant platform-tenant --domain app-domain --policies app-policies.json
# Ops team creates a secret (should succeed)
housectl authz can-i --context '{
"subject": "ops-team",
"action": "create",
"object": "hc://platform/secrets/db-password"
}'
# Application reads secret (should succeed - inherits from secrets-domain)
housectl authz can-i --context '{
"subject": "svc:crud-app",
"action": "read",
"object": "hc://platform/secrets/db-password"
}'
# Application tries to update secret (should fail - deny policy)
housectl authz can-i --context '{
"subject": "svc:crud-app",
"action": "update",
"object": "hc://platform/secrets/db-password"
}'
# Application manages its data (should succeed)
housectl authz can-i --context '{
"subject": "svc:crud-app",
"action": "create",
"object": "hc://platform/app/data/record-123"
}'
Three teams (Operations, Development, Compliance) need different levels of access to review and approve a CRUD application, its data pipeline, and deployment configuration. This models a GitOps-style workflow with separation of duties.
Note: This scenario follows the same pattern as Scenario 1. All policies should be written in TOML format and can be tested locally with housectl authz can-i-local.
Tenant ID: 770e8400-e29b-41d4-a716-446655440002
Tenant Name: enterprise-tenant
Domain Hierarchy:
- compliance-domain (root)
- ops-domain (inherits compliance)
- dev-domain (inherits ops)
Resources:
- hc://770e8400-e29b-41d4-a716-446655440002/compliance-domain/enterprise/app/code/* (source code)
- hc://770e8400-e29b-41d4-a716-446655440002/compliance-domain/enterprise/app/config/* (application config)
- hc://770e8400-e29b-41d4-a716-446655440002/compliance-domain/enterprise/pipeline/* (data pipeline definitions)
- hc://770e8400-e29b-41d4-a716-446655440002/compliance-domain/enterprise/deployment/* (K8s manifests, Terraform)
- hc://770e8400-e29b-41d4-a716-446655440002/compliance-domain/enterprise/compliance/* (audit reports, policies)
# Create tenant
housectl admin create-tenant "enterprise-tenant" "Enterprise multi-team environment"
# Login
housectl config login --url http://localhost:1234 --username admin --tenant enterprise-tenant
# Create domain hierarchy
housectl domain create --tenant enterprise-tenant --name compliance-domain
housectl domain create --tenant enterprise-tenant --name ops-domain --superior-domains compliance-domain
housectl domain create --tenant enterprise-tenant --name dev-domain --superior-domains ops-domain
Policy 1: Compliance Team Read-All Access Compliance can read everything but cannot modify operational systems.
{
"name": "compliance-read-all",
"description": "Compliance team has read access to all resources",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "compliance-team",
"action": "read",
"object": "hc://enterprise/.*"
}
}
]
}
Policy 2: Compliance Team Manages Compliance Resources Compliance can manage compliance-specific resources (audit reports, policy documents).
{
"name": "compliance-manage-compliance-resources",
"description": "Compliance team manages compliance resources",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "compliance-team",
"action": "(create|update|delete|approve)",
"object": "hc://enterprise/compliance/.*"
}
}
]
}
Policy 3: Deny Non-Compliance Modification of Compliance Resources Only compliance team can modify compliance resources.
{
"name": "deny-non-compliance-write",
"description": "Only compliance can modify compliance resources",
"invert": false,
"deny": true,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "(?!compliance-team).*",
"action": "(create|update|delete)",
"object": "hc://enterprise/compliance/.*"
}
}
]
}
Policy 4: Ops Team Deployment Management Operations team can read and deploy infrastructure and application configurations.
{
"name": "ops-deployment-management",
"description": "Ops team manages deployments and infrastructure",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "(read|deploy|rollback)",
"object": "hc://enterprise/deployment/.*"
}
},
{
"rules": {
"subject": "ops-team",
"action": "(read|update)",
"object": "hc://enterprise/app/config/.*"
}
}
]
}
Policy 5: Ops Team Pipeline Management Operations can read and execute data pipelines.
{
"name": "ops-pipeline-management",
"description": "Ops team manages data pipelines",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "(read|execute|monitor)",
"object": "hc://enterprise/pipeline/.*"
}
}
]
}
Policy 6: Ops Approval Required for Production Deployments Production deployments require ops team approval.
{
"name": "ops-approve-prod-deployment",
"description": "Ops must approve production deployments",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "approve",
"object": "hc://enterprise/deployment/production/.*"
}
}
]
}
Policy 7: Dev Team Source Code Management Developers can manage source code and create merge requests.
{
"name": "dev-code-management",
"description": "Developers manage source code",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "(read|write|create|update)",
"object": "hc://enterprise/app/code/.*"
}
}
]
}
Policy 8: Dev Team Limited Config Access Developers can read configs and propose changes but cannot deploy directly.
{
"name": "dev-config-read-propose",
"description": "Developers can read and propose config changes",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "read",
"object": "hc://enterprise/app/config/.*"
}
},
{
"rules": {
"subject": "dev-team",
"action": "propose",
"object": "hc://enterprise/app/config/.*"
}
}
]
}
Policy 9: Dev Team Pipeline Read Access Developers can read pipeline definitions and logs for debugging.
{
"name": "dev-pipeline-read",
"description": "Developers can read pipeline definitions and logs",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "(read|logs)",
"object": "hc://enterprise/pipeline/.*"
}
}
]
}
Policy 10: Deny Dev Direct Production Deployment Developers cannot deploy directly to production.
{
"name": "deny-dev-prod-deploy",
"description": "Prevent developers from deploying to production",
"invert": false,
"deny": true,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "deploy",
"object": "hc://enterprise/deployment/production/.*"
}
}
]
}
# Compliance domain policies
cat > compliance-policies.json <<EOF
[
{
"name": "compliance-read-all",
"description": "Compliance team has read access to all resources",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "compliance-team",
"action": "read",
"object": "hc://enterprise/.*"
}
}
]
},
{
"name": "compliance-manage-compliance-resources",
"description": "Compliance team manages compliance resources",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "compliance-team",
"action": "(create|update|delete|approve)",
"object": "hc://enterprise/compliance/.*"
}
}
]
},
{
"name": "deny-non-compliance-write",
"description": "Only compliance can modify compliance resources",
"invert": false,
"deny": true,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "(?!compliance-team).*",
"action": "(create|update|delete)",
"object": "hc://enterprise/compliance/.*"
}
}
]
}
]
EOF
housectl domain put-policies --tenant enterprise-tenant --domain compliance-domain --policies compliance-policies.json
# Ops domain policies
cat > ops-policies.json <<EOF
[
{
"name": "ops-deployment-management",
"description": "Ops team manages deployments and infrastructure",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "(read|deploy|rollback)",
"object": "hc://enterprise/deployment/.*"
}
},
{
"rules": {
"subject": "ops-team",
"action": "(read|update)",
"object": "hc://enterprise/app/config/.*"
}
}
]
},
{
"name": "ops-pipeline-management",
"description": "Ops team manages data pipelines",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "(read|execute|monitor)",
"object": "hc://enterprise/pipeline/.*"
}
}
]
},
{
"name": "ops-approve-prod-deployment",
"description": "Ops must approve production deployments",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "ops-team",
"action": "approve",
"object": "hc://enterprise/deployment/production/.*"
}
}
]
}
]
EOF
housectl domain put-policies --tenant enterprise-tenant --domain ops-domain --policies ops-policies.json
# Dev domain policies
cat > dev-policies.json <<EOF
[
{
"name": "dev-code-management",
"description": "Developers manage source code",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "(read|write|create|update)",
"object": "hc://enterprise/app/code/.*"
}
}
]
},
{
"name": "dev-config-read-propose",
"description": "Developers can read and propose config changes",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "read",
"object": "hc://enterprise/app/config/.*"
}
},
{
"rules": {
"subject": "dev-team",
"action": "propose",
"object": "hc://enterprise/app/config/.*"
}
}
]
},
{
"name": "dev-pipeline-read",
"description": "Developers can read pipeline definitions and logs",
"invert": false,
"deny": false,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "(read|logs)",
"object": "hc://enterprise/pipeline/.*"
}
}
]
},
{
"name": "deny-dev-prod-deploy",
"description": "Prevent developers from deploying to production",
"invert": false,
"deny": true,
"engine": "Regex",
"statements": [
{
"rules": {
"subject": "dev-team",
"action": "deploy",
"object": "hc://enterprise/deployment/production/.*"
}
}
]
}
]
EOF
housectl domain put-policies --tenant enterprise-tenant --domain dev-domain --policies dev-policies.json
# Compliance reads deployment config (should succeed)
housectl authz can-i --context '{
"subject": "compliance-team",
"action": "read",
"object": "hc://enterprise/deployment/production/k8s-manifests"
}'
# Compliance tries to deploy (should fail - no deploy policy)
housectl authz can-i --context '{
"subject": "compliance-team",
"action": "deploy",
"object": "hc://enterprise/deployment/production/k8s-manifests"
}'
# Ops deploys to production (should succeed - inherits compliance read + has deploy)
housectl authz can-i --context '{
"subject": "ops-team",
"action": "deploy",
"object": "hc://enterprise/deployment/production/k8s-manifests"
}'
# Ops reads source code (should succeed - inherits from compliance)
housectl authz can-i --context '{
"subject": "ops-team",
"action": "read",
"object": "hc://enterprise/app/code/main.rs"
}'
# Developer writes code (should succeed)
housectl authz can-i --context '{
"subject": "dev-team",
"action": "write",
"object": "hc://enterprise/app/code/main.rs"
}'
# Developer tries to deploy to production (should fail - deny policy)
housectl authz can-i --context '{
"subject": "dev-team",
"action": "deploy",
"object": "hc://enterprise/deployment/production/k8s-manifests"
}'
# Developer proposes config change (should succeed)
housectl authz can-i --context '{
"subject": "dev-team",
"action": "propose",
"object": "hc://enterprise/app/config/database.toml"
}'
# Developer reads pipeline logs (should succeed - inherits compliance read + has logs action)
housectl authz can-i --context '{
"subject": "dev-team",
"action": "logs",
"object": "hc://enterprise/pipeline/etl-job"
}'
A typical workflow in this setup:
hc://enterprise/app/code/feature.rshc://enterprise/app/config/feature-flags.tomlhc://enterprise/deployment/production/app-v2deploy action on production resourceslogs action on pipeline resourcesStructure your domains from least-privileged (root) to most-privileged (leaf) so that broader policies propagate down. This prevents accidental privilege escalation.
Use explicit deny policies with "deny": true for sensitive resources like production deployments or secrets. Deny policies take precedence over allow policies.
Use macros like $current_user(), $resource_owner(), and $current_time() to create flexible, context-aware policies that reduce duplication.
hc://app/users/alice/)Choose the simplest engine that meets your requirements - Fixed and Prefix have lower computational overhead than Regex.
Always test authorization policies with housectl authz can-i before deploying to production. Create test scenarios covering both allowed and denied cases.
Use descriptive policy names and detailed descriptions. Future operators need to understand why a policy exists.
Periodically review policies with compliance team to ensure they still match business requirements and security posture.