Skip to content

Rego IAM policy source#3

Draft
royxu6 wants to merge 9 commits intomainfrom
cursor/rego-iam-policy-source-b31b
Draft

Rego IAM policy source#3
royxu6 wants to merge 9 commits intomainfrom
cursor/rego-iam-policy-source-b31b

Conversation

@royxu6
Copy link

@royxu6 royxu6 commented Jan 24, 2026

Propose a formal_rego_policy_document data source to simplify Rego policy creation through a declarative HCL syntax, similar to AWS IAM policies.


Open in Cursor Open in Web

Inspired by AWS IAM policy document data source, this proposal outlines
a new Terraform data source that allows users to compose Formal Rego
policies in a structured, declarative way without writing raw Rego code.

Key features:
- Declarative HCL syntax for policy statements
- Support for session, pre_request, and post_request stages
- Various effect types: allow, block, mask, decrypt
- Flexible condition operators (equals, in, not_in, contains, etc.)
- Target matching by data_label or column_name
- Row-level conditions for fine-grained access control
- Policy document composition via source_policy_documents
- Generated Rego output compatible with formal_policy.module

Co-authored-by: roy <roy@anysphere.co>
@cursor
Copy link

cursor bot commented Jan 24, 2026

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

cursoragent and others added 8 commits January 24, 2026 01:04
Extended the proposal to address advanced use cases like:
- Rate limiting with external data lookups
- Table-level write permissions
- Multiple access paths (laptop vs dashboard)
- Complex helper functions
- Terraform templatefile() integration

The hybrid approach allows:
- Simple policies using declarative statement blocks
- Complex policies using raw_rego blocks
- Mixed policies combining both approaches
- Future DSL extensions for rate limiting, table permissions, etc.

Co-authored-by: roy <roy@anysphere.co>
The key insight from analyzing complex real-world policies is that they
follow a predicate composition pattern:
1. Define atomic boolean predicates
2. Compose with AND/OR/NOT operators
3. Reference in final policy rules

New design features:
- constant{} blocks for reusable values (lists, maps)
- predicate{} blocks for named booleans with conditions
- all_of/any_of for AND/OR composition
- ! prefix for NOT
- Multiple blocks with same name = OR branches
- computed{} blocks for aggregations (max rate limit, etc.)
- rule{} blocks that reference predicates in when{}
- table_check{} for table permission patterns
- raw_rego escape hatch for custom functions

This can express the complex database access policy with rate limiting,
multiple access paths, and table permissions - all declaratively.

Co-authored-by: roy <roy@anysphere.co>
Developer Experience:
- Clear, actionable error messages with suggestions
- Generated Rego preview in terraform plan output
- Source comments mapping Rego back to HCL line numbers
- Validation diagnostics at plan time (errors, warnings, info)
- Dry-run testing with test_case blocks
- Predicate tracing for debugging
- Sensible defaults/shortcuts for common patterns
- IDE integration hints

Edge Cases & Gotchas:
- Empty predicates (always true)
- OR vs AND precedence
- Negation scope
- Rule priority and conflicts
- External data availability warnings
- Reserved names
- String escaping
- Terraform variable interpolation timing

Migration Guide:
- Step-by-step conversion from raw Rego
- What can vs cannot be converted
- Gradual migration approach with raw_rego escape hatch

Conclusion:
- Accessible: no Rego knowledge needed
- Maintainable: self-documenting predicates
- Correct: type checking and validation
- Flexible: escape hatch for custom needs

Co-authored-by: roy <roy@anysphere.co>
Adds a new data source that generates Rego policy code from declarative
HCL configuration, inspired by AWS IAM policy document data source.

Key features:
- Predicate composition pattern: define atomic predicates, compose with
  AND/OR/NOT, reference in policy rules
- Support for constants (lists, maps) that predicates can reference
- Computed values with aggregations (max, min, sum, count)
- Multiple rule types: session, pre_request, post_request
- Target column selection by data_label or column_name
- Row-level conditions for fine-grained access control
- Raw Rego escape hatch for custom functions
- Comprehensive validation: circular dependencies, undefined references,
  reserved name detection

Includes:
- Full implementation with 800+ lines of Go code
- 25 unit tests covering all major functionality
- Documentation with examples

The data source is flexible and does not hardcode any specific input
paths, allowing it to work with various policy patterns.

Co-authored-by: roy <roy@anysphere.co>
The computed block was overly specific and complex. Users who need
aggregations can use raw_rego which is simpler to understand.

The core model is now shockingly simple:
- constants: name your data
- predicates: name your booleans (compose with all_of/any_of/!)
- rules: when predicates match, produce effects
- raw_rego: everything else

Co-authored-by: roy <roy@anysphere.co>
Effect now describes both 'what to do' and 'what to do it to':

  effect {
    action     = "mask"
    type       = "redact.full"
    data_label = "pii"      # target inline
  }

Removed separate target block - simpler mental model.

Co-authored-by: roy <roy@anysphere.co>
- Shorter type names: generator, predicate, rule, effect
- Remove unused helper functions
- Remove unnecessary comments
- Cleaner parsing with direct nil checks
- ~600 lines down from ~900

Co-authored-by: roy <roy@anysphere.co>
Only include examples that correspond to the official policy examples:
- Mask columns by data label
- Decrypt columns by name
- Row-level hashing
- Block by default, allow specific users
- Hash names in HTTP requests

Co-authored-by: roy <roy@anysphere.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants